缓存陷阱

来源:互联网 发布:mac 启动 磁盘工具 编辑:程序博客网 时间:2024/05/29 15:17

场景


   促销满减活动需求,例如满200减100,满100减20 ,这样可以配置满减的阶段,以及计算非满减和满减后的价格进行结算。
接口设计
   在设计过程中需要这样的一个接口,获取该电子书参与的所有促销的活动(为了扩展限时抢活动),并且为了扩展满减需要设置满减池子,也就是把参与满减的书籍放到满减的池子中。
错误地方
   在与之相关的业务逻辑,需要判断该书是否在满减书籍的池子中,当时没有过多的思考,满减池子中的书籍已经做了缓存,我直接从缓存中取出来,通过productIds.contains(productId),也就是每个书籍的id都要去判断一次,当把满减池子中的书籍加到不到19w的时候,性能上就出现了问题,也即是池子中的Id数量为19w,判断某一个Id是否在其中。 


改版第一版本
   由于上次的问题,所以把判断放到了db,通过书籍池子中的唯一标识和该本书的productId 来查找该电子书的内容,同时对该书籍添加了缓存,以及对该数据是否参与满减活动添加了缓存。通过测试,当满减书籍的池子19w的时候,测试结果:ELK监控数据hpi访问量每30秒访问数最高8000,最后稳定在7000左右,访问量为高峰期的2倍左右。 服务器监控cpu稳定在15%,服务器正常 ,服务器端平均每秒处理事务515.90。


改版第二版本

   线上当满减的池子设置的非常小时,倒是出现了问题,报大量的数据库连接超时问题,问题所在一部分在于,添加缓存的时候,当获取满减池子书籍为空的时候没有添加缓存,也就是只有参与满减的活动才有缓存,而没有参与满减活动的电子书则没有缓存(CollectionUtils.isNotEmpty,添加了是否为空的判断,则丢了一部分缓存),在添加缓存之前判断了,造成大量的数据库访问。


   之前设置的缓存失效时间为15min,当缓存大量同时失效的时候,会造成缓存同时构建,同时访问数据,造成对db访问的压力。
   于是在缓存失效的时候添加一个随机数,这样就不会缓存同时失效,减少同时访问db的压力。
code如下
masterRedisTemplate.expire(columnMediaIdCacheKeyFlag,
      Constans.CACHE_EXPIRE_TIME_OF_MEDIA_PROMOTION_FLAG
        + RandomUtils.nextInt(100), TimeUnit.SECONDS);


参考文章:http://blog.csdn.net/black_ox/article/details/28424371


   总结:

   不晓得错过了什么,不晓得得到了什么,人生的每个阶段都有舍得。继续go on



1 0
原创粉丝点击