Redis 内存碎片率升高时怎么区分数据增长和分配器行为
Redis 的 mem_fragmentation_ratio 升高,并不等于当前数据量变大。先看 used_memory 与 used_memory_rss 的变化:前者跟着 Redis 当前分配的数据走,后者是进程驻留内存。删除过一批大键后,RSS 可能暂时留在高位;如果后续写入只复用了这些空闲块,RSS 不再上涨,原因更接近分配器行为,而不是数据持续增长。
- 先用
INFO memory建立两个时间点的内存基线,不要只盯碎片率。 - 用
SCAN分批遍历键名,再用MEMORY USAGE抽样定位业务前缀和大键。 - 删除后 RSS 不降可能是分配器保留页;只有逻辑占用和业务写入都持续上升,才更像数据增长。
先把 Redis 的四个内存指标放在一起看
排查从两个时间点开始:记录业务低峰和高峰,或记录处理一批删除动作前后的值。下面的命令只读取信息,不会扫描键空间:
redis-cli INFO memory | egrep 'used_memory:|used_memory_rss:|mem_fragmentation_ratio:|allocator_allocated:|maxmemory:' # 先保存逻辑占用、RSS、分配器和上限 redis-cli INFO stats | egrep 'instantaneous_ops_per_sec:|expired_keys:|evicted_keys:' # 同时记录写入压力和淘汰背景
可以把结果按这张表理解。used_memory_rss / used_memory 是碎片率的重要基础,但它不是“浪费空间百分比”,也不能跨分配器、版本和工作负载直接套一个硬阈值。
| 观察项 | 它回答什么 | 常见判断 |
|---|---|---|
used_memory | Redis 当前数据及内部分配用了多少 | 持续上升才支持“数据在增长” |
used_memory_rss | 进程实际驻留了多少内存页 | 删除后仍高,可能是分配器暂未归还 |
mem_fragmentation_ratio | RSS 与逻辑占用的关系 | 只能和时间序列及业务动作一起看 |
allocator_allocated | 分配器视角的已分配量 | 帮助区分 Redis 计数与分配器状态 |
例如删除大量缓存后,used_memory 下降、RSS 基本不动,随后新写入时 RSS 也保持平稳,这一组证据更符合“空闲块被复用”。反过来,两个指标都随键数量和写入量同步上升,才应优先查业务是否扩大了缓存范围、TTL 是否失效或 value 是否变大。

用 SCAN 和 MEMORY USAGE 找到真正变大的键
总量只能告诉你“哪里不对”,不能告诉你“谁变大了”。生产实例不要用 KEYS * 一次性阻塞遍历,而是用小批量 SCAN,配合 TYPE、MEMORY USAGE 和 TTL 做抽样:
redis-cli --scan --pattern 'session:*' | head -n 100 | while IFS= read -r key; do type=$(redis-cli TYPE "$key") # 先确认数据类型,避免按错结构处理 bytes=$(redis-cli MEMORY USAGE "$key" SAMPLES 5) # 用固定抽样近似单键占用,避免递归遍历全部元素 ttl=$(redis-cli TTL "$key") # 记录过期边界,判断增长是否来自长期不失效 printf '%s\t%s\t%s\t%s\n' "$bytes" "$ttl" "$type" "$key" done | sort -nr | head -n 20 # 先看抽样中的大键候选
这个示例只取前 100 个键,适合先确认命令和字段;正式排查应让游标完整走完,或按业务前缀分批运行并汇总。MEMORY USAGE 返回的是单键近似占用,SAMPLES 对嵌套类型影响精度;它适合排序和定位,不应被当作精确账单。
如果某个前缀的键数量明显增加,且大键候选没有变化,问题更可能是键数量或 TTL 变化;如果键数量稳定但少数 Hash、List、Set 或 ZSet 的占用持续上升,应检查集合是否没有上限、是否把过多字段塞进一个键,或是否误把明细数据放进缓存。

把碎片率、写入和删除时间对照起来
建议把每次采样保存成同一张表,而不是只在告警时看一次:
| 组合现象 | 更可能的原因 | 下一步 |
|---|---|---|
used_memory、RSS 都涨 | 数据量、value 或集合规模增长 | 按前缀和大键候选定位写入来源 |
used_memory 降、RSS 高位不动 | 删除后分配器保留已申请页面 | 观察后续写入是否复用 RSS,按峰值规划容量 |
| 键数量稳定、单键占用涨 | 集合字段或元素持续膨胀 | 检查写入边界、拆分结构和 TTL |
| 碎片率高但逻辑占用很低 | 历史峰值拉高了 RSS | 不要只按比例扩容,保留绝对值和时间序列 |
修复动作要跟证据匹配:数据真的增长时限制 TTL、控制集合大小或缩小缓存范围;只是 RSS 暂高时先观察分配器复用和峰值内存;单键膨胀时拆分结构或给写入设置上限。直接重启 Redis 可能让 RSS 下降,却会掩盖增长来源,也会引入持久化、故障切换和冷缓存成本。
常见问题
碎片率超过某个数值就必须重启吗?
不能只按一个数值决定。要同时看 used_memory、RSS、绝对内存余量、业务峰值和后续写入是否复用空闲块。
删除键后 RSS 为什么不马上下降?
底层分配器可能保留页面,供后续分配复用;这并不等同于 Redis 仍然持有同样的数据。容量规划应按历史峰值留余量。
MEMORY USAGE 能统计整个 Redis 的精确内存吗?
它用于查询单个键的近似占用,嵌套结构还会受 SAMPLES 影响。全局判断要结合 INFO memory 和分批扫描汇总。
参考资料
- Redis Memory optimization:RSS、分配器复用和碎片率的说明。
- Redis INFO:内存与运行统计字段。
- Redis SCAN、MEMORY USAGE:渐进遍历和单键占用查询。
Go HTTP Client 不复用连接时怎么检查 Response.Body 关闭
- 上一篇
- Go HTTP Client 不复用连接时怎么检查 Response.Body 关闭
- 下一篇
- Go 跟随重定向后 Authorization 为什么消失
-
- 数据库 · Redis | 16小时前 | Redis · Redis SCAN Redis游标遍历 SCAN全量查询 Redis键空间 COUNT参数
- Redis SCAN 为什么不能当作一次性全量遍历
- 236浏览 收藏
-
- 数据库 · Redis | 17小时前 |
- Redis Lua 脚本怎样通过 KEYS 和 ARGV 区分参数
- 313浏览 收藏
-
- 数据库 · Redis | 17小时前 |
- Redis ZSET 怎样查询分数区间内的成员
- 484浏览 收藏
-
- 数据库 · Redis | 17小时前 |
- Redis Hash 怎样一次读取多个字段并设置 TTL
- 104浏览 收藏
-
- 数据库 · Redis | 17小时前 |
- Redis Stream 消费组为什么重复收到消息
- 463浏览 收藏
-
- 数据库 · Redis | 17小时前 |
- Redis Stream XREAD COUNT 怎样限制单次读取消息数
- 166浏览 收藏
-
- 数据库 · Redis | 17小时前 |
- Redis Stream 怎样查看消费者组待处理消息
- 250浏览 收藏
-
- 数据库 · Redis | 17小时前 |
- Redis JSON.SET 路径不存在为什么没有创建对象
- 204浏览 收藏
-
- 数据库 · Redis | 17小时前 |
- Redis EXPIRE 怎样只在新 TTL 更短时更新
- 244浏览 收藏
-
- 数据库 · Redis | 17小时前 |
- Redis JSON.SET 怎样只在键存在时更新
- 173浏览 收藏
-
- 数据库 · Redis | 17小时前 |
- Redis CLIENT PAUSE WRITE 的主节点切换步骤与写入保护边界
- 458浏览 收藏
-
- 数据库 · Redis | 17小时前 |
- Redis GETDEL 怎样读取后删除键
- 306浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 635次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 670次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 707次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 669次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 507次使用
-
- Redis Stream XTRIM 如何避免消费组积压无限增长
- 2026-09-12 501浏览
-
- Redis AOF rewrite 期间如何判断磁盘与内存压力
- 2026-09-12 501浏览
-
- Redis RDB 和 AOF 怎么按可接受数据丢失量选择
- 2026-09-08 501浏览
-
- Redis XAUTOCLAIM 之后为什么仍有 pending:JUSTID、PEL 与消息删除边界
- 2026-08-29 501浏览
-
- Redis SET 的 GET 与 KEEPTTL 怎么一起验收:旧值返回、续期与回滚边界
- 2026-08-20 501浏览

