首页/数据/Redis 进阶速查/近似 LRU:采样淘汰原理
内存与管理99 条

近似 LRU:采样淘汰原理

Redis 不维护全量 LRU 链表,而是给对象记录最近使用时间戳,淘汰时采样若干键挑较久未用的;采样数越大越接近真实 LRU。

Redis 进阶速查数据更新于 2026-10-13

近似 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 说明淘汰对业务的实际影响。

易错点

  • 指望 LRU 绝对精确,把偶发淘汰较新键当成 bug,投入无效排查
  • 以为调大采样数能解决容量不足,真正的解法是扩容、分片或缩短数据生存期
  • 选了 volatile-lru 但键都没有过期时间,内存满后无键可淘汰,写入直接报错
  • 缓存与持久数据混在同一实例上用 allkeys-lru,被业务依赖的数据可能被淘汰
  • 只看 used_memory 不看 used_memory_rss 与碎片率,内存实际已接近上限却以为还有余量

数据来源与参考

  • Redis 官方文档:近似 LRU 算法说明
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌