十、redis缓存设计

缓存更新策略

由于缓存中的数据和真实数据会有一段时间窗口不一致,所以针对不同要求和场景,采取不同的策略

  1. LRU(Recently)、LFU(Frequently)、FIFO算法剔除
    一致性较差,开发人员只能决定使用哪种算法,但相对应维护成本低
  2. 超时剔除
    使用redis的expire命令,在一定程度上减少了一致性问题,且维护成本不是很高。
  3. 主动更新
    对于应用对数据一致性要求非常高的情况下使用,需要再真实数据更新后,立即更新缓存数据。

缓存穿透

缓存穿透是指查询一个根本不存在的数,那么缓存层和存储层都不会命中,它导致的问题就是,如果有大量的请求同时访问一个不存在的数据,那么就可能导致后端存储层如数据库不可用
原因一般有:

1. 自身业务代码或者数据问题
2. 恶意攻击、爬虫等

解决方案:

1. 对空对象,也加入一个缓存并设置一个较短时间的过期时长
2. 布隆过滤器拦截,布隆过滤器会对以往的数据进行统计,如果访问一个没有存在过的数据,则会认为数据不存在,从而保护存储层。

缓存击穿

缓存击穿是指,当一个热点数据在某一个时间失效,这个时候并发量非常高,就会容易导致大量并发访问存储层,并且也可能导致多个线程重建缓存导致应用崩溃
解决的思路就是减少重建缓存的次数,方案:

1. 使用互斥锁,查询数据库并重建缓存的时候只运行一个线程操作,其他线程等待其建完再读缓存(可以使用setnx实现分布式锁),存在死锁和线程池阻塞的风险
2. 物理上永不过期,也就是给value设置一个逻辑过期时间(非redis过期时间),每次查询都去检查,如果发现超过过期时间,则重置缓存。存在一致性问题。

缓存雪崩

缓存雪崩,是指如果缓存层存储了大量请求数据,但某个时刻不能提供服务,那么所有的请求都会到达存储层。

解决方案:

1. 保证缓存层的高可用
2. 依赖隔离组件为后端限流并降级比如hystrix

无底洞优化

主要是针对批量操作来讲,如果节点过多,那么使用批量命令时