引言
缓存能够加速应用的读写速度,同时也可以降低后端负载,对日常应用开发至关重要。
1.缓存的收益和成本
1.1 收益
1.加速读写
2.降低后端负载
1.2成本
1.数据不一致性
2.代码维护成本
3.开销大的复杂计算
4.加速请求响应
2 缓存更新策略
2.1 .LRU/LFU/FIFO算法剔除
场景:常用于缓存使用超过预设的最大值,对现有数据进行剔除。
一致性:算法一致性最差
成本:成本较低,开发者选择合适算法即可
2.2 超时剔除
场景:给缓存数据设置过期时间,在过期后进行自动删除
一致性:因为存在窗口期,后端数据不能及时同步,一致性比较差
成本:成本不是很高
2.3主动更新
场景:真实数据更新后,缓存立更新
一致性:一致性最好。但会发生主动更新如果发生问题,该数据可能长时间不能及时更新,建议和超时剔除结合使用。
成本:成本比较高
2.4 推荐策略
1.低一致性业务,配置最大内存和淘汰策略的配置方式
2.高一致性业务,结合超时剔除和主动更新一块进行使用。保证不能及时更新,也能在数据过期后进行剔除。
3. 缓存粒度控制
1.通用性:缓存全部数据更加通用
2.缓存全部数据会占更大的存储空间,网流量更大,序列化和反序列化开销会更大
3.全部缓存的代码维护更加简单
4. Redis缓存优化
4.1 穿透优化
概念:缓存穿透指缓存层找不到数据,就会去存储层进行请求查询,失去缓存保护后端存储的目的。
解决方法
1. 缓存空对象
存储层查不到数据,则在缓存层为其键添加空值,保证下次缓存查询不会再穿透到存储层
为空值设定较短的过期时间,保证能够被过期删除
会存在一定时间的缓存和存储不一致,可使用消息系统或其他方式清除缓存层中的对象
适用场景:命中率不高,数据频繁变化实时性高
成本: 需要更多缓存,数据不一致
3. 布隆过滤器拦截
在访问缓存和存储之前,将所存在的key用布隆过滤器提前保存,作为第一层拦截
适用场景:命中率不高,相对固定实时性低
成本:占用空间少,代码维护复杂
4.2 无底洞优化
概念:大量节点,存放大量数据,进行大量交互,导致总的时间加长
优化思路:优化SQL,减少网络通信次数,降低成本,如nio,连接池等。
解决办法
1.串行命令:操作时间=n次网络时间+n次命令时间
2.串行IO:将同一个节点的key进行归档,一个节点进行批量执行,操作时间 = 节点次网络时间+n次命令
3.并行IO,在串行IO的基础上进行的,即节点并行处理
4.hash_tag实现:强制将多个key放到一个节点上。只需要一次网络时间。
4.3 雪崩优化
概念:reids层如果奔溃不能提供服务,则所有的请求将会压在存储性,造成存储层崩溃。
预防和解决
1.保证缓存层服务高可用性
2.依赖隔离组件为后端限流并降级
3.提前演练
4.4 热点key重建优化
优化思路
减少重建的次数
数据尽可能一致
较少的潜在的危险
优点:思路简单,保证一致性
缺点:代码复杂度增加 存在死锁风险 线程池阻塞
优化方案
1.互斥锁:保证只有一个线程在重建,使用setnx进行锁
2.永远不过期
物理上没有设置过期时间
为每个value设置过期时间,过期后使用单独线程进行构建缓存
优点:杜绝热点key问题,缺点:不保证一致性,增加代码维护成本和内存成本
5.思维导图
以上思维导图是博主自己个人总结,转载请注明出处。
百度云盘 : Redis缓存设计
提取码 :ec5a
思维导图软件:XMind8 update7
本文章系博主原创,尊重博主辛劳成果,转载请注明出处,谢谢。