Redis集群各节点淘汰不均,本质是maxmemory按节点独立配置且触发条件不一致;需按物理内存比例设maxmemory、启用active defrag、禁用volatile-ttl,并通过evicted_keys和mem_fragmentation_ratio监控真实淘汰行为。

Redis Cluster各节点内存淘汰不均,本质不是淘汰策略没生效,而是淘汰触发条件在各节点上不一致——maxmemory 是按节点独立配置的,而 maxmemory-policy 只对本节点超限生效;如果某节点 keys 数少但单 key 极大、或碎片率高导致 used_memory 虚高,它可能早于其他节点触发淘汰,造成“有的节点狂删 key,有的节点还在报 OOM”。
为什么 maxmemory 设相同值反而导致淘汰不均
集群中每个节点物理内存可能不同(比如混用 32G 和 64G 机器),若统一配 maxmemory 20gb,32G 节点实际可用内存余量小,更容易触达淘汰阈值;而 64G 节点即使 used_memory 达到 35GB,只要没超 20GB 配置值,就完全不淘汰。更隐蔽的是:
-
mem_fragmentation_ratio> 1.5 的节点,used_memory显示值远低于真实物理占用,系统内存压力已高,但 Redis 还没启动淘汰 -
active_defrag_enabled关闭时,大 key 删除后内存不归还 OS,used_memory持续虚高,反复触发无效淘汰 - 某些节点存在大量
volatile-ttl类 key(如短期 token),到期集中失效,expired_keys短时飙升,掩盖了真正该淘汰的冷数据
如何让淘汰行为在集群层面更可控
不追求“绝对均匀”,而是让各节点淘汰节奏与真实负载匹配:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 按节点物理内存比例设
maxmemory:32G 节点配16gb,64G 配32gb,避免硬写死同一数值 - 统一启用活性碎片整理:
CONFIG SET activedefrag yes+CONFIG SET active-defrag-threshold-lower 10,减少因碎片导致的误淘汰 - 禁用
volatile-ttl类策略:它依赖 key 的 TTL 精确性,集群时钟不同步时容易批量过期,改用allkeys-lfu或allkeys-lru,更贴近访问热度 - 用
INFO stats | grep expired_keys对比各节点过期键速率,若某节点值异常高(如每秒 500+),说明它承载了大量短生命周期 key,需从业务层打散(例如加随机后缀token:{uid}:{rand(1,16)})
检查淘汰是否真在发生,而不是被静默跳过
很多团队以为开了 maxmemory-policy 就万事大吉,其实淘汰可能根本没触发:
- 执行
redis-cli -h node_ip -p port INFO memory,确认maxmemory> 0 且used_memory>maxmemory * 0.95—— 否则淘汰逻辑压根不启动 - 看
evicted_keys字段:为 0 说明没淘汰;持续增长才表示策略生效;若它增长但keyspace_hits大幅下降,说明淘汰误伤了热 key - 注意
mem_allocator:若为libc(非 jemalloc),内存归还不及时,used_memory下降慢,会反复触发淘汰
真正难处理的不是淘汰策略本身,而是各节点的 used_memory 统计口径不一致——有的节点刚做过 MEMORY PURGE,有的还在扛着 2.3 的碎片率,这时候强行拉齐 maxmemory 值,只会让负载雪上加霜。

















