注意cache同时过期问题

[文章作者:孙立 链接:http://www.cnblogs.com/sunli/ 更新时间:2010-09-06

     记得在去年,一个应用有个比较消耗资源的后端查询,使用memcached做了一层缓存,缓存时间30分钟(按业务需求来讲,更长点也没关系),按理说,应该完全没有任何问题了,但是出现了一个奇怪的问题,就是在高峰期重启memcached后,会导致大量的后端查询,出现后端服务不过来的情况。这点倒是可以理解。但是在正常运行过程中,随着访问的增加,查询也是一阵阵的访问数据库,形成一个波浪式的访问。

     还记得在08年刚来公司的时候,有一个tomcat下的java应用,缓存是构建在jvm内部的(事实上,很多java应用的缓存都是构建在jvm内部的,因为简单,效率非常高),随着业务量的增加,支撑不了访问量,频繁宕机,宕机重启tomcat是个很大的问题,根本没发直接启动,启动后几秒就又会宕掉,只能把流量在nginx上挡开,让tomcat启动起来了,等待内部缓存建立,大概会需要10-20分钟,再上线服务。

     上面的两个问题都是缓存在同一时间过期造成的。比如应用的某个功能的数据,在缓存的时候都设置成缓存30分钟,那么在cache重启后,将同时产生大量的后端查询来重建缓存,大量的数据都被设置在30分钟过期,30分钟过后,又几乎同时需要对后端进行查询来重构失效后的缓存,这无形对数据库造成了一些不必要的风险。如下图

 图一:cache 同时过期的波浪式穿透db

 

     解决办法:

     在一个比较大的应用中,cache尽量使用服务的形式,跟web应用进行隔离开来,避免应用重启导致重建cache对后端的冲击。(其实这样能提高多个web下面的缓存利用率)

     cache服务尽量使用多个,避免一个宕机重建全部cache对后端的冲击。多个cache服务尽量使用一致性hash的模式。

     cache同时过期的问题,比如是30秒过期,可以找个业务可以接收的范围,比如25-40秒之间随机一个过期时间,可以减少同时过期的概率。

     可以考虑使用多级cache。

     事实上,在设计系统的时候,就需要考虑cache如果失效对系统产生的可能冲击影响,以及如何去避免这些问题的发生。重启系统可以考虑一个缓存预热的过程。

 

posted @ 2010-09-06 13:15 草屋主人 阅读(...) 评论(...) 编辑 收藏