680 字
3 分钟
Redis 删除数据后为什么内存不下降?如何理解内存碎片?
  1. 1Redis 系列导读:知识地图、必会主线与复习顺序
  2. 2Redis 中常见的数据类型有哪些?
  3. 3Redis 通常应用于哪些场景?
  4. 4Redis为什么这么快?
  5. 5Redis 常用的过期时间、删除 Key 命令有哪些?
  6. 6Redis 的过期 Key 是如何被删除的?
  7. 7Redis 内存满了怎么办?有哪些淘汰策略?
  8. 8缓存穿透、击穿、雪崩的区别与解决方案
  9. 9Redis 如何保证缓存与数据库的数据一致性?
  10. 10Redis 的持久化机制有哪些?
  11. 11Redis 主从复制的完整流程是什么?
  12. 12Redis 的哨兵机制是什么?
  13. 13Redis Cluster 模式与 Sentinel 模式的区别是什么?
  14. 14Redis 支持事务吗?如何实现?
  15. 15Redis 中如何实现分布式锁?
  16. 16Redis 的 Lua 脚本功能是什么?如何使用?
  17. 17如何解决 Redis 中的热点 Key 问题?
  18. 18Redis BigKey 有什么危害?如何发现和治理?
  19. 19为什么 Redis 设计为单线程?6.0 版本为何引入多线程?
  20. 20Redis 的 LRU 和 LFU 有什么区别?
  21. 21Redis 数据类型和底层编码有什么区别?
  22. 22Redis 中跳表的实现原理是什么?
  23. 23Redis 的 ZSet 为什么使用跳表,而不是平衡树?
  24. 24Redis 的 RDB 快照如何生成?为什么会有写时复制?
  25. 25Redis 的 AOF 刷盘和重写有什么区别?
  26. 26Redis 断线后如何通过 PSYNC 部分重同步?
  27. 27Redis 主从切换为什么会丢数据?WAIT 能解决吗?
  28. 28Redis 集群会出现脑裂问题吗?
  29. 29Redisson 看门狗(watch dog)机制了解吗?
  30. 30Redis Cluster:哈希槽、Gossip 与故障转移
  31. 31Redis Pipeline 为什么能提高吞吐?能保证原子性吗?
  32. 32Redis 的 SCAN 和 KEYS 有什么区别?
  33. 33Redis 变慢时如何排查?SLOWLOG 能看到所有耗时吗?
  34. 34Redis 和 MySQL 有什么区别?
  35. 35Redis 为什么使用 SDS,而不是 C 字符串?
  36. 36Redis 的哈希表如何处理冲突和渐进式 rehash?
  37. 37Redis Cluster 的 MOVED 和 ASK 重定向有什么区别?
  38. 38Redis Cluster 为什么会报 CROSSSLOT?Hash Tag 怎么用?
  39. 39Redis 如何实现限流?固定窗口和滑动窗口怎么选?
  40. 40Redis Stream 如何保证消息消费?ACK 和 PEL 是什么?
  41. 41Redis 删除数据后为什么内存不下降?如何理解内存碎片?本文

Redis 删除 Key 后,逻辑数据占用可能下降,但进程 RSS 不一定立即减少。内存分配器可能保留空闲空间等待复用,页内仍有其他对象也会阻止整页归还给操作系统。内存碎片、分配器缓存、复制缓冲和 COW 峰值应分开判断。

先分清观察指标#

INFO memory 中 used_memory 反映 Redis 分配的内存统计,used_memory_rss 表示操作系统视角的驻留内存。mem_fragmentation_ratio 大致用 RSS 与使用量比较,但还会受到进程其他开销影响,不能直接理解为“全都是可以回收的碎片”。较小实例因固定开销占比大,比例可能很高,却没有严重容量问题。

还可结合 allocator_allocated、allocator_active、allocator_resident 等分配器指标和相应差值分析,具体字段以运行版本为准。比值小于 1 也不是自动变好,可能与部分内存不在 RAM、swap 等情况有关,需要结合系统指标。

为什么反复写删会产生碎片?#

不同大小对象交替分配和释放,可能留下难以被新对象利用的空隙。一个内存页有些对象被删除、另一些仍活着时,整页还不能释放。若先装载巨大数据集再大量删除,分配器保留的空间也可能让 RSS 长期高于当前数据量。

支持的版本和分配器配置下,可以评估主动碎片整理。它通过搬移对象等方式尝试提高内存利用率,会消耗 CPU,并非一开就完全回收。MEMORY PURGE 也不是保证释放任意碎片的命令。生产环境应通过观测判断收益,避免把重启当成日常内存治理。

常见追问#

碎片率 1.5 就一定要重启吗?#

不能只看一个阈值。要看绝对多出的字节量、实例大小、分配器指标、剩余内存与延迟目标,再选择治理措施。

maxmemory 能限制整个 Redis 进程 RSS 吗?#

不能把它当进程总内存硬上限。分配器、后台任务、复制与 AOF 缓冲及 COW 还会产生额外需求,需要物理内存余量。

BGSAVE 期间内存上涨一定是碎片吗?#

不一定,主进程修改共享页会触发 COW。应结合持久化子进程与 COW 指标确认,避免错误调整淘汰策略。

拆成很多小 Key 能完全消除碎片吗?#

不能。小 Key 会增加对象头、字典和 Key 名等开销,也可能造成新的分配模式;应结合业务访问与内存测量选择数据模型。

Redis 删除数据后为什么内存不下降?如何理解内存碎片?
https://blog.xqcherry.top/posts/interview/redis/redis-memory-fragmentation/
作者
xqcherry
发布于
2026-10-12
许可协议
CC BY-NC-SA 4.0