一、过期删除策略类
Q1:Redis 的 key 过期后是立即删除吗?
不是。Redis 用惰性删除 + 定期删除组合,不会立即删。
过期 key 在未被访问时可能仍占内存。
所以会出现“key 已过期但内存没释放”的现象。
Q2:Redis 的过期删除策略有哪些?
惰性删除:访问 key 时才检查是否过期,过期就删并返回 nil。
定期删除:每隔一段时间随机抽查一批 key,删掉过期的。
两者结合,兼顾 CPU 和内存。
Q3:惰性删除的优缺点?
优点:CPU 友好,只在访问时检查。
缺点:过期 key 不被访问就一直占内存,可能内存泄漏。
Q4:定期删除怎么工作?
默认每秒 10 次(
hz控制)。每次随机抽取 20 个设置了过期时间的 key。
删除其中已过期的。
如果过期比例 > 25%,继续抽,直到低于阈值或超时。
限制执行时间,避免阻塞主线程。
Q5:为什么定期删除是随机抽查,不是全量扫描?
全量扫描会阻塞主线程,尤其大实例。
随机抽查是 CPU 和内存的折中。
保证过期 key 最终被清理,但不保证及时。
Q6:定期删除会阻塞 Redis 吗?
会有一点。Redis 限制单次执行时间(默认 25ms)。
超时就中断,下次继续。
所以不会长时间阻塞。
Q7:从库会主动删除过期 key 吗?
不会。从库等待主库的
DEL命令。从库读到过期 key 时返回 nil(逻辑过期),但不物理删除。
保证主从数据一致。
Q8:主库删除过期 key 后,从库怎么同步?
主库删除时生成
DEL命令写入 AOF 和 binlog。从库重放
DEL,删除对应 key。所以从库的删除由主库驱动。
二、内存淘汰策略类
Q9:Redis 有哪些内存淘汰策略?
共 8 种:
Q10:怎么选择淘汰策略?
纯缓存:
allkeys-lru或allkeys-lfu。有持久数据 + 缓存:
volatile-lru,只淘汰设了过期的。不能丢数据:
noeviction,写入报错,需人工处理。访问频率差异大:
lfu更合适。
Q11:LRU 和 LFU 的区别?
LRU:淘汰最久未使用的,看“最近一次访问时间”。
LFU:淘汰访问频率最低的,看“访问次数”。
LRU 适合时效性强的场景,LFU 适合热点长期稳定的场景。
Q12:Redis 的 LRU 是精确的吗?
不是。Redis 用近似 LRU。
随机采样 N 个 key(
maxmemory-samples,默认 5),淘汰其中最久未用的。采样越大越精确,但 CPU 开销大。
每个 key 有 24 位 lru 时钟,记录访问时间。
Q13:Redis 的 LFU 怎么实现?
每个 key 有 8 位计数器(logc)和 8 位时间戳。
访问时概率性增加计数,避免短期热点。
计数随时间衰减,防止老热点占坑。
参数:
lfu-log-factor、lfu-decay-time。
Q14:maxmemory 怎么设置?
maxmemory设 Redis 可用最大内存。达到后触发淘汰策略。
建议留出系统内存和 fork COW 余量。
不设则可能 OOM。
Q15:淘汰什么时候触发?
每次执行命令前检查内存。
超过
maxmemory就按策略淘汰。淘汰到低于限制才执行命令。
如果
noeviction,直接返回错误。
三、过期与淘汰的关系类
Q16:过期删除和内存淘汰是一回事吗?
不是。
过期删除:key 到了 TTL 被删。
内存淘汰:内存满了,按策略删 key。
两者独立,但都影响内存。
Q17:key 没过期但内存满了会怎样?
触发内存淘汰策略。
如果策略是
volatile-*且没有设过期的 key,可能无法淘汰,写入报错。allkeys-*则淘汰任意 key。
Q18:volatile-lru 和 allkeys-lru 怎么选?
如果所有 key 都是缓存:
allkeys-lru,淘汰范围大。如果部分 key 是持久数据:
volatile-lru,只淘汰缓存。但
volatile-*可能因可淘汰 key 不足而报错。
Q19:noeviction 适用什么场景?
数据不能丢,且内存足够。
内存满时写入报错,由应用处理。
适合持久化数据为主的实例。
四、实战与排查类
Q20:怎么查看 key 的过期时间?
TTL key:剩余秒数,-1 永不过期,-2 不存在。PTTL key:毫秒。PERSIST key:移除过期时间。
Q21:怎么设置过期时间?
EXPIRE key secondsPEXPIRE key millisecondsEXPIREAT key timestampSET key value EX secondsSETEX key seconds value
Q22:怎么查看内存使用?
INFO memory:used_memory、maxmemory、evicted_keys 等。MEMORY USAGE key:单个 key 内存。MEMORY STATS:内存分布。redis-cli --bigkeys:找大 key。
Q23:怎么查看淘汰了多少 key?
INFO stats的evicted_keys。持续增长说明内存压力大。
结合
maxmemory_policy看策略。
Q24:大量 key 同时过期会怎样?
定期删除压力大,可能卡顿。
内存短时间不释放。
解决:TTL 加随机值,打散过期时间。
Q25:怎么避免缓存雪崩式的集中过期?
设置 TTL 时加随机偏移,如
3600 + random(0, 300)。热点 key 用逻辑过期,不设物理 TTL。
多级缓存。
Q26:怎么找大 key?
redis-cli --bigkeys:扫描各类型最大 key。MEMORY USAGE key:单 key 内存。SCAN+STRLEN/LLEN/HLEN/SCARD/ZCARD自定义脚本。大 key 要拆分或异步删除。
Q27:怎么异步删除大 key?
UNLINK key:后台线程删除。FLUSHALL ASYNC、FLUSHDB ASYNC。避免
DEL大 key 阻塞主线程。
五、高频陷阱题
Q28:key 过期了但内存没释放,为什么?
惰性删除没访问到,定期删除还没抽到。
所以内存延迟释放。
可通过
SCAN触发或等待定期删除。
Q29:TTL 返回 -1 和 -2 的区别?
-1:key 存在但没设过期时间。-2:key 不存在或已过期。
Q30:从库读到过期 key 会返回什么?
返回 nil(逻辑过期)。
但不物理删除,等主库
DEL同步。保证主从一致。
Q31:LRU 一定淘汰最久未用的吗?
不一定。近似 LRU 采样淘汰。
采样数越大越接近精确。
默认 5,可能淘汰非最久未用的。
Q32:LFU 的计数器会一直增长吗?
不会。8 位最大 255,且随时间衰减。
概率性增加,避免短期热点刷高。
lfu-decay-time控制衰减速度。
Q33:maxmemory 不设会怎样?
Redis 无限增长,直到 OOM 被系统杀。
或触发 swap,性能骤降。
生产必须设。
Q34:淘汰策略能动态改吗?
能。
CONFIG SET maxmemory-policy allkeys-lru。立即生效。
也可改配置文件。
Q35:volatile-ttl 淘汰什么?
在设了过期时间的 key 中,优先淘汰 TTL 最短的。
适合希望快过期的先走的场景。
评论