redis缓存

33 阅读3分钟

redis是目前最常用的一种nosql数据库,他基于内层运行,性能高效,并且可以实验分布式。在目前的很多场景里面都有使用。

redis的使用场景:

  • 缓存
  • 分布式锁
  • 计数器
  • 保存token
  • 消息队列
  • 延迟队列

其中缓存是一个重点知识:需要了解缓存的穿透击穿和雪崩,还需要了解双写一致和持久化,并且还有数据过期和淘汰策略。

缓存穿透、击穿和雪崩

常见问题:你的项目里面使用了redis缓存,那么关于缓存三兄弟(缓存穿透、击穿和雪崩)你了解哪些?

提问理由:了解项目真实性以及深入发问的切入

  1. 穿透:查询一个不存在的数据,数据库查询不到就不会写入redis,导致每次请求都会访问数据库。

image.png

如果这种不存在的查询非常多,很容易把数据库弄挂。

  • 解决方法1:缓存空数据

没有查询到的数据,在redis里面存储null。(能移动程度解决上面的问题,但是如果每次换一个条件,不同的不存在条件查询,数据库还是容易挂)

  • 解决方案2:加入布隆过滤器

image.png

布隆过滤器就是一个以位为单位的数组,通过三次不同的hash计算得到位置,把位置变成1.查询布隆就是把条件拿去做三次hash,看是不是都是1,如果是表示存在,表示表示不存在。但是可能会出现误判情况,因为数组长度有限。

  1. 击穿:热点数据过期瞬间,非常夺取请求进入。
  • 解决方法1:互斥锁 就是访问时候加锁,如果缓存没有命中,就去数据库查询,这时候其他线程只能被阻塞。(保证了强一致性)
  • 解决方法2:逻辑过期(就是不设置过期时间,性能好)
  1. 雪崩:同一时间大量缓存失效 解决方法:如果是因为缓存时间设置不当,使用随机缓存失效时间,如果是redis宕机,采用主从同步和哨兵模式。

参考:项目中缓存是如何使用的 - 掘金 (juejin.cn)

双写一致性

保证数据库和缓存里面数据一致。

读取比较简单,比如先查询缓存缓存没有查数据库。

怎么进行写操作,比如更新?

延迟双删:其实就是先删除缓存,然后修改数据库,延迟一定时间后,再次删除缓存(因为修改数据库后,需要一定时候对缓存进行更新,延迟一定时间后,数据库主从同步好了,删除缓存,再次查询就一定是之前数据)

但是延迟多久?这个和具体网络环境有关,没有具体的数据。

所以一般我们都是读用共享锁,写有互斥锁完成

数据过期策略

  • 惰性:使用时候检测,过期删除(不好:容易内层满)
  • 定期:定期随机挑选一些key,把里面过期的删掉