一站式学习Redis, 从入门到高可用分布式实践-11-缓存设计与优化
缓存设计与优化
讲解将缓存加入应用架构后带来的一些问题,这些问题常常会成为应用的致命点
- 缓存的收益与成本
- 收益:加速读写、降低后端负载,前端缓存降低后端服务器的负载,业务端使用redis降低后端mysql负载
- 成本
数据不一致:缓存层和数据层有时间窗口不一致,跟更新策略有关
代码维护成本:多了一层缓存逻辑
运维成本:redsi cluster
- 缓存的使用场景
- 降低后端负载:对高消耗的sql,join结果集/分组统计结果缓存
- 加速请求响应:利用redis/memcache加速请求响应时间
- 大量写合并为批量写:如计算器先redis累加在批量写DB
- 缓存更新策略
- LRU/LFU/FIFO算法剔除:例如:maxmemory-policy
- 超时剔除:expire
- 主动更新:开发控制生命周期
- 缓存更新策略对比
- 两条建议
低一致性:最大内存和淘汰策略
高一致性:超时剔除和主动更新结合,最大内存和淘汰策略兜底
- 缓存粒度问题
- 缓存粒度控制3个角度
通用性:全量属性更好
占用空间:部分属性更好
代码维护:表面上全量属性更好.
- 缓存穿透问题-大量请求不命中
- 业务代码自身问题
- 恶意攻击、爬虫等等
如何发现:
- 业务的响应时间
- 业务本身问题
- 相关指标:总调用数、缓存层命中数、存储层命中数
解决方法1:
- 缓存空对象 + 设置过期时间
两个问题:
- 需要更多的键
- 缓存层和存储层数据"短期"不一致
解决方法2:
- 布隆过滤器拦截
- 缓存雪崩
- 由于cache服务承载大量请求,当cache服务异常/脱机,流量直接压向后端组件例如(DB),造成级联故障
缓存雪崩优化方案: - 保证缓存的高可用:个别节点、个别机器、甚至是机房
- 依赖隔离组件为后端限流(缓存降级)
- 提前演练,例如:压力测试
缓存降级名词解析:缓存降级指的是当缓存失效后者缓存服务器挂掉的情况下,不去访问数据库,直接返回默认数据或者服务的内存数据,
缓存降级一般是有损的操作,所以尽量减少降级对业务的影响程度
cache服务的高可用三种方案:复制+哨兵、redis cluster集群、vip主从漂移
- 无底洞问题
-
问题描述
2010年,Facebook有3000个MemCache节点
发现问题,加机器性能没提升,反而下降 -
问题关键点
更多的机器 != 更高的性能
批量接口需求:mget、mset等
数据增长与水平扩展需求 -
优化IO的几种方法
命令本身的优化:慢查询keys, hgetall, bigkey
减少网络通讯次数:例如n次get操作改写为1次mget
降低接入成本:例如客户端长链接/连接池,NIO等 -
4种批量优化的方法
串行mget
串行IO
并行IO
hash_tag
- 热点key的重建优化
- 问题描述:热点key + 较长的重建时间
热点key问题:会有大量的线程进行查询数据库、重建缓存的过程,响应时间会变得很慢 - 三个目标
减少重缓存的次数、数据尽可能一致、减少潜在危险 - 两个解决方案
互斥锁
伪代码
永不过期
缓存层面,没有设置过期时间(没有用expire)
功能层面,为每个value添加逻辑过期时间,当发现超过逻辑过期时间,会使用单独的线程去构建缓存
互斥锁和永不过期方案对比:
- 本章总结
缓存收益:加速读写、降低后端负载
缓存成本:缓存和存储数据不一致性、代码维护成本、运维成本
缓存更新策略:推荐使用剔除、超时、主动更新三种方案共同完成缓存的更新
缓存穿透问题:使用缓存空对象+超时时间、布隆过滤器来解决缓存穿透问题。
无底洞问题:分布式缓存中,有更多的机器不能保证有更高的性能,
有四种批量操作:串行命令、串行IO、并行IO、hash_tag
缓存雪崩问题:通过缓存高可用、缓存降级、提起演练压力测试是解决缓存雪崩的重要方法
热点key的重建为题:互斥锁或者永不过期能够一定程度上解决热点key重建问题
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)