Cache
Contents
💠
-
- 1.1. 缓存淘汰算法
-
- 3.1. Hot Key
- 3.2. BigKey
- 3.3. 缓存雪崩 Cache Avalanche
- 3.4. 缓存穿透 Cache Penetration
- 3.5. 缓存击穿/崩溃 Cache Breakdown
- 3.6. 缓存一致性
💠 2024-09-06 11:36:43
缓存
用时效和空间换时间
从Web应用系统的流程上可分为 客户端 服务端 数据库
缓存淘汰算法
-
FIFO
First In First Out
先进先出- 优点:实现简单
- 缺点:未考虑数据访问频率和时间,和实际场景不贴和。
-
LRU
Least Recently Used
最近最久未使用- 实现方式:维护一个所有数据的链表,新数据插入到链表的头部,如果缓存满了,就会从链表尾部开始移除数据。
- 优点:LRU考虑了最近的数据访问模式,对于局部性原理的表现优秀,简单实用
- 缺点:不能体现数据的访问频率,如果数据最近被访问过,即使访问频度低也不会被淘汰。
- 如果一个数据在一分钟的前59秒被频繁访问,而在最后一秒无任何访问,但是有一批冷门数据在最后一秒进入缓存,那么热点数据可能会被淘汰掉。
-
SLRU
Segmented LRU
分段LRU- 实现方式:类似于内存分代,将缓存分为淘汰段,保护段,两个段都是LRU实现。
- 数据访问第一次被放入淘汰段,访问第二次才会升级到保护段
- 保护段的数据要淘汰时,数据复制到淘汰段。淘汰段的数据要淘汰时就会被直接删除。
- 优点:抵御冷门数据引起热门数据被淘汰
- 缺点:两段的容量设计需要更参考业务场景做调优
- 实现方式:类似于内存分代,将缓存分为淘汰段,保护段,两个段都是LRU实现。
-
LFU
Least Frequently Used
最近最少频率使用- 实现方式:对每个在缓存中的数据进行计数,记录其被访问的次数
- 优点:LFU能够较好地处理长期访问稳定、频率较高的情况,因为这样可以确保频繁访问的数据不容易被淘汰。
- 缺点:对于一些暂时高频访问但之后不再访问的数据,LFU无法有效处理。因为这些数据的访问次数已经非常高,不容易被淘汰,可能造成缓存空间的浪费。
- 并且LFU需要维护所有对象的访问计数,这可能会消耗比较多的存储空间和计算资源。
-
W-TinyLFU
Window Tiny Least Frequently Used
论文 TinyLFU: A Highly Efficient Cache Admission Policy- 实现方式: W-TinyLFU缓存淘汰策略
- 优点:
- 平衡了最近性和频率:与 LRU 相比,不仅考虑了使用频率,还计算了缓存的热门程度。与 LFU 相比,不会让以前非常热门但现在很少使用的数据长时间占用缓存。
- 额外内存占用小: TinyLFU 使用一个固定大小的计数滤波器来跟踪访问频率,这使得其内存占用远低于传统的 LFU 策略。
- 适应性强:可以更好地适应工作负载的变化,因为它对频率的计数有一个时间窗口
- 避免缓存污染:由于它维护了一个 admission window,它可以避免一次性的、大规模的请求可能带来的缓存污染。
- 缺点:
- 需要维护额外的频率信息,SLRU等,增加了一些开销。
- 不如 LRU 算法实现简单。对于不同的使用场景,需要调整参数以获得最佳性能。
应用场景
客户端
浏览器
- 静态资源缓存,Cookie,各种 *Storage, IndexDB
PC端原生
- 配置文件,SQLite,LevelDB
服务端
数据库
会话缓存
MySQL Buffer Pool
分布式缓存
使用分布式共识算法构建出一个集群,将读写压力摊分到集群内节点上。
- tinykv 构建分布式 Key-Value 数据库的教程
Ehcache
Redis cluster
一致性Hash实现数据在分区上的均匀分布
场景
Hot Key
海量用户请求同一个key,引发整个链路的 网卡 带宽 CPU 出现瓶颈
- 统计出hot key 将这批key分散在集群内多个节点上
- 多级缓存,将流量的请求链路缩短
BigKey
Value的内存占用很大,读写,加载容易超时的key
- 拆分Key
缓存雪崩 Cache Avalanche
缓存层大量缓存过期,或者整个缓存层崩溃, 导致大量流量直接访问上游资源层
缓存穿透 Cache Penetration
缓存层和上游资源层都没有当前查询的数据
缓存击穿/崩溃 Cache Breakdown
缓存层部分数据过期了,并且突增大量流量直接访问上游资源层,去查询这部分过期的数据
缓存一致性
- 数据库更新 缓存更新
- 数据库更新 缓存删除
Author Kuangcp
LastMod 2019-05-13