Redis 内存碎片
ps:如果这篇帖子对于还在找工作和找实习的你有所帮助,可以关注我,给本贴点赞、评论、收藏并订阅专栏;同时不要吝啬您的花花
核心结论:Redis内存碎片是已分配但未被使用的零散内存块,常见于频繁增删改场景,会导致内存浪费、OOM风险,需通过INFO memory监控并主动整理。
一、什么是内存碎片?
内存碎片指Redis已向操作系统申请到的内存(used_memory_rss)中,未被有效利用的空闲小块。这些碎片虽总存在,但因不连续、大小不匹配,无法被新数据复用,最终表现为:
- 实际存数据内存(used_memory)远小于操作系统分配内存(used_memory_rss)
- 内存利用率下降,甚至触发maxmemory限制,导致Key被误淘汰
二、产生的核心原因
1. 内存分配器机制(根本原因)
Redis默认使用jemalloc分配器,采用固定大小块(8/16/32/...字节) 分配内存。例如:
- 存6字节数据,jemalloc分配8字节,多余2字节即为碎片
- 分配器为性能会预分配大块内存,释放时未必立即归还操作系统,形成残留碎片
2. 数据频繁变动(直接原因)
- Key增删改频繁:如秒杀、临时缓存场景,Key过期/被删除后,内存块变碎片,新数据未必能填充
- Value大小变化:如字符串追加、Hash字段更新,导致内存扩容/释放,产生新旧碎片
- 过期Key清理:惰性删除+定时清理的策略,会留下大量未被复用的内存空洞
3. 其他因素
- 持久化影响:RDB/AOF重写时会产生临时内存块,重写结束后部分内存未及时释放
- 内存分配器选择:若编译时指定libc分配器,碎片率通常高于jemalloc
三、关键指标与监控
通过INFO memory命令查看核心指标,快速判断碎片情况:
used_memory | Redis实际存储数据的内存(字节) | - |
used_memory_rss | 操作系统分配给Redis进程的总内存(字节) | - |
mem_fragmentation_ratio | 碎片率 = used_memory_rss / used_memory | ✅ <1.0:内存被Swap,性能严重下降,需立即扩容/清理 ✅ 1.0~1.5:正常范围,无需处理 ✅ >1.5:碎片偏高,建议主动整理 |
allocator_frag_ratio | jemalloc内部碎片率 | 辅助判断分配器内部损耗 |
监控命令:
# 实时查看碎片率 redis-cli INFO memory | grep mem_fragmentation_ratio # 完整内存信息 redis-cli INFO memory
四、清理与优化策略
1. 主动碎片整理(Redis 4.0+ 推荐)
Redis 4.0引入Active Defragmentation(主动碎片整理),原理是移动内存中的Key,将零散空闲块合并为连续大块,无需重启,对业务影响小。
配置方式:
# redis.conf activedefrag yes # 开启主动碎片整理(默认关闭,Redis 8.x需手动开启) active-defrag-ignore-bytes 100mb # 碎片达到100MB才触发整理 active-defrag-threshold-lower 10 # 碎片率低于10%不整理 active-defrag-threshold-upper 100 # 碎片率高于100%强制整理 # 控制整理CPU占用,避免影响业务 active-defrag-cycle-min 1 active-defrag-cycle-max 25
触发条件:
- 碎片大小超过active-defrag-ignore-bytes
- 碎片率在[lower, upper]区间内
- 整理时会暂停少量Key的读写,需合理配置cycle参数
2. 重启Redis(终极方案)
重启可彻底释放所有碎片,但需注意:
- 数据丢失风险:需确保开启RDB/AOF持久化,重启后加载数据
- 业务中断:集群模式下可单节点滚动重启,避免服务不可用
3. 预防策略(从源头减少碎片)
- 优化数据结构:小Key合并:如将多个小String合并为Hash/List,减少内存块数量固定长度Value:避免Value频繁扩容/收缩,如预分配字符串空间
- 控制Key生命周期:合理设置过期时间,避免大量Key同时过期及时删除无用Key,避免内存长期占用
- 选择合适分配器:编译Redis时指定--with-jemalloc,优先使用jemalloc分配器
- 监控与预警:配置Prometheus+Grafana监控mem_fragmentation_ratio,阈值设为1.5结合maxmemory-policy配置,避免碎片导致的误淘汰
五、常见误区与注意事项
- 碎片≠内存泄漏:内存泄漏是Redis进程持续占用内存不释放,碎片是已分配未使用的内存碎片率高≠内存泄漏,需通过INFO memory区分
- 整理后碎片率可能反弹:若业务仍频繁增删改,碎片会再次产生,需结合预防策略
- 集群模式注意:集群中需逐个节点开启整理,避免跨节点影响整理时会产生少量网络开销,需在低峰期操作
总结
Redis内存碎片是高频写场景的隐性问题,核心监控指标是mem_fragmentation_ratio,>1.5时优先开启主动碎片整理,结合数据结构优化、生命周期控制等策略,可有效降低内存浪费,保障Redis稳定运行。
ps:如果这篇帖子对于还在找工作和找实习的你有所帮助,可以关注我,给本贴点赞、评论、收藏并订阅专栏;同时不要吝啬您的花花
聚焦Redis 生产环境实战,从问题现象、根因分析、排查流程、解决方案、预防机制五大维度,系统拆解 Redis 线上高频故障与性能瓶颈,提供可直接落地的运维、开发与调优方案,助力构建高可用、高性能、高可靠的 Redis 服务体系
查看18道真题和解析