1. Redis 的过期键删除策略?为什么是"惰性+定期"组合?

为什么组合:惰性兜底(保证过期 key 最终会被清理)+ 定期主动(控制内存峰值)。两者都执行,同一 key 谁先触发谁删。

🎯 面试要点

  • 主从架构:过期删除由主库触发(主删了发 DEL 给从库);从库不主动删,读从库返回已过期但未删的数据也不返回(主库 DEL 同步前)——一致性细节
  • 惰性删除不释放内存的场景:大量过期 key 无人访问 → 内存居高不下 → 配合 maxmemory 淘汰兜底

2. 内存淘汰策略有哪些?怎么选?

触发条件:内存达到 maxmemory 上限后,新写入按策略淘汰旧数据(或拒绝写入)。八种:

为什么是"近似 LRU":真实 LRU 要维护双向链表(内存代价大)。Redis 在对象头记录 lru 时间戳(24 bit,秒级精度,约 194 天循环;LFU 模式下这 24 bit 被拆成 16 bit 衰减时间 + 8 bit 计数器),淘汰时抽样 5 个(maxmemory-samples),淘汰最旧的。抽样代替全表扫描。

缓存场景的标准配置
maxmemory 4gb
maxmemory-policy allkeys-lru    # 纯缓存:所有 key 参与 LRU 淘汰
maxmemory-samples 5             # 抽样数,越大越接近真 LRU,CPU 略增

# 业务数据(不可随意丢)→ 别开淘汰,监控告警 + 扩容
# 热点极不均匀 → lfu 优于 lru(防止"偶用一次的热 key"被误淘汰)

🎯 面试要点

  • volatile-* 系列的前提:key 都设了过期时间;全都没设 → 退化为 noeviction 报错
  • LFU vs LRU:LRU 看"多久没用",LFU 看"用得多不多";LFU 适合防热 key 被扫淘汰
  • 监控:INFO memory 看 used_memory/maxmemory 比例,接近 100% 预警
  • 淘汰与过期是两回事:过期是"key 到点失效",淘汰是"内存不够腾空间"——别混

🎤 常见面试追问

  1. 过期删除和内存淘汰有什么区别?——过期:key 到点失效(惰性+定期删除,清的是"到期的");淘汰:内存满了腾空间(maxmemory 策略,清的是"不重要的")。两个机制独立。
  2. 为什么是"惰性 + 定期"组合?——惰性(访问时删)零开销但过期 key 一直占内存;定期(随机抽样删)主动清理但清不干净。组合:惰性兜底 + 定期控峰值。
  3. 主从架构下过期删除谁负责?——主库删(过期/淘汰)后发 DEL 给从库;从库不主动删。所以从库可能短暂读到"已过期但主库还没通知"的数据。
  4. 近似 LRU 和真 LRU 的区别?——真 LRU 维护双向链表(内存贵);Redis 只在对象头记 lru 时间戳,淘汰时抽样 5 个(maxmemory-samples)挑最旧的——近似实现,代价小。
  5. volatile-lru 和 allkeys-lru 怎么选?——纯缓存(全可丢)→ allkeys-lru;业务数据(部分 key 不可丢)→ volatile-*(只淘汰设了过期的),但注意全没设过期时 volatile 系列会报错。

📖 名词解释(本页术语)

术语 大白话解释
惰性删除访问 key 时才检查是否过期,过期就删。零 CPU 开销,但没人访问的过期 key 一直占内存。
定期删除后台定时任务随机抽样一批带过期时间的 key 删除过期的——主动控制内存峰值。
maxmemoryRedis 内存上限,达到后按淘汰策略处理(或拒绝写入)。
LRU / LFU淘汰算法:LRU 淘汰"最久没用"的;LFU 淘汰"用得最少"的(防热点被误杀)。Redis 用近似实现。
noeviction默认淘汰策略:内存满时写命令直接报错(OOM command not allowed)——当数据库用时必须换策略。
allkeys-* vs volatile-*allkeys 淘汰所有 key;volatile 只淘汰"设了过期时间"的 key(保护没设过期的)。
抽样淘汰Redis 不扫全表,随机抽 maxmemory-samples 个(默认 5)挑最该淘汰的——近似 LRU 的实现。
⚠️ 本页面由 AI 生成,内容仅供参考,请以官方文档和实际源码为准。