高并发下redis缓存出现的问题以及解决方案笔记

本文探讨了高并发环境下Redis缓存遇到的三大问题:缓存穿透、缓存击穿和缓存雪崩,分别给出了相应解决方案。缓存穿透解决方案包括缓存空对象和使用布隆过滤器;缓存击穿解决方案提出使用分布式锁和布隆过滤器;缓存雪崩解决方案建议使用哨兵模式、集群、限流降级以及设置随机过期时间。
摘要由CSDN通过智能技术生成

缓存穿透

缓存穿透是指查询一个根本不存在的数据,缓存层和存储层都不会命中,但是出于容错的考虑,如果从存储层查不到数据则不写入缓存层

解决方案

1.缓存空对象
 把查询到的空结果也缓存到redis中,并给一个较短的过期时间
可能出现的问题:
 缓存层和存储层的数据会有一段时间窗口的不一致,可能会对业务有一定影响。例如过期时间设置为 5 分钟,如果此时存储层添加了这个数据,那此段时间就会出现缓存层和存储层数据的不一致,此时可以利用消息系统或者其他方式清除掉缓存层中的空对象。
2.布隆过滤器
 如下图所示,在访问缓存层和存储层之前,将存在的 key 用布隆过滤器提前保存起来,做第一层拦截。

缓存穿透方案 适用场景 维护成本
缓存空对象 1.数据命中不高 2.数据频繁变化实时性高 代码维护简单,需要过多缓存空间,数据不一致
布隆过滤器 数据命中不高,数据相对固定实时性低 代码维护复杂,缓存空间占用少

缓存击穿

缓存击穿指用户请求的很多数据在缓存中并不存在,导致这些请求在短时间内全部落在数据库上,导致数据库异常。
比如说抢购活动秒杀的接口被用户反复刷新请求。

解决方案

1.redis的分布式锁
* 实现思路:
* 当get某个key为空的时候,通过setNx尝试设置这个key的锁值,成功(当前没有这个锁)则返回,成功获得锁
* 失败,则等待,继续尝试获取锁,如等待超时,返回(未获得锁)
* 死锁:如果某个线程获得锁后,因为某种原因崩溃没能释放锁,导致之后的线程都不能获取锁,而造成死锁。解决方法:给锁加一个过期时间
* 执行过程:
* get某个key为空的时候,通过setNx尝试设置这个key的锁值,锁的设置为uuid。以及失效时间,采用【set key_lock value NX PX 失效时间】命令,NX表示只有在key_lock不存在时才能set成功,PX表示设置key_lock的失效时间,
如果失败返回0,说明该字段已被锁上,那么该线程等待50ms再重试。
如果成功返回1,说明获取到锁,将锁的值保存一份,然后执行业务。业务执行完释放锁(del)
如果获取锁之后执行业务中崩溃了,等key超时后,别的线程可以抢锁进行它的业务。
如果因为A线程某个操作延迟过高导致锁超时,锁被其他线程获取,当A线程准备释放锁的时候,需要先比较当前锁的值和自己持有的是否相同,相同,释放锁,不同

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值