Redis常见缓存问题

1. 什么是缓存穿透?

缓存一般都是key,value的形式,通过key先去缓存中查,没有再去数据库查。如果故意访问一些本来就不存在就key,就会导致一直去查数据库,如果并发量很大的话,会对数据库造成很大压力。简单来说就是通过不存在的key穿过缓存,请求到数据库
解决方案
1.通过key从数据库没查询到数据也进行缓存,将缓存失效时间设置短一点。
2.对key进行过滤,过滤掉不符合的key(比如布隆表达式)。

2. 什么是缓存雪崩?

当缓存服务器重启或者大量缓存集中在某一个时间段失效,在这段时间大量请求到数据库。
解决方案:
1:在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量,减少数据库压力。(通过key从缓存中没有查询数据时,再查询数据库,对查查询数据库的操作加锁)。

2:不同的key设置不同的过期时间,防止同时大量key过期。

3. 缓存击穿

当前有大量请求访问,刚好某个key过期了,就会同时有许多请求去查询数据库,给数据库造成压力(缓存雪崩是大量key失效)。
解决方案:查询数据库的操作加互斥锁,或者由消息队列来同步数据库信息到缓存中。

4. 缓存一致性

查询步骤

先查询缓存,缓存中没有再查询数据库,然后将查询结果放到缓存中。

更新步骤

1.先更新数据库再更新缓存(不建议使用)

  • 操作步骤(线程A和线程B都对同一数据进行更新操作):
  1. 线程A更新了数据库
  2. 线程B更新了数据库
  3. 线程B更新了缓存
  4. 线程A更新了缓存```
  • 问题1:脏读(正确情况下,缓存中应该放入的是线程b的数据)

  • 问题2:浪费性能

2.先更新数据库再删除缓存

操作步骤(线程A更新、线程B读)

  • 请求A进行写操作,删除缓存,此时A的写操作还没有执行完
  • 请求B查询发现缓存不存在
  • 请求B去数据库查询得到旧值
  • 请求B将旧值写入缓存
  • 请求A将新值写入数据库

解决方案
1:延时双删策略(先删除缓存,然后sleep一会,再删除缓存,影响接口响应速度)
2:使用消息队列

还有一下其他情况,大家可以自行查资料;没有百分百完美的方案,主要是看业务需求,根据具体请求找合适的解决方案。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章