近似 LRU 是什么
Redis 不维护全量 LRU 链表:它在对象头记录最近一次访问的时间信息,需要淘汰时从待淘汰范围里随机采样若干键,挑其中最久未使用的删掉。这是精度与开销的折中——精确 LRU 要为每次访问搬动链表节点,内存与 CPU 成本都更高。理解这一点,就不会把偶尔淘汰到较新的键当成故障。
基本信息
| 采样参数 | maxmemory-samples,默认采样 5 个键 |
|---|---|
| 生效前提 | 内存到达 maxmemory 且策略不是 noeviction |
| 时间记录 | 对象头中的访问时间标记,时钟精度有限 |
| 直接后果 | 偶发淘汰到较新的键属于正常统计现象 |
| 观测手段 | evicted_keys 变化速度配合命中率一起看 |
淘汰策略对照
| 策略 | 淘汰范围 | 典型场景 |
|---|---|---|
| allkeys-lru | 所有键按近似最近最少使用淘汰 | 纯缓存,数据都可重建 |
| volatile-lru | 仅淘汰设置了过期时间的键 | 混布负载,持久数据不设 TTL |
| allkeys-lfu / volatile-lfu | 按访问频率淘汰,频率信息带衰减 | 热点集中、新键需要保护 |
| allkeys-random / volatile-random | 随机淘汰 | 无访问倾斜的简单场景 |
| volatile-ttl | 优先淘汰剩余生存时间短的键 | TTL 语义本身就是优先级 |
| noeviction | 不淘汰,写入直接报错 | 数据不可丢,需外部兜底容量 |
查看与调整
查看与调整
redis-cli CONFIG GET maxmemory-policy maxmemory-samples
redis-cli CONFIG SET maxmemory-samples 10 # 提高采样精度,CPU 开销略增
redis-cli INFO stats | grep -E 'evicted_keys|keyspace_hits|keyspace_misses'
redis-cli INFO memory | grep -E 'used_memory_human|mem_fragmentation_ratio'
redis-cli MEMORY USAGE some:key # 单键开销,用于容量取舍典型使用场景
- 缓存定容:内存打满时靠淘汰腾出空间,用命中率变化评估策略是否合适
- 解答疑问:「刚写入的键怎么被删了」多半是采样淘汰的正常表现
- 采样调优:命中率偏低时适当提高采样数,观察淘汰精度是否改善
- 策略选型:区分纯缓存与混布负载,决定用 allkeys 还是 volatile 系列
- 切换评估:从 LRU 换到 LFU 前,先确认访问模式是否真的存在稳定热点
采样数越大淘汰越接近真实 LRU,但不存在精确值;访问时间标记的时钟精度有限,同一时间窗口内被访问的键在排序上可能等同,属于正常现象。
策略效果要看两个方向:evicted_keys 的增长速度说明淘汰压力,keyspace_hits 与 keyspace_misses 说明淘汰对业务的实际影响。