Redis RDB的写时复制(COW)是操作系统层面的内存管理机制,fork瞬间仅复制页表、共享只读物理页,父进程写操作触发缺页中断并复制对应内存页,子进程始终基于fork时刻的一致性快照生成RDB文件。

Redis RDB 的写时复制(COW)本质是操作系统层面的内存管理优化,不是 Redis 自己实现的机制。它让 bgsave 能在不阻塞主线程的前提下完成快照,关键在于“共享但延迟复制”。
fork 瞬间只复制页表,不复制物理内存
当执行 bgsave 时,Redis 主进程调用 fork() 创建子进程:
- 子进程获得父进程虚拟地址空间的完整副本,但所有内存页(如哈希表、字符串对象等)仍指向同一块物理内存
- 这些共享页被标记为只读(read-only),由 MMU(内存管理单元)和内核共同维护
- 此时内存占用几乎不增加,fork 耗时极短(除非内存极大或页表复杂)
父进程写数据才触发实际复制
主线程继续处理客户端请求,一旦修改某个 key:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- CPU 尝试写入只读页 → 触发缺页异常(Page Fault)
- 内核检查该页是否为 COW 共享页(引用计数 > 1)→ 是,则分配新物理页,把原页内容拷贝过去
- 父进程页表更新,指向新页;子进程页表不变,仍指向原页
- 后续对该 key 的读写都在新页进行,不影响子进程看到的数据视图
子进程基于 fork 时刻的数据生成快照
子进程从 fork 完成那一刻起,就拥有了一个稳定的内存快照视角:
- 它遍历的是 fork 时的内存页状态,哪怕主线程之后改了 1000 次,它看到的仍是最初那一份
- 它把这份数据序列化写入临时 .rdb 文件,完成后原子替换旧文件
- 因此 RDB 文件精确反映的是 fork 系统调用执行完成的那个瞬间 的全量数据
要注意的实际影响
COW 虽巧妙,但不是零成本:
- 若主线程在 bgsave 期间大量写入,可能引发频繁页复制,额外内存开销 ≈ 修改页数 × 4KB
- 64GB 实例 fork 可能卡住几百毫秒——这不是 COW 的问题,而是 fork 本身复制页表的开销
- 可通过
INFO stats查看latest_fork_usec,评估是否需拆实例或调优

















