redis缓存设计及常用问题

861 阅读3分钟

redis缓存设计及常用问题

缓存的收益与成本分析 缓存更新策略的选择以及使用场景 缓存粒度控制法 穿透问题优化 无底洞问题优化 雪崩问题优化 热点key重建优化 收益与成本

收益

  1. 加速读写

  2. 降低后端负载 成本

  3. 数据不一致性

  4. 代码维护成本

  5. 运维成本 缓存更新策略

  6. lru,ttl,random,allkey-lru,allkey-random,no-enviction(内存达到最大值时的缓存策略) 2.超时删除 (设定过期时间) 3.主动更新(用于数据一致性较高) 缓存粒度

  7. 全部数据缓存以及部分数据缓存的选择

  8. 思考缓存粒度从几个维度考虑: 数据通用性,空间占用比,代码维护性 通常缓存全部数据 通用性好,代码维护简单,但是空间占用大,而缓存部分数据则相反 穿透问题

原因:cache miss 后直接请求后端服务,常发生在业务代码异常,或者大量恶意攻击导致的

解决方法:

  1. 空对象缓存,但是需要注意缓存空间的使用情况,对空对象缓存时间尽量要小
  2. 布隆过滤器缓存 miss cache 直接返回 不请求后端服务,但是必须有定时程序往缓存中写数据,适用于数据缓存命中不高的场景 布隆过滤器

用途:快速查询一个元素是否在一个集合中

入参:失败率,集合个数

原理:用k个hash函数将结果存在一个位数组中,检查的时候对比每一个位上是否是1 如果全是的话 则说明命中

说明:结果在,有可能不在 结果不在,则一定不在 无底洞问题

表现:集群增加节点依然性能不佳。耗时有可能还有增加

原因:客户端使用mget之类批量获取key的命令时候,会导致更多的io请求。在redis cluster中 key是分布在各个slot中,批量操作的话会增加更多的网络io

解决方式:

  1. 相同节点key 合并。总时间 = node + n次命令时间

  2. redis 强制将这些key 写入同一个slot中

性能比较

  1. 编程复杂,需要考虑多线程开发的问题
  2. 性能最高,维护成本很高,但是容易发生数据倾斜的问题 雪崩问题

表现:在缓存层中服务不可使用,导致后端服务负载过高,出现宕机的情况

解决办法:

  1. 缓存高可用架构 (master/slaver,哨兵,cluster)
  2. 后端限流降级 (限流3个手段 计数器,漏斗,令牌桶)
  3. 提前对业务进行故障演练,正确估计缓存性能,负载情况 热点key重建

表现:通常 缓存key+过期时间,能保证绝大部分需求,但是有2种情况下,这样的做法会引起性能问题

  1. 热点key 过期重建
  2. 重建的逻辑计算相当复杂

原因。热点key中 会有大量的线程尝试重建缓存,导致后端负载过大,甚至引起宕机 解决方式:

  1. 引入分布式锁 保证同一时间只有一个请求来进行key 重建
  2. 设定key 永不过期 直到他变成不是热点key