JJava 知识库
JAVA INTERVIEW

高频面试题

Redis进阶约 3 分钟

Redis 内存快满了,你会怎么确认是过期策略、淘汰策略还是业务 Key 设计的问题?

参考回答约 3 分钟 · 口语表达
先说结论

我会先控制影响,再按证据定位:过期删除处理 TTL 到期的 Key,Redis 通过访问时惰性检查和后台主动采样删除组合控制成本;内存淘汰则在达到 maxmemory 后,根据 noeviction、LRU、LFU、random 或 TTL 等策略为新写入腾出空间。

01

我会先确认影响范围,同时控制故障继续放大。理解惰性删除、定期删除、maxmemory 策略以及 TTL 设计。过期删除处理 TTL 到期的 Key,Redis 通过访问时惰性检查和后台主动采样删除组合控制成本;内存淘汰则在达到 maxmemory 后,根据 noeviction、LRU、LFU、random 或 TTL 等策略为新写入腾出空间。 过期 Key 不保证到期瞬间立刻物理删除,因此监控内存时要理解后台清理节奏。

02

止损之后,我会按请求链路建立证据,而不是凭经验猜。沿着「写入 Key 与过期时间 → 惰性访问检查 → 周期主动采样删除 → 内存达到 maxmemory → 按策略淘汰并反馈」观察输入、状态与输出,这些阶段都可以从日志、指标或源码里验证。 写入 Key 与过期时间 EXPIRE 与数据写入应尽量在同一原子操作中完成,避免进程崩溃留下永不过期 Key。 惰性访问检查 客户端访问 Key 时先检查 TTL,已过期则删除并返回不存在,这是惰性删除。 src/expire.c:activeExpireCycle 主动过期。 INFO stats/memory:expiredkeys、evictedkeys。 我会先确认请求实际走到了哪条路径,再用运行数据验证,不会只看类名或配置猜测。

03

定位时我最关注这些参数、指标和容量关系。写入 100 万个同秒 TTL 与带 20% 抖动 TTL,对比过期 CPU、延迟和回源峰值;再压满内存验证淘汰语义。

04

找到根因后先做最小修复,再用同样的流量验证。百万 Key 使用同一个整点 TTL,主动过期与回源请求同时出现。写入 TTL 加随机抖动、热点逻辑过期并限制回源并发后,负载被摊平。 缓存与业务状态混用同一淘汰实例:expiredkeys:TTL 加随机抖动。 过期时间无抖动集中触发:evictedkeys:状态数据用 noeviction 独立实例。 固定输入和基线 先在没有故障注入的环境执行上述配置,固定数据规模、并发度、运行时版本和预热时间。以「expired/s」为主基线,记录值应满足「应平滑」;同时保存 expiredkeys、evictedkeys,使后续变化能够回到同一时间轴比较。

05

恢复阶段要逐步放量,最后把监控和边界补齐。方案:更适合的场景:主要收益:代价与边界。 惰性+定期过期:通用 TTL 数据:Redis 自动平衡 CPU 与内存:删除时间不精确。 allkeys-lfu:纯缓存且热点相对稳定:保留高频数据:频率估算并非业务优先级。 noeviction:不能丢的状态数据:写失败显式暴露容量问题:达到上限后新写失败。 选型至少带上 Key 数量、Value 大小、命令复杂度、热点分布和过期速率,并用上面的量化基线验证;

排查与恢复时间线从目标到落地
01写入 Key 与过期时间
02惰性访问检查
03周期主动采样删除
04内存达到 maxmemory
05按策略淘汰并反馈