redis集群中各master节点独立执行maxmemory策略,互不影响;需单独配置maxmemory及maxmemory-policy,通过evicted_keys、oom报错等指标确认淘汰,调优maxmemory-samples并开启activedefrag。

Redis 5.0 集群中,每个 Master 节点确实独立执行自己的 maxmemory 和 maxmemory-policy,不会跨节点协调淘汰 —— 这是默认且唯一行为,不是 bug,是设计使然。
为什么集群里各 Master 的内存满容互不影响?
Redis Cluster 不共享内存状态,每个节点只感知自身 used_memory。当某个 Master 执行写命令时,它会检查本地 used_memory > maxmemory,触发本节点的淘汰逻辑;其他 Master 即使内存空闲,也不会帮它删 key,也不会被它拖垮。
-
maxmemory是 per-node 配置,必须在每个节点的redis.conf中单独设置(或用CONFIG SET动态修改) -
CLUSTER NODES或INFO memory返回的内存指标也全是本地值,没有“集群总内存”这类聚合字段 - 客户端路由到哪个 slot 就打到对应 Master,淘汰完全发生在该 Master 内部,和 slot 分布、key 数量分布无关
如何确认某个 Master 节点已触发淘汰?
不能只看 INFO memory 里的 used_memory 是否超限 —— 因为淘汰是渐进式、按需触发的。真正关键的信号是:
- 写命令开始返回
(error) OOM command not allowed when used memory > 'maxmemory'.→ 说明策略是noeviction且已卡死 -
INFO stats中evicted_keys值持续增长 → 表明当前策略正在主动淘汰(如allkeys-lru) -
INFO memory中mem_allocator显示 jemalloc 版本较旧(如 3.x),可能加剧内存碎片,让used_memory看似未超但实际分配失败
建议在每个 Master 上运行:redis-cli -h NODE_IP -p PORT info memory | grep -E "(used_memory|maxmemory|mem_fragmentation_ratio)",再比对 info stats | grep evicted_keys。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
maxmemory-samples 参数对集群节点很关键
LRU/LFU 类策略(如 allkeys-lru)不是全量扫描所有 key,而是每次随机采样 maxmemory-samples 个 key(默认 5),从中选最不活跃的淘汰。这个值直接影响淘汰“准不准”和 CPU 开销:
- 设太小(如 1)→ 淘汰随机性增强,容易误杀热 key
- 设太大(如 100)→ 每次淘汰前要遍历更多 key,写延迟升高,尤其在大 key 多的场景
- 集群中各节点最好统一调优:比如设为 20,在内存压力明显时能提升 LRU 准确率,又不至于明显拖慢响应
修改方式:CONFIG SET maxmemory-samples 20(无需重启,但不持久化);若要固化,需写入各节点的 redis.conf。
容易被忽略的三个实操细节
集群环境下,以下三点常被跳过,却直接导致“明明配了 allkeys-lru,还是频繁 OOM”:
- 没关掉
activedefrag:内存碎片率高(mem_fragmentation_ratio > 1.5)时,即使used_memory没超maxmemory,也可能因无法分配连续页而失败。应开启:CONFIG SET activedefrag yes - 忘了检查
maxmemory单位:config set maxmemory 2g有效,但config set maxmemory 2gb会被 Redis 忽略(日志报 warning),导致实际无内存限制 → 始终用k/m/g小写单位 - 客户端重试逻辑缺失:当某 Master 因
noeviction拒绝写入,客户端若直接抛错而不降级(如写本地缓存、落库),整个链路就断了。真实业务中应捕获OOM command not allowed并走备选路径
单节点内存问题在集群里不会自动“摊薄”,每个 Master 都得自己扛住自己的内存压力 —— 配置、监控、客户端容错,一个都不能少。










