一站式学习Redis, 从入门到高可用分布式实践-11-缓存设计与优化

缓存设计与优化

讲解将缓存加入应用架构后带来的一些问题,这些问题常常会成为应用的致命点

  1. 缓存的收益与成本
  • 收益:加速读写、降低后端负载,前端缓存降低后端服务器的负载,业务端使用redis降低后端mysql负载
  • 成本
    数据不一致:缓存层和数据层有时间窗口不一致,跟更新策略有关
    代码维护成本:多了一层缓存逻辑
    运维成本:redsi cluster
  1. 缓存的使用场景
  • 降低后端负载:对高消耗的sql,join结果集/分组统计结果缓存
  • 加速请求响应:利用redis/memcache加速请求响应时间
  • 大量写合并为批量写:如计算器先redis累加在批量写DB
  1. 缓存更新策略
  • LRU/LFU/FIFO算法剔除:例如:maxmemory-policy
  • 超时剔除:expire
  • 主动更新:开发控制生命周期
  • 缓存更新策略对比
  • 两条建议
    低一致性:最大内存和淘汰策略
    高一致性:超时剔除和主动更新结合,最大内存和淘汰策略兜底
  1. 缓存粒度问题
  • 缓存粒度控制3个角度
    通用性:全量属性更好
    占用空间:部分属性更好
    代码维护:表面上全量属性更好.
  1. 缓存穿透问题-大量请求不命中
  • 业务代码自身问题
  • 恶意攻击、爬虫等等

如何发现:

  • 业务的响应时间
  • 业务本身问题
  • 相关指标:总调用数、缓存层命中数、存储层命中数

解决方法1:

  • 缓存空对象 + 设置过期时间

两个问题:

  • 需要更多的键
  • 缓存层和存储层数据"短期"不一致

解决方法2:

  • 布隆过滤器拦截
  1. 缓存雪崩
  • 由于cache服务承载大量请求,当cache服务异常/脱机,流量直接压向后端组件例如(DB),造成级联故障
    缓存雪崩优化方案:
  • 保证缓存的高可用:个别节点、个别机器、甚至是机房
  • 依赖隔离组件为后端限流(缓存降级)
  • 提前演练,例如:压力测试

缓存降级名词解析:缓存降级指的是当缓存失效后者缓存服务器挂掉的情况下,不去访问数据库,直接返回默认数据或者服务的内存数据,
缓存降级一般是有损的操作,所以尽量减少降级对业务的影响程度

cache服务的高可用三种方案:复制+哨兵、redis cluster集群、vip主从漂移

  1. 无底洞问题
  • 问题描述
    2010年,Facebook有3000个MemCache节点
    发现问题,加机器性能没提升,反而下降

  • 问题关键点

    更多的机器 != 更高的性能
    批量接口需求:mget、mset等
    数据增长与水平扩展需求

  • 优化IO的几种方法
    命令本身的优化:慢查询keys, hgetall, bigkey
    减少网络通讯次数:例如n次get操作改写为1次mget
    降低接入成本:例如客户端长链接/连接池,NIO等

  • 4种批量优化的方法
    串行mget
    串行IO
    并行IO
    hash_tag

  1. 热点key的重建优化
  • 问题描述:热点key + 较长的重建时间

    热点key问题:会有大量的线程进行查询数据库、重建缓存的过程,响应时间会变得很慢
  • 三个目标
    减少重缓存的次数、数据尽可能一致、减少潜在危险
  • 两个解决方案
    互斥锁

    伪代码

永不过期
缓存层面,没有设置过期时间(没有用expire)
功能层面,为每个value添加逻辑过期时间,当发现超过逻辑过期时间,会使用单独的线程去构建缓存

互斥锁和永不过期方案对比:

  1. 本章总结
    缓存收益:加速读写、降低后端负载
    缓存成本:缓存和存储数据不一致性、代码维护成本、运维成本
    缓存更新策略:推荐使用剔除、超时、主动更新三种方案共同完成缓存的更新
    缓存穿透问题:使用缓存空对象+超时时间、布隆过滤器来解决缓存穿透问题。
    无底洞问题:分布式缓存中,有更多的机器不能保证有更高的性能,
    有四种批量操作:串行命令、串行IO、并行IO、hash_tag
    缓存雪崩问题:通过缓存高可用、缓存降级、提起演练压力测试是解决缓存雪崩的重要方法
    热点key的重建为题:互斥锁或者永不过期能够一定程度上解决热点key重建问题
posted @ 2022-04-26 22:30  专职  阅读(45)  评论(0编辑  收藏  举报