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. 预防策略(从源头减少碎片)

  1. 优化数据结构:小Key合并:如将多个小String合并为Hash/List,减少内存块数量固定长度Value:避免Value频繁扩容/收缩,如预分配字符串空间
  2. 控制Key生命周期:合理设置过期时间,避免大量Key同时过期及时删除无用Key,避免内存长期占用
  3. 选择合适分配器:编译Redis时指定--with-jemalloc,优先使用jemalloc分配器
  4. 监控与预警:配置Prometheus+Grafana监控mem_fragmentation_ratio,阈值设为1.5结合maxmemory-policy配置,避免碎片导致的误淘汰

五、常见误区与注意事项

  1. 碎片≠内存泄漏:内存泄漏是Redis进程持续占用内存不释放,碎片是已分配未使用的内存碎片率高≠内存泄漏,需通过INFO memory区分
  2. 整理后碎片率可能反弹:若业务仍频繁增删改,碎片会再次产生,需结合预防策略
  3. 集群模式注意:集群中需逐个节点开启整理,避免跨节点影响整理时会产生少量网络开销,需在低峰期操作

总结

Redis内存碎片是高频写场景的隐性问题,核心监控指标是mem_fragmentation_ratio>1.5时优先开启主动碎片整理,结合数据结构优化、生命周期控制等策略,可有效降低内存浪费,保障Redis稳定运行。

ps:如果这篇帖子对于还在找工作和找实习的你有所帮助,可以关注我,给本贴点赞、评论、收藏并订阅专栏;同时不要吝啬您的花花

Redis生产 文章被收录于专栏

聚焦Redis 生产环境实战,从问题现象、根因分析、排查流程、解决方案、预防机制五大维度,系统拆解 Redis 线上高频故障与性能瓶颈,提供可直接落地的运维、开发与调优方案,助力构建高可用、高性能、高可靠的 Redis 服务体系

全部评论

相关推荐

昨天 21:39
门头沟学院 Java
Data_Seven:6 他说的 全是我的词儿啊
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务