Update 缓存.md

补充大 Key 与热 Key 的问题、发现和处理方法。
This commit is contained in:
CyC2018
2026-10-26 02:34:35 +08:00
parent 91676af01c
commit b3277daaae
+26
View File
@@ -154,6 +154,30 @@ CDN 主要有以下优点:
- 减少网络通信次数;
- 降低接入成本,使用长连接 / 连接池,NIO 等。
### 大 Key 与热 Key
大 Key 指的是值很大的键,例如几 MB 的字符串,或者包含几十万个元素的集合;热 Key 指的是访问量远高于其它键的键,例如秒杀商品的库存。
大 Key 的问题:
- 阻塞:Redis 用一个线程执行命令,对大 Key 执行 HGETALL、DEL 这类 O(N) 的命令时,其它命令都要等待。在本机删除一个有 100 万个字段、占用 64 MB 内存的 HASH,DEL 耗时 341 ms,而 UNLINK 只需 35 μs,它在后台线程中释放内存;
- 网络:一次读写的数据量大,占用带宽;
- 数据倾斜:在集群中,大 Key 所在节点的内存和流量都会高于其它节点。
大 Key 的发现与处理:
- 用 redis-cli --bigkeys 或者 --memkeys 扫描,它们使用 SCAN 命令遍历,不会阻塞服务器;用 MEMORY USAGE 查看单个键占用的内存;
- 拆分:例如把一个大的 HASH 按字段的哈希值拆成 16 个小 HASH,user:1001:fav:0 到 user:1001:fav:15;
- 删除用 UNLINK;读取集合时用 HSCAN、SSCAN 分批读取,不要一次读出所有元素。
热 Key 的问题是请求集中到同一个节点,集群中其它节点再多也无法分担。处理方法:
- 发现:redis-cli --hotkeys,它要求淘汰策略为 LFU;也可以在客户端或者代理中统计访问频率;
- 本地缓存:在应用中缓存热 Key 的值,大部分请求不再访问 Redis,代价是数据会有短暂的不一致,见上文的 [本地缓存](#本地缓存);
- 复制多份:把同一个值写到 stock#0 到 stock#9 这 10 个键中,读取时随机选一个。这些键分布在不同的槽上,请求就分散到了多个节点,代价是写入时要更新所有副本。
热 Key 过期时大量请求同时打到数据库的问题,见上文的缓存击穿。
## 五、数据分布
### 哈希分布
@@ -342,3 +366,5 @@ public class LRU<K, V> implements Iterable<K> {
- [一致性哈希算法](https://my.oschina.net/jayhu/blog/732849)
- [内容分发网络](https://zh.wikipedia.org/wiki/%E5%85%A7%E5%AE%B9%E5%82%B3%E9%81%9E%E7%B6%B2%E8%B7%AF)
- [How Aspiration CDN helps to improve your website loading speed?](https://www.aspirationhosting.com/aspiration-cdn/)
- [Redis: UNLINK](https://redis.io/docs/latest/commands/unlink/)
- [Redis CLI](https://redis.io/docs/latest/develop/tools/cli/)