侧边栏壁纸
博主头像
一定会去到彩虹海的麦当

说什么呢?约定好的事就一定要做到啊!

  • 累计撰写 63 篇文章
  • 累计创建 16 个标签
  • 累计收到 3 条评论

目 录CONTENT

文章目录

[redis]——缓存设计

一定会去到彩虹海的麦当
2022-04-20 / 0 评论 / 0 点赞 / 39 阅读 / 1,183 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2022-05-17,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

思维导图

缓存设计

缓存更新策略

LRU/LFU/FIFO算法剔除

剔除算法通常用于缓存使用量超过了预设的最大值时候,如何对现有的数据进行剔除,开发人员不需要实现算法,只需要配置maxmemory和对应的策略即可。

超时剔除

超时剔除通过给缓存数据设置过期时间,让其在过期时间后自动删除,在过期时间内存在一致性问题即缓存数据和真实数据源的数据不一致。开发人员只需要设置expire过期时间即可。

主动更新

在真实数据更新后,立即更新缓存数据。一致性最高,但如果主动更新出现问题,这条数据很可能长时间不会更新,维护成本较高。

最佳实践

  • 低一致性业务建议配置最大内存和淘汰策略的方式使用。
  • 高一致性业务可以结合使用超时剔除和主动更新,这样即使主动更新出了问题,也能保证数据过期时间后删除脏数据。

缓存穿透

缓存穿透是指查询一个根本不存在的数据,缓存层和存储层都不会命中。缓存穿透将导致不存在的数据每次请求都要到存储层去查询,失去了缓存保护后端存储的意义。

缓存空对象

存储层不命中后,仍然将空对象保留到缓存层中,之后再访问这个数据将会冲缓存中获取

image-20220424140649283

问题:

  1. 空值做缓存,需要存更多的建
  2. 缓存层和存储层的数据会有一段时间窗口的不一致。

布隆过滤器拦截

在访问缓存层和存储层之前,将存在的key用布隆过滤器提前保存起来,做第一层的拦截

image-20220424140853094

这种方法适用于数据命中不高、数据相对固定、实时性低(通常是数据集较大)的应用场景,代码维护较为复杂,但是缓存空间占用少。

image-20220424141006420

无底洞优化

概念

更多节点不代表更高的性能,随着节点在增多,批量操作需要从不同节点上获取,分布式批量操作涉及多次网络时间。

image-20220424141249662

优化方法:

  • 命令本身的优化,例如优化SQL语句等。
  • 减少网络通信次数。
  • 降低接入成本,例如客户端使用长连/连接池、NIO等。

四种批量操作

  1. 串行命令

    获取n个key值,逐次执行n个get命令

    image-20220424141543275

  2. 串行IO

    Smart客户端会保存slot和节点的对应关系,有了这两个数据就可以将属于同一个节点的key进行归档,得到每个节点的key子列表,之后对每个节点执行mget或者Pipeline操作,它的操作时间=node次网络时间+n次命令时间

    image-20220424141623100

  3. 并行IO

    将方案二的最后一步改为多线程执行

    image-20220424141814589

  4. hash_tag实现

    hash_tag可以将多个key强制分配到一个节点上

    image-20220424141900490

总结

image-20220424141917791

缓存雪崩

定义

由于缓存层承载着大量请求,有效地保护了存储层,但是如果缓存层由于某些原因不能提供服务,于是所有的请求都会达到存储层,存储层的调用量会暴增

image-20220424142103167

措施

  1. 保证缓存层服务高可用性
  2. 依赖隔离组件为后端限流并降级
  3. 提前演练

热点key重建优化

当热点缓存失效的瞬间,有大量显出来重建缓存,造成后端负载加大,甚至可能会让应用崩溃

image-20220424142353268

解决措施

  1. 互斥锁

    只允许一个线程重建缓存,其他线程等待重建缓存的线程执行完

    image-20220424142445720

  2. 永远不过期

    没有设置过期时间,但会为每个key设置一个逻辑过期时间,当发现超过逻辑过期时间后,会使用单独线程去构建缓存。会存在数据不一致问题

    image-20220424142600360

总结

image-20220424142625008

0

评论区