因为top或ps将父子进程共享物理页重复计入RSS,造成内存翻倍假象;实际仅在写入时触发COW复制,info中used_memory_rss/used_memory>2.0且min_flt飙升可证实此现象。

为什么bgsave会让top或ps显示内存翻倍
这不是 Redis 真的用了两倍内存,而是 Linux fork() 后 COW 机制下 RSS 统计方式导致的视觉假象。内核把父子进程共享的物理页都计入各自 RSS,但实际物理内存并未复制——直到某一方真正写入某页,才会触发复制(minor page fault)。
-
info memory中的used_memory_rss是真实 RSS 总和,而used_memory才是 Redis 数据实际占用的虚拟内存 - 如果
used_memory_rss / used_memory > 2.0,说明 COW 开销已显著,可能伴随 minor page fault 飙升 - 观察
/proc/$(pgrep redis-server)/stat的第24字段(min_flt)可验证:bgsave 期间该值每秒增长超 10k 就属异常
哪些配置会让bgsave内存开销真正变大
真正让物理内存激增的,不是 fork 本身,而是后续 COW 和内核内存管理行为被错误配置放大:
- 透明大页(THP)启用:
/sys/kernel/mm/transparent_hugepage/enabled为[always]或madvisable时,khugepaged 会持续扫描 Redis 内存试图合并页,加剧页分裂和临时映射开销 -
vm.overcommit_memory=2且vm.overcommit_ratio设置过低:fork 后子进程首次写入时可能触发直接内存回收,甚至 OOM killer 干预 - Redis 自身配置:
activerehashing yes在 bgsave 期间仍活跃,会额外申请哈希表扩容内存,与 COW 叠加压力
bgsave期间内存暴涨但没OOM,是不是就安全了
不一定。即使没触发 OOM,以下现象已表明系统处于高风险状态:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 子进程
write()被阻塞在ext4_writepages或wait_on_page_bit—— 用cat /proc/$(pgrep redis-server)/stack可见 -
iostat -x 1显示await > 50ms且avgqu-sz > 1,说明 I/O 队列积压,子进程 hang 住,间接拖慢父进程调度 -
vmstat 1中pgmajfault不明显,但pgpgout持续上升,说明内核正在主动回收 page cache,为 bgsave 腾写缓存空间
怎么快速验证是不是 THP 导致的内存异常
THP 是 Redis 生产环境最常被忽略的元凶,验证和修复极简单:
- 查当前状态:
cat /sys/kernel/mm/transparent_hugepage/enabled,输出含[always]即启用 - 临时禁用:
echo never > /sys/kernel/mm/transparent_hugepage/enabled - 同步禁用后台整理:
echo never > /sys/kernel/mm/transparent_hugepage/defrag - 重启后失效?把上面两行加到
/etc/rc.local或 systemd drop-in 的ExecStartPre里
做完后观察下一次 bgsave 的 used_memory_rss 增幅,通常能回落 30%–60%。

















