第5章 内存的生死簿 章节摘要:本章跟着一个键的一生走:从 SET 那一刻的诞生,到 EXPIRE 设定的死期,再到内存告急时被淘汰算法选中出局。过期删除的惰性加定期组合、八种淘汰策略、以及缓存三大经典故障的对策,都围绕"内存有限,谁该死"这个冷酷问题展开。 一条主线 凌晨三点告警:Redis 内存使用率 95%,写入开始失败。复盘发现一批没设 TTL 的临时键堆积如山。这次事故串起本章全部内容:过期时间设了是怎么删的、内存满了按什么规则逐出、以及缓存层自身的穿透击穿雪崩怎么防。主线问题是:在有限的内存里,如何让该死的键及时死、该活的键活得稳。 沿途站点 5.1 过期策略与内存淘汰:过期字典的两段式删除,八种 maxmemory-policy 的取舍。 5.
章节摘要:本章跟着一个键的一生走:从 SET 那一刻的诞生,到 EXPIRE 设定的死期,再到内存告急时被淘汰算法选中出局。过期删除的惰性加定期组合、八种淘汰策略、以及缓存三大经典故障的对策,都围绕"内存有限,谁该死"这个冷酷问题展开。
凌晨三点告警:Redis 内存使用率 95%,写入开始失败。复盘发现一批没设 TTL 的临时键堆积如山。这次事故串起本章全部内容:过期时间设了是怎么删的、内存满了按什么规则逐出、以及缓存层自身的穿透击穿雪崩怎么防。主线问题是:在有限的内存里,如何让该死的键及时死、该活的键活得稳。
一个键从生到死的完整路径:
转折点在 5.1 的"两段式删除":为什么不一到点就删?因为维护一个全局定时器给亿级键排队,本身比删键更贵。精确性再次被拿去换了吞吐——与渐进式 rehash、HyperLogLog 一脉相承。想通这一点,5.2 的三大故障(本质上都是"该缓存的数据不在了")的对策也就顺理成章。
内存告警的排查顺序,把本章知识串成一条线:
| 观察到的现象 | 先查什么 | 对应小节 |
|---|---|---|
| used_memory 逼近 maxmemory | evicted_keys 是否已在涨、涨速多少 | 5.1 |
| 内存没到顶但键很多没删 | expired_keys 与定期删除轮次 | 5.1 |
| 碎片率异常偏高或低于 1 | 删键潮、写时复制、是否被换出 | 5.1、8.1 |
| 数据库瞬时压力陡增 | 是穿透(查不存在的)还是击穿(热点过期) | 5.2 |
| 大批缓存同时失效回源 | TTL 是否统一、实例是否整体重启 | 5.2 |
排查时先对现象、再查指标、最后回结构——这套顺序与第 8 章的延迟排查互为镜像。
本章动手主线沿用开头那场凌晨告警:先用 INFO 键空间确认"没 TTL 的临时键"这个病灶,再给键补 TTL 并观察 expired_keys 的节奏,最后故意把一批键设成同秒过期、复现一次小型过期风暴、用抖动 TTL 消掉它。一场事故的完整复盘走下来,两节的知识点全部落在手上。
内存里的生死管好了,下一个问题是"重启之后呢"。第 6 章讲持久化:RDB 快照与 AOF 日志,两条把内存搬到磁盘的路。