Redis-缓存设计与优化
标签:Redis

Redis缓存设计与优化

1. 受益和成本

受益:

成本:

使用场景:

2. 缓存更新策略

  1. LRU/LFU/FIFO算法剔除:例如maxmemory-policy
  2. 超时剔除:例如expire
  3. 主动更新:开发控制生命周期

对比:

策略 一致性 维护成本
LRU...算法剔除 最差
超时剔除 较差
主动更新

使用建议:

3. 缓存粒度

  1. 通用性:缓存全量属性比较好
  2. 占用空间:缓存部分属性比较好
  3. 代码维护:表面上全量属性更好

选择缓存的粒度的时候要根据自己的实际情况,看是否需要全部属性已经内存空间来说还是选择部分属性

4. 缓存穿透问题

大量的请求在缓存层没有命中,总是去后台获取数据,造成缓存失效,加大后台的负担

主要原因可能是自身代码逻辑出现问题或者遭受恶意攻击、爬虫去大量爬取不存在的键,这个时候可以通过缓存空对象,即就算从后台取出的值为空,我也在cache层缓存一个空值,并加上过期时间,但是它可能会需要更多的键。

还有一种原因导致后台返回为空,可能当时后台出现短期不可用,不过这种情况可以通过当后台好了的时候给cache层一个信号,强制刷新缓存。

5. 缓存雪崩

如何避免?

1:在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待。

2:不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀。

3:做二级缓存,A1为原始缓存,A2为拷贝缓存,A1失效时,可以访问A2,A1缓存失效时间设置为短期,A2设置为长期(此点为补充)

6. 热点key重建优化

到了缓存重建时间,大量的线程去做查询数据源和缓存重建操作,将会导致程序响应变慢,而且也会造成后端的压力变大。

互斥锁:

通过互斥锁保证只有一个线程去查询数据源并重建缓存,其他线程进入等待状态,直到获取缓存可以直接输出。

永不过期:

对比:

方案 优点 缺点
互斥锁 思路简单
保证一致性
代码复杂度增加
存在死锁的风险
永不过期 基本杜绝热点key重建问题 不保证一致性
逻辑过期时间增加维护和内存成本
  • 4 min read

CONTRIBUTORS


  • 4 min read