LRU 时钟是什么
Redis 在每个对象头部存了一个 24 位的最近访问时间戳,也就是 LRU 时钟:精度为秒级,大约每 194 天回绕一次。淘汰时并不维护严格的访问队列,而是在 maxmemory-samples 个候选键里抽样比较这个时间戳,淘汰最旧的一个。理解这套近似机制,才能解释「热点键偶尔也会被淘汰」这类现象。
基本信息
| 存储位置 | 对象头部的 24 位时间戳字段 |
|---|---|
| 精度 | 秒级(LRU_CLOCK_RESOLUTION 为 1000 毫秒) |
| 回绕周期 | 约 194 天(2 的 24 次方秒) |
| 查看命令 | OBJECT IDLETIME(空闲秒数) |
| 相关配置 | maxmemory-policy、maxmemory-samples(默认 5) |
典型使用场景
- evicted_keys 持续增长时,判断抽样精度是否够用
- 排查热点键被淘汰的疑似误杀
- 用空闲时间找出长期没人访问的键
- 在 LRU 与 LFU 策略之间做选择时评估命中特性
- 巡检脚本大量读键前,先规避热度污染
观测与配置
观测与配置
redis-cli OBJECT IDLETIME hot:key # 空闲秒数,越小表示最近被访问过
redis-cli OBJECT FREQ hot:key # 仅 LFU 策略可用;LRU 下会报错
redis-cli CONFIG GET maxmemory-policy # 当前淘汰策略
redis-cli CONFIG GET maxmemory-samples # 每次淘汰比较几个候选键
redis-cli INFO stats | grep evicted_keys # 淘汰是否在持续发生
redis-cli INFO memory | grep maxmemory_human观测项读法
| 观察项 | 含义 | 注意点 |
|---|---|---|
| OBJECT IDLETIME | 距离上次访问的空闲秒数 | 秒级精度,同一秒内的多次访问无法区分 |
| maxmemory-samples | 每次淘汰比较的候选键数 | 调大更接近真 LRU,但 CPU 开销上升 |
| 时钟回绕 | 约 194 天循环一次 | 跨越回绕的旧键可能被误判为新键 |
| evicted_keys | 累计被淘汰的键数量 | 持续增长说明容量已经不足 |
空闲时间来自与 TTL 共用的一套近似设计,所以它与业务语义上的「多久没人用」只是近似对应,用于趋势判断最合适。
LFU 策略下 OBJECT IDLETIME 仍可返回,但 OBJECT FREQ 只在 LFU 下可用,LRU 策略执行会直接报错。
OBJECT IDLETIME 是秒级精度加抽样淘汰,不要用它做严格的 SLA 判定,只能当参考信号。
策略选择参考
- 访问分布均匀、希望淘汰最久未用的键:LRU 更合适
- 有明显热点且要抵抗偶发批量扫描:LFU 更抗干扰
- 两种策略都受采样精度影响,样本数决定近似的粗细
- 切换策略会改变 OBJECT FREQ 是否可用,脚本要先适配