redis 热点key问题及其解决方案

打印 上一主题 下一主题

主题 866|帖子 866|积分 2598

缓存穿透+解决方案


  • 缓存穿透(查询不存在的数据)

    • 查询不存在的缓存,由于缓存不命中,并且出于容错的考虑,就会进入存储层查询
    • 而如果从存储层查不到数据也不将这个不存在的数据写入缓存,
    • 风险:如果查询大量这种不存在数据查询请求,不命中缓存,也不写入缓存,一直请求存储层,DB很有可能会挂

  • 预防

    • 接口层增加校验,数据合理性校验
    • 缓存和数据库都没有的,可以将key-null写入缓存,设置短时间过期,防止被同一个key一直攻击

  • SpringCache解决方案

    • 空结果也缓存,默认不配置condition或者unless就行

  1. cache:
  2.    #使用的缓存类型
  3.     type: redis
  4.    #过期时间
  5.     redis:
  6.       time-to-live: 3600000
  7.       # 开启前缀,默以为true
  8.       use-key-prefix: true
  9.       # 键的前缀,默认就是缓存名cacheNames
  10.       key-prefix: XD_CACHE
  11.       # 是否缓存空结果,防止缓存穿透,默以为true
  12.       cache-null-values: true
复制代码
缓存击穿+解决方案


  • 缓存击穿

    • 热点key失效时,这一刻,有大量该热点key请求未命中缓存,从数据库查找,导致数据库请求量暴增,压力增大

  • 预防

    • 设置热点key永不过期
    • 定时任务更新热点缓存
    • 设置互斥锁

  • SpringCache解决方案

    • 缓存的同步 sync
    • sync 可以指示底层将缓存锁住,使只有一个线程可以进入计算,而其他线程堵塞,直到返回结果更新到缓存中

  1. @Cacheable(value = {"product"},key = "#root.args[0]", cacheManager = "customCacheManager", sync=true)
复制代码
缓存雪崩+解决方案


  • 大量的key设置了相同的过期时间,导致在缓存在同一时刻全部失效,造成瞬时DB请求量大、压力骤增,引起雪崩
  • 预防

    • 存数据的过期时间设置随机,防止同一时间大量数据过期现象发生
    • 设置热点数据永远不过期,定时任务定时更新

  • SpringCache解决方案

    • 设置差别的过时时间
    • 比如CacheManager配置多个过期时间维度
    • 配置文件 time-to-live 配置
    1. cache:
    2. #使用的缓存类型
    3. type: redis
    4. #过期时间
    5. redis:
    6. time-to-live: 3600000
    7. # 开启前缀,默以为true
    8. use-key-prefix: true
    9. # 键的前缀,默认就是缓存名cacheNames
    10. key-prefix: XD_CACHE
    11. # 是否缓存空结果,防止缓存穿透,默以为true
    12. cache-null-values: true
    复制代码
热点key+解决方案

热点key存储不当的危害:缓存中的某些Key对应的value存储在集群中⼀台机器,使得所有流量涌向同⼀机器,成为系统的瓶颈,⽆法通过增加机器容量来解决
解决方案


  • 避免带宽或者传输影响,本地缓存热点key数据,对于每次读请求,将⾸先检查key 是否存在于本地缓存中,如果存在则直接返回,如果不存在再去访问分布式缓存的机器
  • 高可用集群,或主从哨兵模式,将热点key存储到本地缓存,且数据存储分配均匀

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

光之使者

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表