redis子进程不立即复制内存页,因fork后共享父进程只读物理页;仅当子进程自身写入(如aof重写构造命令)或父进程修改数据时,才触发缺页中断并复制对应页。

Redis子进程为什么不会立即复制内存页
因为fork()后子进程共享父进程的物理页,且这些页被标记为只读(read-only)。子进程首次尝试写入某页时,CPU检测到权限冲突,触发缺页中断——这不是错误,而是内核接管并分配新物理页的正常机制。
缺页中断发生在子进程写入哪类数据时
仅当子进程真正修改内存内容时才触发,比如RDB子进程在序列化过程中对key-value结构做遍历、编码、写入临时文件缓冲区等操作。注意:bgsave子进程本身不改业务数据,它只读取;但AOF重写子进程会构造新命令流,这部分内存操作会触碰大量页。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 只读遍历(如RDB快照)通常不触发COW,除非遇到内存映射页或内核内部缓存更新
- AOF rewrite子进程需组装命令字符串、计算校验和、维护临时缓冲区,这些都会写内存 → 触发缺页中断 → 分配新页
- 如果父进程在子进程运行期间高频修改数据(如
HSET、INCR),那些被改写的页会立刻被COW复制,子进程后续读取的是副本,不再触发新缺页
为什么缺页中断不影响父进程响应
缺页中断是子进程自身的上下文行为,由内核在子进程时间片内处理。父进程的页表和物理页未被改动,其指令流、网络事件循环、命令解析完全不受干扰。真正影响父进程的是fork()调用本身的同步开销,不是后续的缺页。
-
latest_fork_usec统计的是fork系统调用耗时,包含页表复制、VMA扫描等,与缺页无关 - 子进程缺页时父进程仍在执行客户端命令,但若此时父进程RSS飙升(因COW复制),可能间接导致OOM Killer介入
- 监控中看到
mem_fragmentation_ratio正常但used_memory_rss翻倍,基本可锁定是COW引发的缺页分配行为
容易被忽略的关键点
缺页中断是否频繁,取决于子进程“主动写内存”的强度,而不是父进程写入量。很多人误以为只要父进程不动,子进程就安全——其实AOF rewrite子进程自己就是高写负载进程,它的缺页行为是设计使然,无法绕过,只能通过控制其执行时机(避开业务高峰)、限制单次rewrite数据量(用aof-rewrite-incremental-fsync yes)、以及确保足够物理内存来缓冲。










