Redis 缓存穿透 缓存击穿 缓存雪崩 分布式锁 总结

缓存穿透:大量查询数据库中不存在的数据,穿透redis到数据库中查询,导致数据库压力大,可以用布隆过滤器解决

缓存击穿:热门key过期,对于热点key的大量查询需要回数据库中查询,导致数据库崩溃,可以调整热点key的存活时间或者使用锁来解决问题

缓存雪崩:短时间内大量key值过期,大量查询需要回到数据库中查询,导致数据库压力大,redis压力大,应用压力大,恶性循环直到全部崩溃,可以通过将key值得存活时间设置为随机,这样就不会短时间内有大量key值过期

分布式锁:分布式情况下,而进程之间甚至可能都不在同一台物理机上,因此需要将标记存储在一个所有进程都能看到的地方,一个数据库正常上锁没办法让其他分布式数据库也上锁,所以我们需要分布式锁,redis可以被所有数据库共同使用,所以这里介绍如何通过redis实现分布式锁:使用set nx ex

这有两种问题:
问题一:锁过期释放了,业务还没执行完。假设线程a获取锁成功,一直在执行临界区的代码。但是100s过去后,它还没执行完。但是,这时候锁已经过期了,此时线程b又请求过来。显然线程b就可以获得锁成功,也开始执行临界区的代码。那么问题就来了,临界区的业务代码都不是严格串行执行的啦。

问题二:锁被别的线程误删。假设线程a执行完后,去释放锁。但是它不知道当前的锁可能是线程b持有的(线程a去释放锁时,有可能过期时间已经到了,此时线程b进来占有了锁)。那线程a就把线程b的锁释放掉了,但是线程b临界区业务代码可能都还没执行完呢。(可以通过将key的value设为每个线程的uuid,判断自身uuid和key的uuid,如果uuid不同就不能释放锁
问题三:但是这里判断与删除没有原子性,也有可能正要释放,但是时间到了自动释放,被其他线程抢了锁,你释放就会把其他线程的锁给释放了,可以用lua脚本解决)

redis实现分布式锁演变过程:
1.SETNX加锁 + EXPIRE设置过期时间:没有原子性
2.set < key> < value> nx ex < time>:解决加锁和设置过期时间的原子性,存在问题一,问题二
3.set < key> < uuid> nx ex < time>:解决问题二,问题一,问题三
4.set < key> < uuid> nx ex < time>+lua完成(判断加删除):解决问题三,存在问题一
5.开源框架Redisson:只要线程一加锁成功,就会启动一个watch dog看门狗,它是一个后台线程,会每隔10秒检查一下,如果线程1还持有锁,那么就会不断的延长锁key的生存时间。因此,Redisson就是使用Redisson解决了锁过期释放,业务没执行完问题,解决问题一
6.Redisson+Redlock:1到5都是单机redis实现分布式锁,redlock可以通过集群实现分布式锁,规则如下:

i.按顺序向5个master节点请求加锁根据设置的超时时间来判断,是不是要跳过该master节点。
ii.如果大于等于三个节点加锁成功,并且使用的时间小于锁的有效期,即可认定加锁成功啦。
iii.如果获取锁失败,解锁!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值