哨兵模式下 Redis 内存碎片全解

先一句话前置:哨兵只管主从故障切换、集群元数据,不干涉 Redis 自身内存分配、碎片机制、maxmemory 规则,碎片产生、归属、整理、风险和单机完全一致,只多一个主从切换附加风险


0、Redis 内存碎片是怎么产生的?

根本原因

Redis 用 jemalloc/libc 内存分配器,内存按固定块粒度分配,释放不立刻归还系统

  1. Key 频繁增删改
    小key删了、大key改小,分配器留下零散空闲内存块,不能被新大key复用,就成碎片。
  2. 大 Key / 集合对象
    Hash/List/Set 频繁扩缩容、渐进式删除,最容易产生大量碎片。
  3. 过期 Key 惰性删除+定时清理
    过期键不是立刻释放,后台慢慢回收,内存孔洞越来越多。
  4. 主从复制缓冲区、客户端缓冲区
    复制积压缓冲区、client-output-buffer 动态涨缩,反复申请释放内存,制造碎片。
  5. 哨兵额外加重因素
    哨兵心跳、发布订阅、主从同步复制缓冲区长期波动,额外加剧碎片。

1、内存碎片属于 maxmemory 的一部分吗?

结论

碎片不属于 maxmemory 管控范围,不计入 maxmemory 限额

  1. 管控口径
    • maxmemory 限制的是:used_memory(Redis 逻辑数据内存:所有KV、元数据、业务结构)
    • 碎片在:used_memory_rss
      [
      碎片近似 = used_memory_rss - used_memory
      ]
      [
      碎片率 = \dfrac{used_memory_rss}{used_memory}
      ]
  2. 关键痛点(哨兵主从更要命)
    • RSS 被碎片撑得很高,占满服务器物理内存,直接 OOM
    • 哨兵如果发生主从切换,从库同时做全量同步、RDB 落地,内存再暴涨,极易连环 OOM

2、碎片怎么整理?整理期间有什么风险(哨兵模式专属+通用风险)

三种整理方式

方式A:开启主动碎片整理 activedefrag(Redis4.0+ 生产首选,哨兵主从都可用)
activedefrag yes
active-defrag-ignore-bytes 100mb
active-defrag-threshold-lower 10
active-defrag-cycle-min 1
active-defrag-cycle-max 20
  • 工作机制:后台异步渐进式迁移 key,不是一次性整理,分片慢慢挪内存
  • 主线程:极轻微微阻塞(亚毫秒~毫秒级),正常业务无感知
方式B:MEMORY PURGE(Redis6.0+)
  • 只通知 jemalloc 把空闲内存页归还系统
  • 不移动key、不整理内存孔洞,不阻塞主线程
  • 只能缓解轻度碎片,重度无效
方式C:重启实例(兜底方案,哨兵环境要滚动重启)
  • 原理:重启重新加载数据,内存重新排布,碎片清零
  • 哨兵必须先裁从库重启,再手动切主,再重启老主,避免全集群不可用

整理期间 通用风险 + 哨兵模式特有风险

通用风险
  1. CPU 占用抬升
    activedefrag 会占用配置比例 CPU,高并发下轻微增加命令延迟毛刺。
  2. 短期内存先涨后降
    整理时要临时拷贝内存页,RSS 短暂更高,内存余量不足会 OOM。
  3. 超大 Key 带来微阻塞
    几十MB以上大key迁移时,主线程短暂卡顿,极端出现业务超时。
哨兵模式 独有风险
  1. 主从复制延迟变大
    碎片整理期间内存拷贝、进程内存抖动,主从复制缓冲区波动,复制延迟拉高
  2. 误触发哨兵主观下线
    整理偶发主线程微卡顿、命令响应变慢,若 sentinel down-after-milliseconds 设得过小,哨兵误判主库下线,触发无故主从切换
  3. 切换叠加内存压力
    若整理期间刚好触发故障切换,新主库全量同步+RDB 落地,内存双重打爆,集群雪崩。

哨兵模式 最佳落地建议

  1. 碎片率 >1.5 告警,>1.8 必须开启整理
  2. 优先开 activedefrag,严控 cycle-max 不超20%;
  3. 哨兵故障判定时间不要设太小,留出整理卡顿冗余;
  4. maxmemory 不要拉满,预留 30% 以上系统内存给碎片+复制缓冲区;
  5. 禁止业务高峰期手动重启整理,避免哨兵乱切换。
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐