zoukankan      html  css  js  c++  java
  • 关于缓存的几个问题

      这里的缓存是指各个缓存框架,比如现在比较火的redis、memcached,以及有些过气的ehcache、oscache等。缓存作为挡在数据库前面的屏障,减少DB的调用次数,起到了绿化带似的缓冲和隔离作用。又因为缓存的存储特性能起到快速存取、提高响应速度的作用。这里不谈缓存的好处,只聊缓存的几点麻烦。

      一、缓存并发。适用场景:某缓存KEY在短时间内被大量查询,刚好发生在缓存KEY刚好到达过期时间的那一刻,或者DB刚好更新数据通知缓存也做了更新的那一刻。在这个时间点,缓存是没有数据的,那么自然要到DB来查了,并发带来的查询压力顺势传递给DB。

    应对措施:针对缓存查询加锁,只放第一个查询直达DB,其他查询锁在外面。当第一个查到数据后把锁解开,其他查询这时从缓存就能查到数据了。

      二、缓存穿透。适用场景:某缓存KEY没被命中,DB也没数据。因为DB永无数据,缓存永远无法命中,请求每次都将直达DB。形象的说就是穿透,或者击穿。少量这种请求的话关系不大,如果是大量、并发的话,DB脆的当场就跪了。

      应对措施1:返回空值时也缓存起来,下次查询请求还来,缓存就说是空值打发了,把DB保护起来。对并发、重复刷是顶住了,但如果量大的话,要耗内存,可能会挤掉其他正常的数据,需要设置一个较短的过期时间,用完就扔。

      应对措施2:把这种值不存在的key都收集到一个集合中,后续请求若在集合中则直接过滤。如果量大的话,维护该这个黑名单也是个麻烦事,而且每次请求都来黑名单点一次名也是件费力的事。

      三、缓存雪崩。适用场景:缓存启动、重启或失效时间设置不均衡,导致大量缓存同一时间失效。假设所有缓存同时失效,那么这一刻缓存就对DB失去了意义,DB只能裸奔了。当然后面数据还会慢慢重新加载到缓存,DB边裸奔边穿衣,前提是能扛得住。

      应对措施1:针对启动、重启的情况规划缓存预热。针对缓存KEY约好一起失效的情况,从设置失效时间入手,不能让它们约,给不同的KEY设置失效时间。简单点设置随机时间,业务有规划的按不同KEY进行规划。

      应对措施2:问题既然是缓存失效引起的,那么就不要失效了。一层永久、全量缓存,一层本地缓存,搞二级缓存。麻烦是加机器、重搭缓存框架,伤筋动骨。

  • 相关阅读:
    hibernate关联关系(多对多)
    hibernate关联关系(一对多)
    hibernate主键生成策略
    hibernate01
    利用Struts2拦截器完成文件上传功能
    layui的CRUD案列
    Struts2的CRUD
    Git中.gitignore文件不起作用
    在 Visual Studio 中使用 Q# 进行量子编程
    Elasticsearch 搜索
  • 原文地址:https://www.cnblogs.com/wuxun1997/p/7758246.html
Copyright © 2011-2022 走看看