Redis作为内存数据库,所有数据默认都存放在内存中,一旦占用的内存达到maxmemory设定的上限,继续写入就会面临一个关键问题:哪些数据应该被清出去?这个决策由maxmemory-policy参数决定。将淘汰策略设置为allkeys-lru是缓存场景中最常见的选择,它表示当内存不足时,Redis会从所有键(无论是否设置了过期时间)中,挑选最近最少使用的键进行淘汰。本文将从原理、配置和实际使用注意事项三个层面,把这个策略讲清楚。

allkeys-lru的工作原理到底是什么
LRU全称Least Recently Used,即最近最少使用。它的核心假设是:最近被访问过的数据,将来再次被访问的概率更高;而长时间没被碰过的数据,大概率是冷数据,可以优先淘汰。当Redis使用的内存逼近maxmemory上限时,再有新的写入请求进来,Redis会按照这个算法先淘汰掉最冷的键,释放空间后再执行写入。
需要注意的是,Redis实现的并不是严格的LRU算法。严格的LRU需要一个双向链表维护全部键的访问顺序,每次访问都要移动节点,内存开销和CPU开销都不小。Redis采用的是近似LRU:给每个对象记录一个最近访问时间的时钟值(存24位空间,即lru字段),淘汰时随机抽取若干个键作为样本,从样本中挑出空闲时间最长的那个淘汰掉。采样数量由maxmemory-samples参数控制,默认值是5。样本数越大,结果越接近理论LRU,但消耗的CPU也越多,官方文档指出样本数设为10时已经非常接近真实LRU的表现。
allkeys-lru中的allkeys意味着候选范围是整个键空间,这一点很重要。与之对比,volatile-lru只会在设置了过期时间的键中做淘汰,如果你的键全都没有设置TTL,配置volatile-lru会导致内存满之后写入直接报错。所以对于纯缓存场景——数据丢了可以回源数据库重建——allkeys-lru通常是更稳妥的选择。
如何配置allkeys-lru并验证生效
配置方式有两种。第一种是修改配置文件redis.conf,找到maxmemory和maxmemory-policy两项,写入后重启实例生效;第二种是通过CONFIG SET命令在运行时动态修改,无需重启,立即生效。推荐先用CONFIG SET在线调整,观察稳定后再回写到配置文件,避免重启后配置丢失。
# 编辑 redis.conf,重启后生效 maxmemory 2gb maxmemory-policy allkeys-lru # 近似LRU的采样数量,默认5,可适当调大到10 maxmemory-samples 10 # 运行时动态修改,立即生效,不重启实例 redis-cli CONFIG SET maxmemory 2gb redis-cli CONFIG SET maxmemory-policy allkeys-lru redis-cli CONFIG SET maxmemory-samples 10 # 查看当前配置确认生效 redis-cli CONFIG GET maxmemory redis-cli CONFIG GET maxmemory-policy
验证策略是否真的在干活,可以借助INFO stats中的evicted_keys指标。这个计数器记录了因为内存达到上限而被淘汰的键总数。如果内存已经顶到maxmemory但evicted_keys一直是0,同时客户端报OOM command not allowed错误,说明策略配置可能有问题,或者当前策略找不到可淘汰的对象。此外,INFO memory中的used_memory和maxmemory对比也能直观看出内存压力。
# 观察淘汰计数,隔一段时间执行一次,看数值是否增长 redis-cli INFO stats | grep evicted_keys # 查看内存使用情况 redis-cli INFO memory | grep -E "used_memory_human|maxmemory_human|maxmemory_policy"
使用allkeys-lru需要注意的坑
第一个常见的坑是把allkeys-lru用在了存重要数据的Redis上。如果实例里除了缓存还存了分布式锁、队列、会话等不能丢失的数据,allkeys-lru不会区分它们,任何键都可能被淘汰掉,业务就会出现莫名其妙的异常。正确做法是做实例隔离:缓存实例用allkeys-lru,存储关键数据的实例不要设置过小的maxmemory,或者改用noeviction配合容量规划。
第二个坑是key的数量极多且冷热分布均匀时,近似LRU的随机采样可能导致淘汰效果不理想,出现缓存命中率下降的情况。这时可以调大maxmemory-samples,或者从业务层面优化,比如给冷数据主动设置过期时间,让过期删除机制分担淘汰压力。同时要警惕批量写入大键的场景,如果单个键的值很大,淘汰几个小键可能凑不够空间,Redis会继续淘汰更多键,写放大效应会带来明显的延迟抖动。
第三个坑是maxmemory本身设置不合理。如果给Redis分配的maxmemory超过了机器物理内存,操作系统会先触发OOM killer或者开始使用swap,进程层面的淘汰策略根本没机会执行,表现为Redis响应突然变得极慢。一般建议maxmemory不超过物理内存的70%到80%,给操作系统、fork时的写时复制以及碎片整理留出余量。另外要注意,开启AOF或RDB持久化时fork子进程需要复制页表,内存越满这个开销越大,这也是不能把内存榨干的原因之一。
总结来说,allkeys-lru适合典型的缓存场景:数据全量可以重建、追求自动化的空间回收。配置时记得同时设置合理的maxmemory和采样数,上线后持续关注evicted_keys和缓存命中率,一旦发现淘汰过于频繁或命中率下滑,就要重新评估内存容量与业务增长是否匹配。
Redismaxmemory-policyallkeys-lru修改时间:2026-09-07 00:12:32