什么是内存碎片?
Redis 存储 5GB 数据,却占用了 10GB 物理内存——多出来的 5GB 就是内存碎片。
碎片产生的原因:频繁的键值增删改操作,会在内存中留下大量「空洞」,这些空洞无法被有效利用,导致内存利用率持续下降。
第一步:检查碎片率
redis-cli info memory | grep mem_fragmentation_ratio
判断标准:
| 碎片率 | 状态 | 处理建议 |
|---|---|---|
| 1.0 ~ 1.2 | 正常 | 无需处理 |
| 1.2 ~ 1.5 | 轻度碎片 | 关注趋势 |
| > 1.5 | 需要优化 | 立即处理 |
| < 1.0 | 使用了虚拟内存 | 先解决内存不足 |
第二步:找到根因
三种常见场景:
场景一:频繁增删改
高频写入的业务(如计数器、会话存储)会产生大量碎片。优化方向:设置合理的过期时间,使用批量操作(MSET/MGET)。
场景二:数据类型选择不当
大量小 key 分散存储,碎片率高。优化方向:将相关小 key 合并为 Hash 结构。
场景三:Redis 版本过旧
Redis 4.0 以下没有自动碎片整理功能。升级到 4.0+ 是根本解决方案。
第三步:清理碎片
方案一:开启自动整理(推荐,Redis 4.0+)
redis-cli config set activedefrag yes
自动整理在后台运行,对业务影响极小(性能损耗 < 5%)。
方案二:手动重启(适合低流量时段)
# 先备份数据
redis-cli bgsave
# 等待备份完成后重启
systemctl restart redis
重启会清除所有碎片,但需要在业务低峰期操作。
预防措施
- 定期监控碎片率,设置告警阈值(建议 > 1.5 时告警)
- 避免过度优化,碎片率在 1.2 以内无需处理
- 集群规划时预留 10-20% 的内存余量
- 优先使用 Hash 结构替代大量分散的 String key