Redis 内存泄漏最明显、最常见的信号,就是在业务相对稳定时,used_memory 仍然持续单边上涨。排查时应结合 INFO memory 做周期性监控,借助 MEMORY STATS 检查客户端缓冲区是否异常膨胀,通过 KEYS 扫描验证 TTL 设置是否合理,并结合 RDB 快照对比,识别隐藏的数据结构膨胀问题。

看 used_memory 是否持续单向上涨
判断 Redis 是否存在内存泄漏,最直观的依据并不只是“内存是否占满”,而是在业务数据规模基本稳定、没有新功能发布、TTL 配置正常的前提下,used_memory 依然在数小时甚至数天内持续呈现**单调递增**趋势。建议定时(如每 10 分钟)执行 redis-cli info memory 进行采集,重点关注并对比:used_memory、used_memory_peak、used_memory_rss。如果 used_memory 持续刷新峰值,而来自 MEMORY STATS 的 dataset.bytes 基本没有明显变化,就可以初步判断:增长的并非业务数据本身,而是 Redis 内部额外开销在不断累积。
查 clients.normal 和 replication.buffer 是否异常膨胀
很多被误判为“Redis 内存泄漏”的场景,本质上其实是客户端缓冲区堆积。例如某个慢消费者没有及时消费 pub/sub 消息,或者从节点网络延迟、卡顿,导致主节点持续堆积复制缓冲区。此时可执行 MEMORY STATS,重点检查:clients.normal、clients.replica、replication.buffer 是否明显高于日常基线(比如平时仅 2MB,突然升到 200MB)。这类问题通常不会触发 key 过期或淘汰机制,但会让 total.allocated 持续上升,从监控表现上看与真正的内存泄漏非常相似,因此是 Redis 性能监控中必须重点排查的项目。
对比 keys.count 和实际业务生命周期
Redis 并不会立刻清理所有已过期但尚未被访问的 key,而是采用惰性删除与定期抽样结合的机制。因此,keys.count 长时间只增不减并不罕见,尤其常见于高频写入临时 session、验证码等短生命周期 key 的业务场景。可以使用 redis-cli --scan --pattern "*session*" | wc -l 快速估算可疑前缀的数量,再结合实际业务规则进行验证:如果这些 key 理论上应在 30 分钟后自动消失,但扫描后却发现大量 TTL 为 -1,或者剩余过期时间仍大于 2 小时,就很可能是代码中漏掉了 EXPIRE,或者错误使用了 SET 而不是 SETEX。这类 TTL 配置问题,往往正是 Redis 内存持续增长的重要隐患。
用 rdb -c memory 抓快照做横向对比
单次执行 INFO 只能看到某一时刻的静态状态,无法完整反映内存变化趋势。要更准确地判断 Redis 是否真的存在内存泄漏风险,还需要结合 RDB 快照做对比分析:例如在凌晨业务低峰期执行一次 dump.rdb,间隔 12 小时后再导出一次。随后使用 rdb -c memory 分别导出为 CSV 文件,并按 size_in_bytes 排序。排查时应重点关注那些键名相同、但 size 增长超过 50% 的条目。很多情况下,这类增长并不是 key 数量变多,而是 list、set 等数据结构持续执行 LPUSH/SADD,却缺少对应的 LTRIM/SPOP 清理操作,从而引发隐性膨胀。相比单纯的键数量上涨,这种数据结构层面的持续扩张往往更危险,也更容易被忽视。
mem_fragmentation_ratio 偏高,可能只是 jemalloc 分配器的正常行为;used_memory_rss 高于 used_memory,也不一定就能直接判定为泄漏。真正关键的是,把内存增长趋势与业务操作、客户端状态、key 生命周期放在一起交叉分析。只有这样,才能更准确地通过 Redis 性能监控发现内存泄漏隐患,避免把排查时间浪费在内存碎片率或缓冲区假象上。