Redis 3.2内存异常:Used Memory仅43MB但RSS达2.7G且增长,求生产环境解决方案
这种Redis内存碎片异常飙升的情况我在生产环境处理过好几次,结合你给出的监控数据(mem_fragmentation_ratio高达63.34),咱们来拆解问题并给出不用重启的应急方案:
先理解核心现象
used_memory是Redis实际存储数据消耗的内存(43.71M),说明你的业务数据量并不大used_memory_rss是操作系统给Redis进程分配的物理内存(2.70G),两者差值极大说明内存碎片严重到了极端程度mem_fragmentation_ratio = used_memory_rss / used_memory,正常范围在1.0~1.5之间,你这个63.34已经远远超出合理值
可能的根因
jemalloc 3.6.0的碎片缺陷
你当前用的内存分配器是jemalloc-3.6.0,这个旧版本在应对频繁的内存分配/释放场景(比如大量过期key删除、大key频繁修改)时,容易产生大量无法被操作系统回收的内存碎片,这些碎片会一直占用物理内存。历史大key遗留影响
虽然现在db0只有4613个key,但之前可能存在过超大体积的key(比如包含百万级元素的哈希、列表),删除这些大key后,jemalloc不会主动把释放的内存归还给操作系统,而是保留在Redis进程的内存池中,久而久之就会撑大RSS。Redis 3.2的内存回收机制不足
Redis 4.0及以后版本才引入了**主动内存碎片整理(active defrag)**功能,而3.2只能依赖jemalloc的被动回收逻辑,效率极低,无法应对严重的碎片堆积。
生产环境无需重启的应急方案
1. 触发jemalloc归还空闲内存
执行以下Redis命令(务必在业务低峰期操作,会短暂阻塞进程):
DEBUG PURGE
这个命令会强制jemalloc将进程中未被使用的空闲内存归还给操作系统,通常能大幅降低used_memory_rss。执行后可以再用INFO memory查看碎片率变化。
2. 优化后台任务调度频率
默认Redis的hz参数是10,代表每秒执行10次后台任务(包括过期key清理、内存回收)。可以临时调高这个值,让Redis更频繁地处理内存相关的后台工作:
CONFIG SET hz 100
注意:hz值越高,Redis占用的CPU会越多,建议根据服务器CPU负载调整(比如从20、50逐步往上试),后续业务平稳后可以调回默认值。
3. 避免后续产生新碎片
- 尽量避免创建和修改大key:如果有大体积的哈希/列表,拆分成多个小key来存储
- 分批删除过期/无用key:因为Redis 3.2没有
UNLINK(异步删除)命令,一次性删除大量key会瞬间释放大量内存,加剧碎片问题,建议分批次执行DEL操作
长期优化方案(若后续能重启)
- 升级Redis到4.0及以上版本,开启主动内存碎片整理:
CONFIG SET activedefrag yes,这个功能会在后台自动整理内存碎片,无需人工干预 - 升级jemalloc到5.x版本:新版本的内存分配器在碎片管理上有大幅优化,能减少碎片产生
- 配置合理的
maxmemory和淘汰策略:如果服务器内存有限,设置maxmemory并选择合适的淘汰策略(比如allkeys-lru),避免内存无限制增长
内容的提问来源于stack exchange,提问作者Farhad

