maxmemory-samples设过大(如20+)会显著增加纯CPU密集型开销,因每次淘汰需随机采样大量key进行LRU/LFU评估;默认值5是90%场景的精度与性能平衡点,仅对allkeys-lru、volatile-lfu等采样类策略生效。

maxmemory-samples 设置过大会显著增加 CPU 开销
会,而且是纯 CPU 密集型开销。Redis 在启用 allkeys-lru、volatile-lfu 等基于近似算法的淘汰策略后,每次触发淘汰检查时,都要调用 evictionPoolPopulate 函数随机采样一批 key 做访问时间或频次评估——这个过程不涉及磁盘、网络或锁竞争,只消耗 CPU。
常见错误现象:
- 内存使用率长期低于
maxmemory(比如 60%),但top中redis-server的 CPU 占用持续高于 70% -
INFO stats中evicted_keys持续增长,且与写入 QPS 强相关 -
perf top显示evictionPoolPopulate占 CPU 时间 Top 3
关键参数差异:
-
maxmemory-samples 1:极快,但接近随机淘汰,缓存局部性受损 -
maxmemory-samples 5:默认值,90% 场景下精度与开销平衡点 -
maxmemory-samples 20+:单次采样耗时可能翻 3–5 倍,key 总数超百万时尤为明显
注意:maxmemory-samples 对 volatile-ttl、noeviction 等策略无效;它只影响 LRU/LFU 类策略。
定期删除过期 key 也会抢 CPU,但机制不同
这不是淘汰策略的问题,而是过期清理本身带来的开销。Redis 每 100ms 执行一次过期 key 抽查(由 hz 配置控制),默认随机取 20 个带过期时间的 key 判断是否过期。如果其中过期比例 >25%,就继续抽样,最多执行 25ms。
容易踩的坑:
- 大量 key 同一时刻过期(如没加随机偏移),导致单次抽查中过期比例极高,触发连续多轮扫描,CPU 短时飙升
- 把
hz调得过高(如设为 100),让抽查频率从每秒 10 次变成 100 次,CPU 开销线性增长 - 误以为“没写入就没压力”,其实只要存在大量待清理的过期 key,定期删除就会持续争抢 CPU
验证方式:观察 INFO stats 中 expired_keys 是否在低流量时段仍稳定增长;用 redis-cli --stat 看 expired_keys 和 instantaneous_ops_per_sec 是否弱相关。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
LRU/LFU 实现不是真算法,而是采样估算
Redis 不维护全局访问链表或计数器,而是靠每个 key 的 lru 字段(24 位)记录最后一次被访问的“相对时间戳”(单位是 Redis 服务启动后的 LRU clock tick)。淘汰时仅靠这个字段 + 随机采样做排序,本质是启发式估算。
这意味着:
- 调高
maxmemory-samples并不能让 LRU 更“准确”,只是让估算结果更趋近统计学意义下的分布,对实际命中率提升微乎其微 - 真正影响缓存效果的是数据访问模式(局部性、倾斜度),而不是采样数量
- 如果你的应用冷热分明、访问集中,
maxmemory-samples 3和5的淘汰行为几乎无差别
性能影响:采样量翻倍 → CPU 时间大致翻倍,但内存释放速度、缓存命中率变化可忽略。
noeviction 或 volatile-ttl 策略基本不耗 CPU
如果业务场景允许拒绝写入,或所有缓存都带 TTL 且希望优先删快过期的,选 noeviction 或 volatile-ttl 可彻底避开淘汰计算开销。
适用场景:
- Redis 用作旁路缓存(cache-aside),应用层控制写入节奏
- 所有 key 都通过
EXPIRE或SETEX设置 TTL,且 TTL 分布较均匀 - 集群中某节点承担读多写少的固定角色,内存水位可控
注意:volatile-ttl 不依赖采样,也不更新任何访问元信息,纯靠读取 key 的 expires 字段排序,开销可忽略。
真正难调的不是策略本身,而是把 maxmemory-samples 当成“精度开关”去盲目调高——它其实是 CPU 开销调节旋钮,不是缓存质量杠杆。

















