Update 缓存.md

为面试中常问的小节加上高频标记;补充过期时间兜底时旧值可能保留的时长。
This commit is contained in:
CyC2018
2026-10-30 02:57:56 +08:00
parent 23016c7de6
commit e6e24407a1
+7 -7
View File
@@ -2,12 +2,12 @@
<!-- GFM-TOC -->
* [缓存](#缓存)
* [一、缓存特征](#一缓存特征)
* [二、缓存位置](#二缓存位置)
* [二、缓存位置](#二缓存位置) 🔥
* [三、CDN](#三cdn)
* [四、缓存问题](#四缓存问题)
* [四、缓存问题](#四缓存问题) 🔥🔥
* [五、数据分布](#五数据分布)
* [六、一致性哈希](#六一致性哈希)
* [七、LRU](#七lru)
* [七、LRU](#七lru) 🔥
* [附录:实测](#附录实测)
* [参考资料](#参考资料)
<!-- GFM-TOC -->
@@ -37,7 +37,7 @@
除了容量淘汰,缓存通常还会为数据设置过期时间,到期后自动失效。
## 二、缓存位置
## 二、缓存位置 🔥
### 浏览器
@@ -114,7 +114,7 @@ CDN 主要有以下优点:
<div align="center"> <img src="pics/cdn.png" width="760px"/> </div><br>
## 四、缓存问题
## 四、缓存问题 🔥🔥
穿透、击穿和雪崩都是请求越过缓存直接到达数据库,区别在于原因:穿透查询的是缓存和数据库中都不存在的数据,击穿是一个热点键过期,雪崩是大量的键同时过期或者缓存整体不可用。
@@ -194,7 +194,7 @@ Redis 8 起内置了布隆过滤器(BF.RESERVE、BF.ADD、BF.EXISTS),Redis
常用的补救措施:
- 为缓存设置过期时间作为兜底;
- 为缓存设置过期时间作为兜底,需要注意过期时间从这次写回缓存时算起,慢读请求很晚才写回旧值时,旧值最长还会保留一个完整的过期时间;
- 延迟双删:更新数据库并删除缓存之后,隔一段时间再删除一次,清掉慢读请求写回的旧值,间隔要大于读请求从查询数据库到写回缓存的耗时;
- 删除失败时重试:把要删除的键发到消息队列,由消费者删除,失败就重新投递;
- 订阅数据库的 binlog(例如使用 Canal)异步删除缓存,失败时重试,业务代码中不再需要删除缓存;
@@ -285,7 +285,7 @@ binlog 方案把删除缓存从业务代码中移出:Canal 伪装成 MySQL 的
Redis Cluster 使用的不是一致性哈希,而是把 Key 映射到固定的 16384 个哈希槽上,再把哈希槽分配给各个节点,节点变化时只需要迁移对应的哈希槽。
## 七、LRU
## 七、LRU 🔥
以下是基于双向链表和 HashMap 的 LRU 算法实现,对算法的解释如下: