根本原因是各节点maxmemory配置与真实内存压力不匹配;需按物理内存比例设maxmemory、启用active defrag、禁用volatile-ttl,并通过evicted_keys和mem_fragmentation_ratio监控淘汰实效性。

根本原因不是淘汰策略失效,而是各节点的 maxmemory 配置与真实内存压力不匹配——Redis Cluster 每个节点独立触发淘汰,但物理资源、碎片率、key 分布和过期节奏完全不同。
为什么统一配 maxmemory 20gb 反而加剧不均
集群里混用不同规格机器时,硬写死同一数值会直接扭曲淘汰节奏:
- 32GB 物理内存节点配
maxmemory 20gb,系统余量仅剩 12GB,还要分给内核、复制缓冲区等,实际可用远低于 20GB - 64GB 节点同样配
maxmemory 20gb,即使used_memory已达 35GB(因碎片或缓冲区膨胀),只要没超 20GB,就完全不淘汰 -
mem_fragmentation_ratio > 1.5的节点,used_memory显示值严重偏低,OS 层面已快 OOM,Redis 却还“以为很空”
如何确认淘汰是否真在发生,而不是被静默跳过
很多团队看到 maxmemory-policy 配了就以为万事大吉,其实淘汰可能压根没启动:
- 执行
redis-cli -h node_ip -p port INFO memory,检查maxmemory> 0 且used_memory > maxmemory * 0.95—— 否则淘汰逻辑根本不进入判断分支 - 看
evicted_keys字段:为 0 表示没淘汰;持续增长才说明策略生效;若它涨但keyspace_hits断崖下跌,说明误删了热 key - 查
expired_keys:某节点该值每秒突增数百,大概率承载了大量短生命周期 key(如 token、验证码),掩盖了真实冷数据淘汰需求
让淘汰节奏贴合真实负载的实操配置
目标不是“绝对均匀”,而是让每个节点的淘汰行为反映它真实的内存压力:
- 按物理内存比例设
maxmemory:32GB 节点配16gb,64GB 配32gb,避免一刀切 - 统一启用活性碎片整理:
CONFIG SET activedefrag yes+CONFIG SET active-defrag-threshold-lower 10,减少因碎片虚高引发的误淘汰 - 禁用
volatile-ttl:集群时钟不同步时易批量过期,改用allkeys-lfu或allkeys-lru,更贴近访问热度 - 检查
mem_allocator:若为libc(非jemalloc),大 key 删除后内存不归还 OS,used_memory持续虚高,需换 allocator 或重启
真正难处理的从来不是参数本身,而是业务层 key 的 TTL 设计——比如所有 token 统一设 EX 3600,就会导致某节点在整点前后集中过期,瞬间触发大量淘汰。这种问题光调 Redis 配置没用,必须从业务侧加随机后缀或分桶打散。











