memory purge仅在使用jemalloc且mem_fragmentation_ratio>1.5时可能降低used_memory_rss,需空闲内存块足够大且连续才能触发madvise归还;libc malloc下直接报错,碎片率<1.2时无效。

MEMORY PURGE 什么时候能真正归还 RSS 内存
它只在 Redis 编译时使用 jemalloc(默认),且运行时内存碎片严重(mem_fragmentation_ratio > 1.5)时才可能降低 used_memory_rss。前提是:空闲内存块足够大、连续,jemalloc 才会调用 madvise(MADV_DONTNEED) 交还给 OS。
常见误判场景:
-
mem_fragmentation_ratio ≈ 1.1→ 执行MEMORY PURGE基本无变化 - 用了
libc malloc或tcmalloc→ 命令直接报错:ERR MEMORY PURGE not supported -
used_memory接近maxmemory,但used_memory_rss更高 → 这是碎片,不是内存泄漏;MEMORY PURGE可能有用,但淘汰策略不会触发
如何确认当前是否适合执行 MEMORY PURGE
先跑 INFO memory,重点关注三行:
-
used_memory:1827456000(Redis 自认用了多少) -
used_memory_rss:3982458880(OS 看到的物理内存) -
mem_fragmentation_ratio:2.18(RSS / used_memory,> 1.5 才值得干预)
如果 mem_fragmentation_ratio 在 1.0~1.2 之间,说明碎片极少,MEMORY PURGE 没必要;若 > 2.0 且 used_memory_rss − used_memory > 500MB,可尝试。
再验证分配器类型:INFO memory 中若有 mem_allocator:jemalloc-5.2.1 才继续;若显示 libc,跳过该命令。
执行 MEMORY PURGE 的正确姿势和副作用
直接发命令即可,无需参数:
MEMORY PURGE
它会阻塞主线程几毫秒到几十毫秒(取决于 jemalloc arena 数量和空闲页规模),期间所有命令排队等待。不建议在流量高峰时手动触发。
执行后观察变化:
-
used_memory不变(没删 key) -
used_memory_rss可能下降(如从 4.0GB → 3.2GB) -
mem_fragmentation_ratio向 1.0~1.2 靠拢 -
evicted_keys、expired_keys等指标完全不变
注意:MEMORY PURGE 不是定时任务,Redis 不会自动重试;若一次效果弱,可间隔 30 秒再试一次,但连续多次意义不大。
比 MEMORY PURGE 更有效的替代方案
当 MEMORY PURGE 效果微弱或不生效时,优先考虑这些实操路径:
- 发
SIGUSR1信号强制 jemalloc purge:kill -USR1 $(pidof redis-server)(对 Redis 6.0+ +background_thread yes更有效) - 用
UNLINK替代DEL删除大 key,避免阻塞,也减少碎片生成节奏 - 开启主动碎片整理:
CONFIG SET activedefrag yes(Redis 4.0+ 实验特性,需搭配active-defrag-ignore-bytes和active-defrag-threshold-lower调优) - 长期 RSS 居高不下且无法缓解?考虑滚动重启从节点,或启用
FLUSHDB ASYNC清库后重建
真正难处理的,是小对象高频增删导致的细碎空闲页 —— jemalloc 对这种场景几乎不归还,MEMORY PURGE 也无能为力。这时候得从业务侧收敛 value 大小、避免短生命周期小 key 泛滥。











