中 进阶
Redis内存碎片#
一句话答案#
频繁增删导致 jemalloc 内存碎片,mem_fragmentation_ratio > 1.5 需关注,Redis 4.0+ 支持自动碎片整理。
核心要点
碎片产生原因:
Redis 使用 jemalloc 内存分配器,按固定大小的内存块分配(8/16/32/64...字节)
申请 24 字节 → jemalloc 分配 32 字节 → 浪费 8 字节(内部碎片)
频繁删除/修改 key → 释放的内存块大小不一,无法被新数据复用(外部碎片)plaintextmem_fragmentation_ratio 解读:
| 值 | 含义 | 处理 |
|---|---|---|
| < 1.0 | Redis 使用了 swap 分区,性能急剧下降 | 立即排查,增加物理内存 |
| 1.0 ~ 1.5 | 正常范围 | 无需处理 |
| > 1.5 | 碎片严重,内存浪费大 | 开启自动整理或重启 |
容易产生碎片的操作:
- 频繁删除大量 key(过期清理、批量删除)
- 频繁修改 value 大小(String 从短变长)
- 大量不同大小的 key-value 混合存储
碎片整理方案:
Redis 4.0 之前:只能重启实例(RDB/AOF 重新加载,内存重新紧凑分配)
Redis 4.0+:自动碎片整理(activedefrag)
config set activedefrag yes # 开启
config set active-defrag-threshold-lower 10 # 碎片率超过 10% 开始整理
config set active-defrag-threshold-upper 100 # 碎片率超过 100% 全力整理
config set active-defrag-cycle-min 1 # 最小 CPU 占比 1%
config set active-defrag-cycle-max 25 # 最大 CPU 占比 25%plaintext排查命令:
INFO memory
# 关注字段:
used_memory: 1073741824 # Redis 实际使用内存
used_memory_rss: 1610612736 # 操作系统分配给 Redis 的内存(含碎片)
mem_fragmentation_ratio: 1.50 # RSS / used_memory
mem_allocator: jemalloc-5.2.1 # 内存分配器版本bash面试回答(2分钟版)
Redis 使用 jemalloc 作为内存分配器,当频繁执行增删改操作时,释放的内存块大小不一,无法被新数据完全复用,就会产生内存碎片。通过 INFO memory 命令查看 mem_fragmentation_ratio(实际占用 RSS / Redis 已用内存),该值在 1.0-1.5 之间是正常的,超过 1.5 说明碎片严重需要处理。容易产生碎片的操作包括:频繁删除大量 key、频繁修改 value 大小(比如 string 从短变长)以及大量过期 key 被清理。Redis 4.0 之前只能通过重启来整理碎片,4.0 开始引入了 activedefrag 自动碎片整理功能,设置 activedefrag yes 开启后,Redis 在后台利用 jemalloc 的内存迁移能力将数据重新紧凑排列释放碎片空间。自动整理会消耗一定 CPU,可以通过 active-defrag-cycle-min/max 控制整理的 CPU 占比上下限。如果碎片率低于 1.0 说明 Redis 使用了 swap 分区,这时性能会急剧下降需要立即排查。
追问与易错
追问方向:
- “碎片率太低说明什么?”→ mem_fragmentation_ratio 小于 1.0 说明 Redis 使用了 swap 分区(操作系统将内存页换到磁盘),Redis 单线程模型下磁盘 IO 会导致所有请求延迟飙升,需立即增加物理内存
- “自动碎片整理影响?”→ activedefrag 利用 jemalloc 的内存迁移能力在后台整理,会消耗一定 CPU;可通过 active-defrag-cycle-min/max 控制 CPU 占比上下限(如 1%-25%),避免影响正常请求
- “什么操作容易导致碎片?”→ 频繁删除大量 key(过期清理/批量删除)、频繁修改 value 大小(String 从短变长)、大量不同大小的 key-value 混合存储,都会导致 jemalloc 释放的内存块大小不一无法复用
易错点:
- ❌ 碎片率高就有问题——1.0-1.5 正常
- ❌ 重启是唯一方案——4.0+ 有自动整理