Redis常见问题

122 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第14天,点击查看活动详情

1. 击穿

当大量并发业务访问Redis获取数据时,由于数据过期已清除,或其他原因数据已经不存在了,而导致大量并发直接访问到数据库。

解决思路

并发很大,但是要阻止并发到达数据库,redis里又没有key

解决方案

  1. 所有有线程都来get key
  2. 因为key已经不存在了,在得到null的结果后,向缓存中设置值,setnx,这个相当于一把锁,只有在不存在的时候才能设置成功
  3. 设置成功的,去数据库取数据,并存储到缓存中
  4. 设置失败的,休眠随机时间后又从第一步开始。随机时间是为了避免又同时去取值。

方案的问题

1.死锁,第一个线程若是获取数据的时候出现意外,线程挂了。则后边的数据无法拿到锁,而一直休眠。

  • 解决方案,拿到锁的时候,设置一个过期时间,在指定时间没返回,锁自动过期。

2.给锁设置过期时间之后,获得锁的线程没挂,但是锁超时了怎么办。

  • 解决方案,新建一个线程,监控是否取回数据和线程是否正常,然后去循环检查和更新锁的时间

2 穿透

从业务接受并查询的是数据库根本不存在的数据。并且缓存里也没有。

解决方案:布隆过滤器

布隆过滤器的缺点,只能增加,不能删除

解决方案,在删除数据的时候,设置一个空key,在查到有key但为空的时候,直接返回,不去数据库查询。

3 雪崩

大量的key同时过期,间接造成大量的访问到达数据库。比如设置大量的key为半夜12点过期,此时有大量并发到来,则访问全部到达了数据库。

解决方案
对于雪崩的问题,解决思路有两种

  1. 若是数据时点性无关,也就是数据和时间没有关系,则可以设置随即过期时间,避免同时过期。
  2. 若是时点性相关,比如贷款利率过了12点必须变化,薪资半夜12点调整等,则强依赖击穿方案。
  3. 或是在业务层,加判断,零点延时。在业务中请求数据的时候判断时间,若是快到12点了前一秒直接延时3秒。此时数据将没有问题。

4 redis做分布式锁

主要就是三点:

  1. 使用setnx获取锁
  2. 添加过期时间,避免死锁
  3. 新建守护线程,检测主线程是否正常并延长锁过期时间