小白也能看懂的缓存雪崩、穿透、击穿

位流苔原
• 阅读 1813

大家好,我是七淅(xī)。

作为后端开发,我想缓存是大家再熟悉不过的东西了。

本文会介绍出现缓存雪崩、穿透和击穿的业务背景、解决方案和对业务可靠性处理。事先说明,最佳解决方案一定需要结合实际业务调整,不同业务的处理不完全相同

其实我在网上也看过不少关于缓存雪崩、穿透、击穿介绍,不知道是不是大家所做业务的不同,发现有不少小伙伴有以下疑问,比如:

  • 加随机时间过期后,如果访问时间刚好就是加了随机时间后的数据,这样岂不是白加了随机时间?
  • 热点数据不过期,那岂不是有越来越多的脏数据?

就以上问题,我都会在文中一一解释,以下说的缓存都指 Redis。

我争取把这一高频面试题讲明白,如果大家看后能在这块内容和面试官面前谈笑风生,那你就是最靓的仔。

下面,我就开始进入正题啦。

1. 缓存雪崩

即缓存同一时间大面积的失效,这个时候来了一大波请求,都怼到数据库上,最后数据库处理不过来崩了。

1.1 业务场景举例

APP 首页有大量热点数据,在某大型活动期间,针对不同时间段需要展示不同的首页数据。

比如在 0 点时需要替换新的首页数据,此时旧首页数据过期,新首页数据刚开始加载。

而 0 点正在有个小活动开始,大批请求涌入。因为新数据刚开始加载,请求多数没有命中缓存,请求到了数据库,最后就把数据库打挂了。

1.2 解决方案

再强调一下,所谓的解决方案是需要根据实际业务调整,不同业务的处理不完全相同

1.2.1 方法一

常见方式就是给过期时间加个随机时间。

注意这个随机时间不是几秒哈,可以长达几分钟。因为如果数据量很大,按照上述例子,加上 Redis 是单线程处理数据的。那么几秒的缓冲不一定能够保证新数据都被加载完成。

所以过期时间宁愿设置长一点,也好过短一点。反正最后都是会过期掉,最终效果是一样的。

而且过期时间范围加大,key 会更加分散,这样也是一定程度缩短 Redis 在过期 key 时候的阻塞时间。

而至于文章开头说的:「如果访问时间刚好就是加了随机时间后的数据,这样岂不是白加了随机时间」。

现在你结合上例活动的例子,它还会是一个问题吗?结合业务,一定要结合业务。

1.2.2 方法二

加互斥锁,但这个方案会导致吞吐量明显下降。所以还是要看实际业务,像上述例子就不合适用

1.2.3 方法三

热点数据不设置过期。不过期的话,正常业务请求自然就不会打到数据库了。

那新的问题又来了,不过期有脏数据,怎么办?

很简单,活动整体结束后再删除嘛。

那像上述例子,可以怎么处理呢?—— 选择方法一;或者提前把 0 点需要的新数据加载进 Redis,不必等到 0 点才去加载,这样也是可以的

2. 缓存击穿

缓存击穿是指一个热点 key 过期或被删除后,导致线上原本能命中该热点 key 的请求,瞬间大量地打到数据库上,最终导致数据库被击垮。

有种千里之堤,溃于蚁穴的感觉。

2.1 业务场景举例

出现情况一般是误操作,比如设置错了过期时间、误删除导致的。

谁还没误操作过呢,删库跑路了解一下。反正我误删过测试库的数据,幸好人没事,狗头保命。

2.2 解决方案

方法一

代码问题,该 review 的 review。

热点数据到底要不要过期,什么时候过期要明确

既然是热点数据,大概率是核心流程。那么该保证的核心功能还是需要保证的,减少犯错机会。万一出问题,那就是用户的一波输出了。

方法二

线上误操作的事情,该加强权限管理的加强,特别是线上权限,一定需要审核,以防手抖。

PS:若有帮助希望大家可以点赞、在看、转发随便来一份鼓励吧,这对我真得很重要,非常感谢~

3. 缓存穿透

缓存穿透是指:客户端请求缓存和数据库中不存在的数据,导致所有的请求都打到数据库上。如果请求很多,数据库依旧会挂得明明白白。

3.1 业务场景举例

  • 数据库主键 id 都是正数,然后客户端发起了 id = -1 的查询
  • 一个查询接口,有一个状态字段 status,其实 0 表示开始、1 表示结束。结果有请求一直发 status=3 的请求过来

3.2 解决方案

3.2.1 方法一

做好参数校验,对于不合理的参数要及时 return 结束

这点非常重点,做任何业务都一样,对于后端来说,要有互不信任原则

简单来说,就是不要信任来自前端、客户端和上游服务的请求数据,该做的校验还是要做。

因为我们永远都不知道用户会写什么奇奇怪怪的数据;又或者即使你和对接的开发约定好了要怎么传参数,但你保不准他就没遵守呢;退一步来说,万一接口被破解呢。

你要保护好自己,不然到时出问题时,你和老大说,因为谁谁不遵守约定传参导致,或者因为没想到用户会这么填,你看看你老大会这么说(狗头.jpg)

3.2.2 方法二

对于查不到数据的 key,也将其短暂缓存起来。

比如 30s。这样能避免大量相同请求瞬间打到数据库上,减轻压力。

但是后面肯定要去看为什么会有这样的数据,从根本上解决问题,该方法只是缓解问题而已。

如果发现就是某些 ip 在请求,并且这些数据非法,那可以在网关层限制这些 ip 访问

3.2.3 方法三

提供一个能迅速判断请求是否有效的拦截机制,比如布隆过滤器,Redis 本身就具有这个功能。

让它维护所有合法的 key,如果请求参数不合法,则直接返回。否则就从缓存或数据库中获取。

关于布隆过滤器可以看我之前写的文章:布隆过滤器

4. 业务可靠性处理

如开头所说,缓存指 Redis。

  • 提高 Redis 可用性:Redis 要么用集群架构,要么用主从 + 哨兵。保证 Redis 的可用性。

没有哨兵的主从不能自动故障转移,所以只有主从,万一高峰期或者在关键的活动时间节点挂了。

那么等出现线上告警、定位问题、沟通信息、等运维解决,一套操作下来,估计黄花菜都凉了。

  • 减少对缓存的依赖

对于热点数据,是不是可以考虑加上本地缓存,比如:Guava、Ehcache,更简单点,hashMap、List 什么也可以。

减少对 Redis 压力的同时,还能提高性能,一举两得。

  • 业务降级

从保护下游(接口或数据库)的角度考虑,针对大流量场景是不是可以做下限流。这样即使缓存崩了,也不至于把下游全部拖垮。

以及该降级的功能是不是可以降级,提前写好降级开关和降级逻辑,关键时候全靠它稳住。

原创不易,如果觉得文章不错,希望能关注下我的公号:七淅在学Java
点赞
收藏
评论区
推荐文章
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Stella981 Stella981
4年前
Redis 击穿、穿透、雪崩的解决方案
Redis击穿、穿透、雪崩的解决方案击穿和穿透场景:指的是单个key在缓存中查不到,去数据库查询(透过redis去查db叫击穿)区别:击穿:数据在数据库中真实存在,缓存丢失,大量请求击穿数据库穿透:数据在缓存中没有,数据库中也没有
Stella981 Stella981
4年前
Guava的两种本地缓存策略
Guava的两种缓存策略缓存在很多场景下都需要使用,如果电商网站的商品类别的查询,订单查询,用户基本信息的查询等等,针对这种读多写少的业务,都可以考虑使用到缓存。在一般的缓存系统中,除了分布式缓存,还会有多级缓存,在提升一定性能的前提下,可以在一定程度上避免缓存击穿或缓存雪崩,也能降低分布式缓存的负载。Guav
Stella981 Stella981
4年前
Redis持久化机制(文末有福利)
        上一篇主要针对Redis的内存淘汰机制以及Redis容易引发的三大问题:缓存击穿、缓存穿透以及缓存雪崩进行了详细的讲解以及提供了业界常用的解决方案。本篇主要讲讲Redis的持久化机制,Redis受开发者欢迎的一大原因就是因为可持久化的特性。我们如何保证Redis宕机之后重启可以将数据进行恢复?所以一般情
Stella981 Stella981
4年前
Redis 缓存穿透、缓存雪崩的概念及其预防
缓存穿透【什么是缓存穿透】频繁查询不在缓存中的数据,给原本被缓存保护的系统过大压力。【为什么会发生缓存穿透】1\.程序没写好;2\.恶意攻击。【怎样防止缓存穿透】1\.在对key进行查询之前,先做初步判断,如果key一定不存在(例如,对某表的缓存,key一定由数字组成,那么包含非数字的key一定是不存在的
Stella981 Stella981
4年前
Redis之缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级
\TOC\Redis之缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级1、缓存雪崩  发生场景:当Redis服务器重启或者大量缓存在同一时期失效时,此时大量的流量会全部冲击到数据库上面,数据库有可能会因为承受不住而宕机  解决办法:    1)随机均匀设置失效
Stella981 Stella981
4年前
Redis缓存穿透、缓存雪崩和缓存击穿
Redis缓存穿透、缓存雪崩缓存雪崩,是指在某一个时间段,缓存集中过期失效。产生雪崩的原因之一,比如在写本文的时候,马上就要到双十二零点,很快就会迎来一波抢购,这波商品时间比较集中的放入了缓存,假设缓存一个小时。那么到了凌晨一点钟的时候,这批商品的缓存就都过期了。而对这批商品的访问查询,都落到了数据库上,对于数据库而言,
Stella981 Stella981
4年前
Redis缓存穿透、缓存雪崩、并发问题分析与解决方案
(一)缓存和数据库间数据一致性问题分布式环境下(单机就不用说了)非常容易出现缓存和数据库间的数据一致性问题,针对这一点的话,只能说,如果你的项目对缓存的要求是强一致性的,那么请不要使用缓存。我们只能采取合适的策略来降低缓存和数据库间数据不一致的概率,而无法保证两者间的强一致性。合适的策略包括合适的缓存更新策略,更新数
Stella981 Stella981
4年前
Redis 缓存问题及解决方案
【相关概念】缓存击穿:指的是一些热点数据过期,由于热点数据存在并发量大的特性,所以短时间内对数据库的造成很大的冲击,导致系统瘫痪。常见于例如微博系统中明星结婚或出轨时微博瘫痪的情况。缓存雪崩:指的是大量数据或全部数据集中过期失效的情况,这种情况是由于大量数据设置了相同的过期时间而导致的。【使用缓存的流程】
【专项测试系列】-缓存击穿、穿透、雪崩专项测试
作者:刘须华一、背景概述: R2M缓存的使用,极大的提升了应用程序的性能和效率,特别是数据查询方面。而缓存最常见的问题是缓存穿透、击穿和雪崩,在高并发下这三种情况都会有大量请求落到数据库,导致数据库资源占满,引起数据库故障。平时
Redis缓存异常及解决方案
本文向读者解释了Redis使用过程中,数据不一致、缓存雪崩、缓存击穿和缓存穿透等问题的定义,并给出对应的解决方案。
位流苔原
位流苔原
Lv1
汴水流,泗水流,流到瓜洲古渡头,吴山点点愁。思悠悠,恨悠悠,恨到归时方始休,月明人倚楼。
文章
4
粉丝
0
获赞
0