欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

漫谈应用缓存的命中率问题

程序员文章站 2022-03-08 22:04:40
...
这篇文章源自于:

http://www.iteye.com/topic/77195

其中很多人谈到了缓存命中率的问题,应用缓存的命中率取决于很多的因素:

1、应用场景
是OLTP还是OLAP应用,即使是OLTP,也要看访问的频度,一个极少被访问到的缓存等于没有什么效果。一般来说,互联网网站是非常适合缓存应用的场景。

2、缓存的粒度
毫无疑问,缓存的粒度越小,命中率就越高,对象缓存是目前缓存粒度最小的,因此被命中的几率更高。举个例子来说吧:你访问当前这个页面,浏览帖子,那么对于ORM来说,需要发送n条SQL,取各自帖子user的对象。很显然,如果这个user在其他帖子里面也跟贴了,那么在访问那个帖子的时候,就可以直接从缓存里面取这个user对象了。

3、架构的设计
架构的设计对于缓存命中率也有至关重要的影响。例如你应该如何去尽量避免缓存失效的问题,如何尽量提供频繁访问数据的缓存问题,这些都是考验架构师水平的地方。再举个例子来说,对于论坛,需要记录每个topic的浏览次数,所以每次有人访问这个topic,那么topic表就要update一次,这意味着什么呢?对于topic的对象缓存是无效的,每次访问都要更新缓存。那么可以想一些办法,例如增加一个中间变量记录点击次数,每累计一定的点击,才更新一次数据库,从而减低缓存失效的频率。

4、缓存的容量和缓存的有效期
缓存太小,造成频繁的LRU,也会降低命中率,缓存的有效期太短也会造成缓存命中率下降。

所以缓存命中率问题不能一概而论,一定说命中率很低或者命中率很高。但是如果你对于缓存的掌握很精通,有意识的去调整应用的架构,去分解缓存的粒度,总是会带来很高的命中率的。

这里我可以举一个实际的案例,JavaEye2.0网站在使用对象缓存之前,通过MySQL的监控工具进行观察,在连续24小时的平均每秒发送SQL条数超过了200条,在使用对象缓存之后,连续24小时的平均每秒发送SQL条数下降到了120条左右,几乎下降了一半。

考虑到很多SQL都是分页语句,关联查询,条件查询,集合操作,都是不能被缓存的SQL,而真正能够被缓存的SQL只有根据主键查询对象和对象关联对象的查询。所以真正能够被缓存的SQL估计最多占所有SQL的60%。所以换算下来,应用缓存的命中率之高,已经相当惊人了。

不过这里要提醒的一点,有将近一半的SQL都被缓存,不意味着性能可以提升一倍。这是因为能够被缓存的都是按照主键查询单条记录的SQL,这些SQL本身即使发送到数据库,对数据库造成的压力也没有想像的那么大。真正对数据库造成庞大压力的正是那些没有索引的大表查询,和造成了全表扫描的关联查询,这些一旦涉及到全表扫描的查询,才是性能的真正杀手。当然了,不管怎么说,通过使用对象缓存,是毫无疑问可以大幅度降低数据库的负载压力的,有效提升web应用的性能的。

关于这一点,我再给出一组数据来加深大家的印象,通过使用操作系统网络工具进行统计:

JavaEye网站web server的端口每秒数据流量是2MB;
JavaEye网站的MySQL数据库端口的每秒数据流量是1.2MB;
而网站的memcached的端口每秒的数据流量高达5MB。