缓存系列:缓存击穿的解决思路

大家好,我是李哥。

上次我们讨论了在分布式系统下的缓存架构体系,从浏览器缓存到客户端缓存,再到CDN缓存,再到反向代理缓存,再到本地缓存,再到分布式缓存。整个链路中有非常多的缓存。

在整个缓存链路,存在各种各样的问题,常见的问题有缓存穿透、缓存击穿、缓存雪崩、缓存数据一致性问题等。不常见的问题有缓存倾斜、缓存阻塞、缓存慢查询、缓存主从一致性问题、缓存高可用、缓存故障发现与故障恢复、集群扩容收缩、大Key热Key等等。

今天我们就来聊聊:缓存击穿

老规矩,先看一下本文大纲:

缓存击穿是什么?

我们知道,缓存的工作原理是先从缓存中获取数据,如果有数据则直接返回给用户,如果没有数据则从慢速设备上读取实际数据并且将数据放入缓存。就像这样:

很多情况下,缓存是存在失效时间的,如果一个缓存数据失效,那么请求就会透过缓存层,打到慢设备层,如果此时这个缓存数据的访问量很大(热点数据),那么慢设备就要承受这波流量轰炸,扛不住可能就宕机了。

就像这样:

这,便是缓存击穿

缓存击穿强调单个key数据过期 + 高并发

缓存击穿的痛点有哪些?

从上面的流程图来看,我们已经知道,最大的痛点就是慢设备宕机了,后面引发一系列的问题相当的严重(整个慢设备宕机,也就是说如果是单库的服务,整个服务几乎不可用;如果是涉及到分库分表的,宕机几个库则散列在这些库的请求几乎不可用)。

其次,服务QPS瞬间下降。假设从缓存取数据需要0.01s,从数据库取数据需要1s,那么1个线程在1s内原本能处理100个请求,现在只能处理1个请求,再假设1个服务的tomcat线程数为200,那么原本1台机器的QPS=线程数 * 每秒处理请求数=200 * 100=20000,现在则变成1台机器的QPS=线程数 * 每秒处理请求数=200 * 1=200。

当并发过大(实际QPS大于200),那么线程数不够用了,用户只能排队等待线程释放,这就是用户反馈的:“什么垃圾网站,卡死了!”。

缓存击穿的解决思路?

一旦发生缓存击穿的问题,看似是慢设备扛不住的问题,实际罪魁祸首的并不是慢设备,为什么这么说呢?

发生这种现象,我认为架构设计是不合理而导致的。在我看来,分为几个阶段治理缓存击穿。

  1. 如果有必要,请隔离
  2. 保证热点数据存在缓存中
  3. 防止热点数据在缓存中没有

如果有必要,请隔离

隔离?怎么隔离?

一般情况下,都是不需要隔离的,因为隔离的成本实在太大了,只有在超级大促活动的时候才会考虑这种隔离方案,比如618、双11、双12。

在这里,这种隔离指的是普通环境与热点环境进行热点隔离,相互不影响。

对此,就算热点环境的慢设备扛不住这种瞬间流量宕机了,它也不影响我们正常环境的请求。

在我们的实际生产环境中,其实还存在其他的一些隔离方案,如:机房隔离,环境隔离,集群隔离,进程隔离,线程隔离,资源隔离等。

保证热点数据存在缓存中

如果是这种高并发的数据,一定需要保证缓存层能够防住。

那么问题来了,如何保证缓存层能够防住呢?

有两种情况,缓存阻塞或宕机导致缓存击穿,缓存数据没有导致缓存击穿。

如果是缓存阻塞或宕机,这种情况下的解决方案是:

  1. 排查宕机的原因,排查慢查询,优化慢查询;
  2. 缓存集群优化或扩容;

如果是缓存没有数据,这种情况下的解决方案是:

  1. 热点缓存数据永不过期
  2. 使用定时任务定时刷新缓存数据与过期时间,保证缓存数据存在

防止热点数据在缓存中没有

在上面,我们已经分析了很多情况下,也做出了许多的布防措施,当然,我们仍然是不能够保证一定是永远可用,仍然无法百分之百保证缓存的数据是永不过期的。

所以,我们还需要考虑一个兜底的方案:假设缓存没有,那该怎么办?

如果不作为,一旦发生这种情况有可能服务和数据库都宕机了,然后就...收拾书包就回家了。

所以一定要作为。

不知道大家还记不记得在上一篇文章中提到的,将「高并发转变为低并发」,详情可以看看之前的一片文章:

原理就是当缓存层被击破了,那么会存高并发的请求达到慢设备,我们可以将「高并发转变为低并发」。多数情况下我们都是使用分布式锁。

而使用分布式锁又有很多方案:

  1. 数据库唯一键
  2. 数据库悲观锁
  3. 基于redis的setnx原理
  4. 基于Redisson实现
  5. 基于Zookeeper实现

对于锁,不是我们今天的主题,后续我们会推出锁系列相关的文章,敬请期待。

总结

概念:缓存击穿指的是单个数据过期,加高并发的请求打到慢设备后有可能导致慢设备宕机。

现象:慢设备宕机、服务QPS直线下降、用户反馈网站慢

解决方案:

  1. 提高缓存高可用;
  2. 保证热点数据存在缓存;
  3. 访问慢设备时由高并发转低并发(一般使用分布式锁);

感谢阅读,关注我,助你成为架构师。

你的分享、点赞、在看将是对我最大的支持!

猜你喜欢

转载自juejin.im/post/7078296204097880100