首页 > 数据库 >Redis 缓存击穿,缓存穿透,缓存雪崩原因+解决方案

Redis 缓存击穿,缓存穿透,缓存雪崩原因+解决方案

时间:2023-09-11 20:22:30浏览次数:48  
标签:缓存 请求 过期 Redis redis 雪崩 key 解决方案

缓存击穿,缓存穿透,缓存雪崩的原因

  • 缓存击穿:key对应的数据存在,但在redis中过期,此时若有大量并发请求过来,这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮。
  • 缓存穿透:key对应的数据在数据源并不存在,每次针对此key的请求从缓存获取不到,请求都会到数据源,从而可能压垮数据源。比如用一个不存在的用户id获取用户信息,不论缓存还是数据库都没有,若黑客利用此漏洞进行攻击可能压垮数据库。
  • 缓存雪崩:当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,也会给后端系统(比如DB)带来很大压力。

缓存击穿的解决方案

使用互斥锁(mutex key)业内常用

若有大量的请求直接打到数据库上,会导致数据库崩溃,那么就先用redis互斥锁,使得所有的请求只有一个请求能拿到资源,等查到数据后,再将数据写回缓存。

其余的请求申请不到锁的时候,意味着已经有请求拿到资源了,所以只需要sleep一段时间(等数据写入缓存),再次去读取缓存即可。

让redis的key永不过期(可行但不好)

  • 设置key永不过期,在修改数据库的时候,同时更新缓存。
  • 在key将要过期的时候,去更新这个key,延长他的过期时间。
  • 分级缓存,一级缓存失效,还有二级缓存垫背。

为什么不好?因为数据的量巨大,我们的 redis 缓存,是基于内存的,一个单点,一般也不会分配过大的内存,来保证它足够灵活。

如果永不过期,那么redis就会越来越臃肿,没有初衷了。

 

使用redis锁的解决方案思路图:

针对互斥锁的思路完善这个解决方案

问题1

如果用户请求完锁之后还没来得及释放就挂了,那么锁就会一直被占用,后面的用户就不能正常工作了。

解决方案:给这个锁设置过期时间,保证无论如何一定会被释放。

问题2

如果用户请求完锁之后,锁到期了依旧没有完成业务,那么其余的用户就会抢占这个锁,互相卡来卡去超时。

解决方案:开一个线程去监控锁的过期时间,如果锁临近过期了还没完成事务,就会延长锁的过期时间。

应用:Redisson自带的看门狗函数。

问题3

如果碰见redis集群的场景,且申请锁的redis挂了,那么就会影响redis的主从一致性。

解决方案:加锁的 redis 结点,只要满足,N/2+1,也就是过半,即代表加锁成功。(Redlock)

在整个加锁过程中,整个加锁的过程,不能超过锁的有效时间,否则,就应算作加锁失败,要立刻清除所有单独结点上的锁。

 

缓存穿透的解决方案

布隆过滤器

将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被 这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。

用bitmap,采用多次哈希的方式,每一次哈希都往一个槽位写上 1; 当来查询一个不存在的 key 的时候,就可以进行同样的多次哈希,第一次可能碰巧撞对,得到 1,但是后面还有两次,这样,就不一定有那么好的运气,还能够撞对。 因此,这样,可以降低缓存穿透的概率。

布隆过滤器的示意图

 

无效值也加入redis

比较简单的,就是选择,当用户查询不存在的数据时,将这个 key,存入 redis,然后用一个特殊的 value 来表示,这是一个不存在的数据。
缺点:但是,如果有大量的请求,都请求各不相同的不存在的数据,那么,redis 的缓存,就会用来存储大量没用的数据,就会造成空间的浪费。

 

缓存雪崩的解决方案

有一个简单方案就时将缓存失效时间分散开,比如我们可以在原有的失效时间基础上增加一个随机值,比如1-5分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。

或者Redis查DB数据的时候将请求加一个随机延迟时间,让请求不要集中。

 

一般随机失效时间就已经能完成任务了,但是如果有强更新强同步的需求(12点清空数据等)。

第二个随机延迟时间的方法能完成需求,因为随机延迟时间请求,一方面能降低请求的压力,第二方面第二波请求可以从redis读取数据,进一步降低压力。

 

 

标签:缓存,请求,过期,Redis,redis,雪崩,key,解决方案
From: https://www.cnblogs.com/xiaochaoheni/p/17693938.html

相关文章

  • redis连接失败
     本次连接redis失败记录,密码全为0,不加“”认证会失败springboot yml配置 密码为0时,要加“”很经典的错误,记录一下......
  • redis集群
    Redis集群本章是基于CentOS7下的Redis集群教程,包括:单机安装RedisRedis主从Redis分片集群1.单机安装Redis首先需要安装Redis所需要的依赖:yuminstall-ygcctcl然后将课前资料提供的Redis安装包上传到虚拟机的任意目录:例如,我放到了/tmp目录:解压缩:tar-xzfredis-6......
  • 分享一个 SpringBoot + Redis 实现「查找附近的人」的小技巧
    前言SpringDataRedis提供了十分简单的地理位置定位的功能,今天我就用一小段代码告诉大家如何实现。正文1、引入依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>2、更......
  • redis-实战篇-商户查询缓存
    基本思路添加缓存的原则:动态数据不要加缓存缓存cache:数据交换的缓冲区。一般读写性能较高。比如浏览器缓存,浏览器会将一些经常使用的数据缓存到本机,这样在多次加载时就不需要访问服务器,而浏览器未命中的缓存则会去tomcat获取。缓存的作用:降低后端负载、提高读写效率、降低响应......
  • Redis的缓存穿透、缓存雪崩、缓存击穿问题及解决方案
    Redis的缓存穿透、缓存雪崩、缓存击穿问题及解决方案缓存穿透问题及解决思路缓存穿透:缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在,这样缓存永远不会生效,这些请求都会打到数据库。因为我们查数据通常是现在redis缓存查数据,如果redis没有这个数据,就会去数据库查。如......
  • 七、Nginx缓存机制
    对于性能优化而言,缓存是一种能够大幅度提升性能的方案,因此几乎可以在各处都能看见缓存,如客户端缓存、代理缓存、服务器缓存等等,Nginx的缓存则属于代理缓存的一种。对于整个系统而言,加入缓存带来的优势额外明显:减少了再次向后端或文件服务器请求资源的带宽消耗。降低了下游服务器的......
  • 监听canal实现缓存同步
           ......
  • Linux下安装Redis的详细安装步骤
    一.Redis安装1.下载linux压缩包【redis-5.0.5.tar.gz】2.通过FlashFXP把压缩包传送到服务器3.解压缩tar-zxvfredis-5.0.5.tar.gz4.进入redis-5.0.5可以看到redis的配置文件redis.conf5.基本的环境安装使用gcc-v命令查看gcc版本已经是4.8.5了,于是就没有再次安装,直接......
  • nginx本地缓存
           ......
  • 查询Redis
            ......