架构学习笔记--缓存-缓存穿透:缓存雪崩:缓存热点

1 篇文章 0 订阅
1 篇文章 0 订阅

什么是缓存穿透

缓存没有生效,大量请求访问某一个key的数据 , 实际缓存中并不存在该key的缓存 , 然后都转而降级查询DB 去了,最终的结果是DB查询压力增大。

关键词:缓存未生效,导致DB压力骤增

可能的发生场景
  • 某一个很偏僻的数据, 因为程序bug或者某种重试机制 , 或者某一活动突然请求查询该数据 , 使用了这种接口;
  • 操作有误 ,活动前提是需要先做一个操作产生数据然后活动才能开始;
  • 设计上不合理,有些数据永远不会变,所以就直接放到缓存中永不过期,但是又是热点数据,后来因为某些问题导致缓存丢失;
  • 缓存生成本身需要耗费大量的时间和资源;
  • 黑客攻击, 故意访问不存在的数据,拖垮系统 ;
  • 爬虫爬取数据
解决办法
  • 对没有命中的空值进行缓存,过期时间根据实际情况设置
  • 尽量避免人为操作失误导致,对于可能发生热点访问的缓存数据多演练
  • 系统监控要做好,尽量保证在第一时间感知问题并解决,识别出爬虫并禁止访问/返回固定数据

什么是缓存雪崩

缓存失效后由于需要重新生成缓存,在生成缓存的时间内接收到的请求大量请求,引起系统性能骤然下降。

解决办法

更新锁机制

对缓存更新进行加锁保护,保证只有一个线程能够进行缓存的更新,未能获取更新锁的线程要么等待锁释放后重新读取缓存,要么就返回空值或者默认值。

分布式集群的业务系统要实现更新锁机制,需要使用分布式锁,如zookeeper。

后台更新机制

缓存本身的有效期设置为永久,后台线程定时更新缓存。

后台定时更新机制需要考虑一种情况,当缓存系统内存不足时需要踢掉一些缓存数据,从缓存被踢掉,到下一次定时更新缓存的这段时间内,业务线程读取缓存返回空值,会给人一种数据丢了的感觉,解决方式如下:

  • 后台线程除了定时定时更新缓存外还需要频繁地读取缓存,如果发现缓存被踢了,就立刻更新缓存。(读取间隔不宜过长,否则业务线程还是读不到数据,用户体验一般)
  • 业务线程发现缓存失效后,通过消息队列发送消息通知后台线程更新缓存。可能存在多个业务线程发消息更新缓存的情况,不过更新线程可以判断缓存是否已经存在,存在就不会执行更新操作,这种方式虽然实现复杂度稍高一些,但是用户体验好,更新及时。

后台更新既适合单机多线程的情况也适合分布式集群的场景,相比更新锁机制更简单一些。

后台更新机制还适合业务刚上线的时候缓存预热。

缓存预热 是指系统上线后将相关的缓存直接加载到缓存系统,而不是等待用户方位才触发缓存加载。

缓存热点

虽然缓存系统本身的性能比较高,但对于一些特别热点的数据,如果大部分甚至所有的业务请求都命中同一份缓存数据,则这份数据所在的缓存服务器的压力也很大。例如,某明星微博发布“我们”来宣告恋爱了,短时间内上千万的用户都会来围观。

缓存热点的解决方案就是复制多份缓存副本,将请求分散到多个缓存服务器上,减轻缓存热点导致的单台缓存服务器压力

以微博为例,对于粉丝数超过 100 万的明星,每条微博都可以生成 100 份缓存,缓存的数据是一样的,通过在缓存的 key 里面加上编号进行区分,每次读缓存时都随机读取其中某份缓存。

缓存副本设计有一个细节需要注意,就是不同的缓存副本不要设置统一的过期时间,否则就会出现所有缓存副本同时生成同时失效的情况,从而引发缓存雪崩效应。正确的做法是设定一个过期时间范围,不同的缓存副本的过期时间是指定范围内的随机值。

极客时间版权所有: https://time.geekbang.org/column/article/8640

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值