12-缓存设计

nobility 发布于 2022-11-12 2943 次阅读


缓存设计

  • 收益
    • 加速读写
    • 降低后端MySQL等数据库的负载
  • 成本
    • 缓存层和数据层由于更新策略,导致数据不一致
    • 编码增加一层缓存层的逻辑代码
    • 以及运维成本
  • 使用场景
    • 对高消耗的分组查询和多表查询结果进行缓存
    • 加速请求响应时间
    • 大量写合并成批量写,比如计数器,先将计数暂存缓存中,过一段时间再存入MySQL,减少对MySQL的访问

缓存更新策略

  • 仅使用Redis内置的内存回收策略

  • 超时剔除:手动为key设置过期时间,即expire属性

  • 主动更新:定时更新(每隔一段时间想数据源询问数据是否变化)、监控数据源的变化(发布更新消息,缓存层订阅,收到更新消息后更新缓存)

缓存粒度

  • 存储全部属性更占空间,但是通用性高,代码维护成本低
  • 存储部分属性占用空间少,但是通用性低,代码维护成本高

缓存穿透

缓存穿透

缓存雪崩

请求流量直接压向底层数据源,数据源无法承受访问压力

  • 缓存倾斜(宕机):缓存服务器无法承受访问压力,缓存服务器宕机,导致流量转向底层数据源
    • 解决方案:保证缓存服务器的高可用性,甚至做二级缓存
  • 缓存同时失效:设置了很多相同的过期时间的key,导致缓存在某一时刻同时失效,导致流量转向底层数据源
    • 解决方案:将过期时间设置为一个随机时间
  • 缓存击穿:热点key突然失效,并且缓存重建时间较长,有大量的线程会去查询数据源并重建缓存,导致流量转向底层数据源
    • 解决方案:使用互斥锁(分布式锁),只有第一个线程进行缓存重建,其他线性阻塞等待

缓存污染

由于程序的错误处理(比如异常处理不当),导致向缓存中存储了错误的处理结果,下次再从缓存中取时任然是错误的结果

解决方案:正确的异常处理,当计算结果出错或发生异常时,将错误的计算结果或异常信息从缓存中删除

缓存无底洞

集群中添加机器时,客户端的性能不但没提升,反而下降

更多的机器等于数据增长与水平扩展,并不意味着更高的性能,因为集群多个节点之间通信也需要消耗资源

优化方案:命令本身优化、减少网络通信次数、降低连接成本(使用长连接/连接池、NIO等)

此作者没有提供个人介绍
最后更新于 2022-11-12