NoSQL之redis缓存雪崩、穿透、击穿概念解决办法

news/2024/11/28 20:48:18/

目录

一:缓存雪崩

1.1概念理解

1.2解决方案

1.2.1数据预热

1.2.2缓存层高可用

1.2.3做二级缓存,或双缓存策略

1.2.4缓存业务添加限流和服务降级策略

1.3举例

二:缓存穿透

2.1概念理解

2.2解决方案

2.2.1缓存空值

2.2.2布隆过滤器拦截

2.2.3其它的方法

2.3举例

三:缓存击穿

3.1概念理解

3.2解决方案

3.2.1分布式互斥锁

3.2.2永不过期

3.3俩种方案对比

一:缓存雪崩

1.1概念理解

所谓的redis缓存雪崩指的是:redis中大量key集中过期或者redis服务器宕机,从而导致大量请求从数据库获取数据,导致数据库服务器访问压力过大,引起数据库压力造成查询堵塞甚至宕机。

1.2解决方案

1.2.1数据预热

可以通过缓存reload机制,预先去更新缓存,再即将发生大并发访问前手动触发加载缓存不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀。

1.2.2缓存层高可用

可以搭建redis集群,保证高可用;缓存层设计成高可用的,即使个别节点、个别机器、甚至是机房宕掉,依然可以提供服务。利用sentinel或cluster实现。

1.2.3做二级缓存,或双缓存策略

采用多级缓存,本地进程作为一级缓存,redis作为二级缓存,不同级别的缓存设置的超时时间不同,即使某级缓存过期了,也有其他级别缓存兜底,比如说nginx缓存。

1.2.4缓存业务添加限流和服务降级策略

在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待。
业界比较常用的做法,是使用mutex。简单地来说,就是在缓存失效的时候(判断拿出来的值为空),不是立即去load db,而是先使用缓存工具的某些带成功操作返回值的操作(比如Redis的SETNX或者Memcache的ADD)去set一个mutex key,当操作返回成功时,再进行load db的操作并回设缓存;否则,就重试整个get缓存的方法。
SETNX,是(SET if Not eXists)的缩写,也就是只有不存在的时候才设置,可以利用它来实现锁的效果。

1.3举例

国内比较知名的一个互联网公司,曾因为缓存事故,导致雪崩,后台系统全部崩溃,事故从当天下午持续到晚上凌晨 3~4 点,公司损失了几千万。

缓存雪崩的事前事中事后的解决方案如下。

事前:redis 高可用,主从+哨兵,redis cluster,避免全盘崩溃。
事中:本地 ehcache 缓存 + hystrix 限流&降级,避免 MySQL 被打死。
事后:redis 持久化,一旦重启,自动从磁盘上加载数据,快速恢复缓存数据。

用户发送一个请求,系统 A 收到请求后,先查本地 ehcache 缓存,如果没查到再查 redis。如果 ehcache 和 redis 都没有,再查数据库,将数据库中的结果,写入 ehcache 和 redis 中。

限流组件,可以设置每秒的请求,有多少能通过组件,剩余的未通过的请求,怎么办?走降级!可以返回一些默认的值,或者友情提示,或者空白的值。

好处:

数据库绝对不会死,限流组件确保了每秒只有多少个请求能通过。
只要数据库不死,就是说,对用户来说,2/5 的请求都是可以被处理的。
只要有 2/5 的请求可以被处理,就意味着你的系统没死,对用户来说,可能就是点击几次刷不出来页面,但是多点几次,就可以刷出来一次。


二:缓存穿透

2.1概念理解

缓存穿透是指查询一个根本不存在的数据,缓存层和持久层都不会命中。在日常工作中出于容错的考虑,如果从持久层查不到数据则不写入缓存层,缓存穿透将导致不存在的数据每次请求都要到持久层去查询,失去了缓存保护后端持久的意义。(对于系统A,假设一秒 5000 个请求,结果其中 4000 个请求是黑客发出的恶意攻击。黑客发出的那 4000 个攻击,缓存中查不到,每次你去数据库里查,也查不到。)

缓存穿透问题可能会使后端存储负载加大,由于很多后端持久层不具备高并发性,甚至可能造成后端存储宕机。通常可以在程序中统计总调用数、缓存层命中数、如果同一个Key的缓存命中率很低,可能就是出现了缓存穿透问题。
造成缓存穿透的基本原因有两个:

  • 自身业务代码或者数据出现问题(例如:set 和 get 的key不一致)
  • 一些恶意攻击、爬虫等造成大量空命中(爬取线上商城商品数据,超大循环递增商品的ID) 

2.2解决方案

2.2.1缓存空值

缓存空对象:是指在持久层没有命中的情况下,对key进行set (key,null)

缓存空对象会有两个问题:

  • value为null 不代表不占用内存空间,空值做了缓存,意味着缓存层中存了更多的键,需要更多的内存空间,比较有效的方法是针对这类数据设置一个较短的过期时间,让其自动剔除。
  • 缓存层和存储层的数据会有一段时间窗口的不一致,可能会对业务有一定影响。例如过期时间设置为5分钟,如果此时存储层添加了这个数据,那此段时间就会出现缓存层和存储层数据的不一致,此时可以利用消息系统或者其他方式清除掉缓存层中的空对象。

2.2.2布隆过滤器拦截

布隆过滤器原理是一个二进制的数组,存储的是0或1,在添加元素时进行多次hash运算,得到多个0或1,存储到相应位置。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。

在访问缓存层和存储层之前,将存在的key用布隆过滤器提前保存起来,做第一层拦截,当收到一个对key请求时先用布隆过滤器验证是key否存在,如果存在在进入缓存层、存储层。可以采用布隆过滤器,使用一个足够大的bitmap,用于存储可能访问的key,不存在的key直接被过滤;访问key未在DB查询到值,也将空值写进缓存,但可以设置较短过期时间。这种方法适用于数据命中不高、数据相对固定、实时性低的应用场景,代码维护较为复杂,但是缓存空间占用少。

2.2.3其它的方法

热点参数的限流降级
进行权限校验
做好数据格式的校验

2.3举例

数据库 id 是从 1 开始的,结果黑客发过来的请求 id 全部都是负数。这样的话,缓存中不会有,请求每次都“视缓存于无物”,直接查询数据库。这种恶意攻击场景的缓存穿透就会直接把数据库给打死。

解决方式很简单,每次系统 A 从数据库中只要没查到,就写一个空值到缓存里去,比如 set -999 UNKNOWN。然后设置一个过期时间,这样的话,下次有相同的 key 来访问的时候,在缓存失效之前,都可以直接从缓存中取数据


三:缓存击穿

3.1概念理解

缓存击穿,就是说某个 key 非常热点,访问非常频繁,处于集中式高并发访问的情况,当这个 key 在失效的瞬间,大量的请求就击穿了缓存,直接请求数据库,就像是在一道屏障上凿开了一个洞。

3.2解决方案

3.2.1分布式互斥锁

只允许一个线程重建缓存,其他线程等待重建缓存的线程执行完,重新从缓存获取数据即可。set(key,value,timeout)

3.2.2永不过期

  • 从缓存层面来看,确实没有设置过期时间,所以不会出现热点key过期后产生的问题,也就是“物理”不过期。
  • 从功能层面来看,为每个value设置一个逻辑过期时间,当发现超过逻辑过期时间后,会使用单独的线程去更新缓

3.3俩种方案对比

分布式互斥锁:这种方案思路比较简单,但是存在一定的隐患,如果在查询数据库 + 和 重建缓存(key失效后进行了大量的计算)时间过长,也可能会存在死锁和线程池阻塞的风险,高并发情景下吞吐量会大大降低!但是这种方法能够较好地降低后端存储负载,并在一致性上做得比较好。

永远不过期:这种方案由于没有设置真正的过期时间,实际上已经不存在热点key产生的一系列危害,但是会存在数据不一致的情况,同时代码复杂度会增大。


http://www.ppmy.cn/news/615758.html

相关文章

恶魔之魂重制版登陆服务器未响应,数毛社分析《恶魔之魂:重制版》 60帧运行,加载超快...

原标题:数毛社分析《恶魔之魂:重制版》 60帧运行,加载超快 魂类游戏《恶魔之魂:重制版》将登陆PS5平台,很多玩家都非常期待该作。近日,数毛社公布了PS5《恶魔之魂:重制版》的游戏演示分析。Rese…

原罪学者 无限连接服务器,黑暗之魂2原罪学者 召唤或连线失败的解决方法分享...

黑暗之魂2原罪学者 召唤或连线失败的解决方法分享 今天为大家带来的是黑暗之魂2原罪学者召唤或连线失败的解决方法分享,一起来看看吧! 自从前几天更新之后无法召唤与被召唤让本人非常苦恼,因为我很喜欢跟别人一起逛街阿!!!!因此我在网路上爬文…

《计算之魂》读书笔记

计算之魂(吴军) 引子 计算的本质——从机械到电子 第 1 章 毫厘千里之差——大O概念 1.1 算法的规范化和量化度量 软件为什么从计算机科学中分离出来? 最初计算机是用于计算,而拥有了计算的基础功能,为了更高效计算更…

Redis中的缓存穿透,缓存击穿,缓存雪崩,分布式锁

目录 一、缓存是什么? 二、缓存穿透 1.缓存穿透是什么 2.解决方案 三、缓存击穿 缓存击穿是什么 2.解决方案 四、缓存雪崩 1.什么是缓存雪崩 2.解决方式 五、使用redis实现分布式锁 总结 一、缓存是什么? 缓存是数据交换的缓冲区,是…

南山驿站机器人_fc机器人大战钢铁之魂攻略

【游戏提示】 一,此次改版一共28关攻略集合多位玩家直播和改版作者资料并由本人亲自 通关测试拼凑而成! 二,这个版本有很多游戏坑,比较重要的都会标红说明,各位玩家要认真看,不完美攻略 要漏掉哪个环节&…

Redis——缓存穿透、缓存击穿、缓存雪崩、分布式锁

文章目录: 1.缓存穿透 1.1 什么是缓存穿透? 1.2 缓存穿透的解决方案 2.缓存击穿 2.1 什么是缓存击穿? 2.2 缓存击穿的解决方啊 3.缓存雪崩 3.1 什么是缓存雪崩? 3.2 缓存雪崩的解决方案 4.分布式锁 4.1 使用setnx del…

勇士传说--

1. 将准备好的素材--变成16像素点-- >Fliter Mode--Point -- >Compression(压缩)--None 2.将素材切割-- Sprite Editor--切割--可以按照像素点切割地图--切割人物可以数格数 3.制作背景-->窗口-->2D-->平铺调色板(Palette)-->拖到检…

计算机之魂

计算机之魂 - 关键四个知识 问题 1 朗道程序员分级法如何把程序员分成七级 朗道分级法 : 1 级最高 7 级最低 能够开创一个产业和一个学科的基础能够提出重要的计算机理论和实践中的新问题 , 并且解决他们 , 并且还能设计和实现别人无法实现的产品能够解决前人未解决的问题,并且…