写点什么

缓存穿透、缓存击穿、缓存雪崩及解决方案

作者:Steven
  • 2022 年 8 月 19 日
    辽宁
  • 本文字数:1594 字

    阅读完需:约 5 分钟

本文先大致介绍缓存的两种模式:内联缓存、旁路缓存,再介绍三种缓存异常情况:穿透、击穿、雪崩的产生原因、现象及解决方案。

缓存模式

缓存分为 Inline cache 内联缓存Cache-aside 旁路缓存两种模式。其中内联缓存又分为了 read through、write through 和 read/write through。

内联缓存

一般不常见,应用不直接访问存储系统,缓存系统在存储系统的前面,数据一致性由缓存系统保证。

比如要读取一个数据,如果缓存系统没有,缓存系统则去存储系统提取数据再返回。

如果要更新一个数据,应用告诉缓存要更新数据,缓存更新自己,同时更新存储系统。

旁路缓存

缓存独立于存储系统,由应用分别控制缓存和存储系统。生产环境一般都会采用。下面的三种缓存异常也基于旁路缓存讨论。

如下图所示,读缓存的场景,分为缓存命中,和缓存缺失两种情况:

缓存命中:计算系统访问缓存,数据存在,直接返回数据。

缓存缺失:计算系统访问缓存,数据不存在,从存储系统提取数据,再更新到缓存,最后返回数据。

缓存穿透

要访问的数据,在缓存和存储系统都没有。如果持续大量的访问则会同时带给缓存系统和存储系统巨大的压力。其实主要是存储系统的压力。

具体来说,查询某个 Key 的数据,缓存系统中没有数据,则直接到存储系统中查询,存储系统中也没有数据,返回空。因为是空,所以缓存系统也不会缓存这个空结果。这样每次查询这个 Key 都会经历这样的查询缓存系统,再查询存储系统的过程。

发生的原因:

业务层误操作,缓存系统中和存储系统中的数据被误删除了。

恶意攻击,专门访问不存在的数据。

解决方案:

缓存空值或缺省值,如果发生穿透,可以针对查询的数据,在缓存系统中缓存一个空值,或与业务约定的缺省值,比如商品数量约定为 0 或 -1。这样后续的访问就不需要再访问存储系统了。

布隆过滤器,在数据写入的时候,使用布隆过滤器做标记。查询时可以快速通过布隆过滤器快速判断数据是否不存在,不存在则不需要访问存储系统了。

请求入口验证,在请求入口端对业务请求数据做合法性校验。

缓存击穿

要访问的数据,在存储系统是有的,但缓存中没有。访问该数据的大量并发请求,一下子都落在了存储系统上面。

发生的原因:

一般发生在热点数据过期失效时。

也有可能发生在热点数据未初始化完成阶段。

解决方案:

设置热点数据永远不过期,如果可预测,设置合理的过期时间。

加锁,控制只有一个查询请求可以访问存储系统,其它请求被锁住,等存储系统的数据返回后更新到缓存,其它请求再读取缓存返回数据。

缓存提前预热,针对热点数据未初始化完成的情况,提前把缓存数据准备好。

缓存雪崩

要访问的数据,在存储系统是有的,但缓存中没有。大量请求在缓存系统无法处理,被发到存储系统,存储系统面临巨大的压力。

发生的原因:

缓存的大量数据同时过期

缓存系统实例发生故障宕机

解决方案:

对于大量数据同时过期

避免给大量的数据设置相同的过期时间,在数据过期时间的基础上添加一定的较少的随机偏移,即满足业务需要,又不会同时过期。

服务降级,保障核心业务在缓存缺失时可以通过直接访问存储系统获取数据。


对于缓存系统实例宕机

熔断和限流,前者为避免发生连锁反应,导致整个存储系统崩溃,暂停业务系统对缓存接口的访问。后者允许部分流量可以直接访问存储系统。

高可靠集群,比如一个主节点宕机了,从节点可以切换为主节点,继续服务。


总结

缓存穿透,是缓存和存储系统都没有数据,每个请求过来都把缓存和存储系统逐个访问一次。

缓存击穿,对于某个或某几个数据,存储系统中有,缓存本来应该有现在却没有,大量并发请求一起打过来要访问这个数据,都打在了存储系统上。

缓存雪崩,大量缓存数据同时过期失效,导致流量都打在了存储系统上。


参考资料

Redis 核心技术与实战(极客时间)

https://medium.com/@mena.meseha/3-major-problems-and-solutions-in-the-cache-world-155ecae41d4f

https://developpaper.com/cache-penetration-avalanche-hotspot-and-redis/


发布于: 刚刚阅读数: 5
用户头像

Steven

关注

还未添加个人签名 2008.07.18 加入

还未添加个人简介

评论

发布
暂无评论
缓存穿透、缓存击穿、缓存雪崩及解决方案_Steven_InfoQ写作社区