← 返回题目列表

Redis 内存碎片是什么?如何排查和优化?

高频 中等 第 11 / 36 题 更新于 2026/07/29
Redis内存碎片maxmemory性能优化

简化版

Redis 内存碎片是分配器向操作系统申请的内存大于 Redis 实际存放数据需要的内存,常由频繁增删改、大 Key 变化、分配器复用不充分导致。排查看 INFO memorymem_fragmentation_ratio、RSS、used_memory,并结合 bigkey、淘汰策略和主动碎片整理优化。

详细版

Redis 内存指标常见有:

  • used_memory:Redis 数据和内部结构使用的内存。
  • used_memory_rss:进程实际占用的物理内存。
  • mem_fragmentation_ratio:RSS 与 used_memory 的比例。

碎片率过高说明 Redis 进程占用内存明显高于数据实际使用。原因可能是频繁写入删除、value 大小变化大、大 Key 删除、jemalloc 分配粒度、fork 写时复制等。

优化方向包括拆 BigKey、稳定 value 大小、合理 maxmemory、开启主动碎片整理、低峰期执行清理、避免短时间大批量删除。不能只看一个 ratio,要结合实例大小和操作系统内存判断。

完整版教学

一、内存碎片到底是什么

内存碎片可以理解为“房间租了很多,但真正放东西的面积没那么多”。Redis 通过内存分配器申请和释放内存,释放后的空间不一定马上还给操作系统,也不一定正好能被下一次分配复用。

如果 used_memory 是 4 GB,而 used_memory_rss 是 6 GB,碎片率大约是 1.5。多出来的 2 GB 不一定是业务数据,可能是碎片、分配器保留、进程额外开销。

记忆钩子:used_memory 看“东西有多少”,RSS 看“房子占多少”,碎片看“房子和东西差多少”。

二、关键指标怎么看

INFO memory 是排查入口。核心指标包括 used_memoryused_memory_rssmem_fragmentation_ratioallocator_frag_ratioallocator_rss_ratio 等。

used_memory = 4GB
used_memory_rss = 6GB
mem_fragmentation_ratio = 6 / 4 = 1.5

但 ratio 要结合绝对值看。一个很小的实例 used_memory 只有 20 MB,RSS 60 MB,ratio 是 3,也未必严重;一个 100 GB 实例 ratio 1.3,多出来 30 GB 就很危险。

三、为什么频繁增删改会产生碎片

Redis value 大小经常变化时,旧内存块释放,新内存块申请,分配器可能留下很多大小不合适的空洞。例如一个 key 的 value 在 1 KB、20 KB、3 KB 之间反复变化,复用效率就可能下降。

BigKey 删除也会制造明显波动。一个包含百万 field 的 Hash 被删除,释放过程和分配器回收都可能带来延迟和碎片。

写入 20KB -> 删除 -> 空出 20KB 块
写入 3KB  -> 可能只复用一部分
剩余空间 -> 碎片或等待复用

四、maxmemory 和碎片的关系

Redis 的 maxmemory 控制的是 Redis 视角的内存使用,不一定等于进程 RSS。碎片率高时,即使 used_memory 没超过 maxmemory,操作系统层面的物理内存也可能紧张。

比如机器 16 GB,Redis maxmemory 设置 12 GB,碎片率 1.4 时 RSS 可能接近 16.8 GB,系统就可能发生 swap 或 OOM 风险。

指标示例
maxmemory12 GB
used_memory12 GB
fragmentation ratio1.4
估算 RSS16.8 GB

所以容量规划要给碎片、fork、客户端缓冲区和系统留余量。

五、主动碎片整理能解决什么

Redis 支持主动碎片整理,尝试把分散对象搬到更紧凑的内存位置,让分配器释放更多页。它能降低部分碎片,但会消耗 CPU。

这类优化应该压测和灰度。业务高峰期激进整理可能带来 CPU 抖动,低峰期逐步整理更稳。碎片整理不是替代数据模型优化的银弹。

先监控 -> 判断碎片绝对量 -> 低峰开启/调参 -> 观察 CPU 与 P99

六、从数据模型减少碎片

比起事后整理,更好的方式是减少碎片来源。常见做法包括拆分 BigKey、控制 value 大小、避免频繁重写大对象、批量删除改成渐进式删除。

例如把一个 100 万 field 的 Hash 按用户段拆成 100 个小 Hash,删除、迁移、过期和复制压力都会更可控。碎片问题往往和 BigKey 治理相互关联。

问题改法
大 Hash 频繁改分片拆 key
大量一次性删除分批删除或异步删除
value 大小剧烈变化稳定结构或拆冷热字段

七、排查流程怎么讲

线上排查不要只盯 mem_fragmentation_ratio。建议按实例内存、RSS、碎片绝对值、BigKey、fork、淘汰、客户端缓冲区一起看。

INFO memory
   |
看 used_memory / RSS / ratio
   |
查 BigKey 与写入删除模式
   |
看 fork/AOF rewrite/复制
   |
决定拆 key、调 maxmemory、开碎片整理或迁移重启

有时重启可以降低碎片,但它是运维手段,不是根因修复。面试回答要体现你会找根因。

八、常见误区与追问

  • 误区:碎片率大于 1 就一定有问题。 要结合 used_memory 规模和 RSS 绝对差值判断。
  • 误区:maxmemory 设置好了就不会 OOM。 RSS、fork 写时复制、客户端缓冲区都可能额外占内存。
  • 误区:重启 Redis 就算解决碎片。 重启可能短期下降,但频繁增删大对象的根因仍在。
  • 追问:碎片整理会不会影响性能? 会消耗 CPU,需低峰、灰度、观察 P99。
  • 追问:BigKey 和碎片有什么关系? 大对象分配释放不均衡,容易放大碎片和释放延迟。
  • 追问:怎么给 maxmemory 留余量? 根据碎片率、fork 峰值、连接缓冲区和系统内存预留,而不是贴满机器内存。

九、加强记忆

记住“used_memory 是数据,RSS 是占用,ratio 是差距”。碎片问题本质是内存分配和释放不均衡带来的空间浪费。

答题时按指标、原因、风险、治理四步走:看 INFO memory,找 BigKey 和写删模式,再决定整理、拆分、限额或迁移。