Redis的雪崩与穿透解决方法

1.Redis的穿透、雪崩与击穿

1.1出现穿透的原因

原因:缓存穿透是指用户访问一个数据库和Redis中不存在的key,如果不对这类请求进行过滤拦截的话,请求每次都会穿过Redis直接打到数据库上,并且我们一般是缓存中没数据的时候去数据库中取,取出来之后再放到缓存中,但这类请求所需要的数据在数据库中也不存在,所以即使请求打到数据库上,最终缓存中还是没有数据,在这类请求高并发的情况下,数据库很快就会被拖垮,引起服务异常。

解决方法:
1.API网关
2.限定ip的访问次数.
3.缓存空值
之所以会发生穿透,就是因为缓存中没有存储这些空数据的key。从而导致每次查询都到数据库去了。那么我们就可以为这些key对应的值设置为null 丢到缓存里面去。后面再出现查询这个key 的请求的时候,直接返回null 。
4.布隆过滤器
布隆过滤器:
本质上布隆过滤器是一种数据结构,比较巧妙的概率型数据结构(probabilistic data structure),特点是高效地插入和查询,可以用来告诉你 “某样东西一定不存在或者可能存在”。
相比于传统的 List、Set、Map 等数据结构,它更高效、占用空间更少,但是缺点是其返回的结果是概率性的,而不是确切的。
我们可以在做事务型处理之后,将需要缓存的key放到布隆过滤器中,但是由于布隆过滤器只能保证可能存在,所以在使用过程中还是会有穿透的可能性存在,但概率极小.

1.2出现雪崩的原因

原因:大量的key在同一时刻同时失效,这些key并不一定是设置了相同的时间,也可能是凑巧时间累计在一起了,恰巧大量的针对这些失效的key的请求在同一时间大量的打了进来,这时缓存全部未命中,所有的请求都透传到数据库上,引起数据库压力瞬间扩大数倍,极易导致数据库因负载过高而崩溃,危害极大。
解决方法:
**1.加锁:**对访问的key进行加锁,同时只放一个请求透传到数据库,从一定程度上缓解了数据库的压力,这也是缓存击穿的一种解决方案
**2.队列:**所有的请求全部塞入到队列中,依次打到数据库上,这种方式能解决数据库的压力,但是会给请求处理效率带来一些延迟
**3.随机过期时间:**给key设置过期时间时,在原过期时间的基础上加一个随机时间,比如3000毫秒以内的随机数,这样过期时间重复或者累计重复的可能性降低了很多,不太容易引起大量的key同时失效,并且成本较低。

1.3缓存击穿的原因

**原因:**缓存雪崩是说的大量的key,缓存击穿说的是某一个热点key,也就是在某些时间点会被超高的并发访问。key在某个时间点过期的时候,恰好在对这个Key有大量的并发请求过来,缓存中无法命中则会把请求全部打到数据库,如此大量的请求可能会瞬间把数据库压爆。
解决方法:
1.让业务查询多个redis,并且保证数据不再同一时间失效即可.
2.同步锁:对于热点key,set缓存的时候同时set一个针对这个key的监视key,监视key的过期时间一定要小于被监视的key,每次获取缓存数据的时候都获取一下这个监视key,并判断监视key是否过期了,如果过期了,则重置一下key的过期时间,并重新设置这个监视key
3.临时加锁:对key加上互斥锁,若缓存中命中不了的时候,先给这个key设置一个锁(SETNX),锁的过期时间要非常简短,只有加锁成功的线程才透传到DB,加载完数据后set到缓存中,并释放锁

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值