allkeys-lru是生产最常用也最易误用的全局lru淘汰策略,需同时配置非零maxmemory和maxmemory-policy allkeys-lru才生效,其lru为随机采样5个key的近似实现,不区分是否设过期时间,适用于纯缓存场景但可能误伤未设ttl的核心数据。

allkeys-lru 是生产环境最常用、也最容易误用的淘汰策略之一——它不看 key 是否设置了过期时间,只要内存满了,就从所有 key 里挑“最近最少使用”的淘汰。但它的“最近”是近似计算出来的,不是精确的。
allkeys-lru 的触发条件和配置方式
它只在 maxmemory 被设为非零值且内存达到阈值时才生效。没配 maxmemory,或者配了但没设 maxmemory-policy allkeys-lru,这个策略根本不会启动。
- 必须显式配置:
maxmemory-policy allkeys-lru(写在redis.conf里,或用CONFIG SET maxmemory-policy allkeys-lru) -
maxmemory建议设为物理内存的 70%~80%,避免 OOM killer 干掉 Redis 进程 - 不依赖 key 的
EXPIRE属性:哪怕你一个 key 都没设过期时间,allkeys-lru照样能淘汰它
为什么 allkeys-lru 的“LRU”不是真的 LRU?
Redis 为了节省内存和 CPU,没维护全局访问链表,而是用随机采样 + 近似排序实现 LRU。每次淘汰前,它只随机抽查 maxmemory-samples 个 key(默认是 5),从中选 lru 字段最小的那个淘汰。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 采样数太小(比如保持默认 5):容易误杀“其实刚被访问过但没抽中”的热 key
- 采样数太大(比如设成 20):提升准确性,但增加 CPU 开销,尤其在高并发写场景下可能拖慢响应
- 真实访问顺序和淘汰顺序之间存在偏差,这是设计取舍,不是 bug
allkeys-lru 在生产环境踩过的典型坑
它看似“通用”,但实际业务中常因数据混合导致核心数据被误伤。
- 缓存 + 持久化数据混存:比如把用户 session(应设 TTL)和商品元数据(长期有效)都存在同一个 Redis 实例,
allkeys-lru可能把高频读的商品信息淘汰掉,反而留下冷 session - 写多读少的数据占满内存:日志类、埋点类 key 大量写入但几乎不读,它们的 lru 时间戳一直很“新”,但实际毫无价值,却挤占了真正热 key 的空间
- 短生命周期 key 没设过期时间:例如临时任务 ID,本该 10 分钟后自动过期,结果因为没调
EXPIRE,被allkeys-lru当作“长期存活”key 保护起来,直到某次访问才突然被淘汰,行为不可控
实测建议:怎么配才更稳?
别只改 maxmemory-policy,要配合其他参数一起调。
- 把
maxmemory-samples从默认 5 提到 10 或 15,对命中率提升明显,多数业务可接受这点 CPU 成本 - 监控
evicted_keys指标:持续上涨说明淘汰频繁,得查是不是缓存容量设小了,或者有数据没按预期访问 - 搭配
INFO memory中的lru_clock和 key 的 lru 值(用OBJECT FREQ/OBJECT IDLETIME查)做抽样分析,验证淘汰是否符合业务热度分布 - 如果发现核心数据总被误淘汰,优先考虑拆实例:热数据走
allkeys-lru实例,冷/临时数据走volatile-lru实例
真正难的不是配对参数,而是厘清哪些 key 属于“应该被 LRU 淘汰”的范畴——这需要结合业务访问模式画出热力图,而不是靠策略名字拍脑袋。










