← 返回题目列表

Redis fork 和写时复制会带来哪些性能影响?

困难 第 32 / 36 题 更新于 2026/07/30
RedisforkCOW持久化

简化版

Redis 在 RDB、AOF rewrite 等场景会 fork 子进程。fork 本身要复制页表,实例越大耗时越明显;fork 后父进程继续写入会触发写时复制,导致额外内存占用。内存不足、透明大页、写入高峰都可能放大延迟和 OOM 风险。

详细版

Redis 持久化和重写通常采用父子进程模型:父进程继续处理请求,子进程负责生成 RDB 或重写 AOF。操作系统不会立刻复制全部数据页,而是先共享内存页;当父进程修改某页时,才复制出新页,这就是 COW。

性能影响主要有两类:第一,fork 阶段复制页表,可能造成毫秒到秒级卡顿;第二,子进程存在期间写入越多,COW 额外内存越多,可能把实例推向 OOM。

优化方向包括:预留内存、避开写高峰做 rewrite、关闭透明大页、控制大 key 和写入峰值、监控 latest_fork_usecused_memory_rssaof_rewrite_in_progress 等指标。

完整版教学

一、Redis 为什么需要 fork

Redis 要把内存数据落盘,但不能长时间停止服务。于是它常用 fork 创建子进程:父进程继续响应客户端,子进程拿 fork 时刻的数据视图去写 RDB 或重写 AOF。

这是一种“服务不中断”的设计,但不是零成本。fork 依赖操作系统机制,实例内存越大、页表越大,fork 阶段越可能产生延迟。

父进程 Redis
   |
   | fork
   v
子进程:写 RDB / rewrite AOF
父进程:继续处理 GET/SET

二、fork 成本来自页表复制

fork 时不会复制 20GB 数据本体,但需要复制进程地址空间的页表。页表越大,复制越慢。

假设 Redis 使用 40GB 内存,页大小 4KB,大致会涉及约 1000 万个页的映射关系。真实页表层级更复杂,但直觉很清楚:大内存实例 fork 成本不可忽略。

Redis 指标 latest_fork_usec 可以观察最近一次 fork 耗时。比如 50000 微秒是 50ms,已经可能影响部分请求的尾延迟。

三、COW 为什么会吃额外内存

fork 后父子进程共享物理内存页。只要父进程不改数据,子进程可以稳定读取旧视图;一旦父进程修改某页,操作系统会复制该页,让子进程继续看到旧数据,父进程写新页。

fork 后:
父进程 page A  ----共享---- 子进程 page A

父进程修改 page A:
父进程 page A'           子进程 page A

如果 rewrite 期间写入非常高,很多页面被修改,就会产生大量 COW 内存。实例本来用了 70% 内存,COW 再涨 20%,就可能接近机器上限。

四、透明大页为什么会放大问题

透明大页 THP 可能把内存页变成 2MB 级别。COW 的复制单位变大后,修改很小的数据也可能复制更大的页,额外内存和延迟都会上升。

这也是 Redis 生产环境常建议关闭 THP 的原因之一。它不是 Redis 语义问题,而是操作系统内存管理策略和 Redis fork/COW 模型之间的冲突。

因素对 fork/COW 的影响优化方向
实例内存大fork 页表复制慢控制单实例规模
写入高峰COW 内存上升避开高峰 rewrite
THP 开启COW 粒度变大关闭透明大页
大 key 多修改释放成本高治理数据模型

五、如何监控和规划容量

不能只看 used_memory,还要看 RSS、碎片、复制缓冲、AOF rewrite 状态和系统可用内存。used_memory 是 Redis 视角,RSS 是操作系统实际占用,两者差距能暴露碎片和 COW 压力。

一个简单容量思路是:Redis 常态使用不要顶满机器内存,要给 fork、COW、复制缓冲和系统预留空间。写入越高,预留越要充足。

如果实例 32GB,常态用到 30GB,再做 AOF rewrite,风险很大;如果常态控制在 18~22GB,缓冲空间会更安全。

六、常见误区与追问

  • 误区:fork 会复制整个 Redis 内存,所以一定慢到不可用。 fork 主要复制页表,数据页通过 COW 共享,但大实例仍有明显成本。
  • 误区:子进程持久化不影响父进程。 fork、COW、磁盘 IO 和内存压力都会间接影响服务。
  • 误区:只要内存没超过 maxmemory 就安全。 COW、缓冲区和 RSS 可能让进程或系统先触顶。
  • 追问:latest_fork_usec 看什么? 看最近 fork 耗时,持续升高说明实例规模或系统内存状态需要关注。
  • 追问:为什么 rewrite 要避开写高峰? 写越多触发 COW 越多,额外内存和延迟风险越高。

七、加强记忆

记忆钩子:fork 像给 Redis 拍一张内存快照,COW 像拍照后继续改房间;改得越多,为了保留照片里的旧样子,需要额外复制的东西越多。

这题要把“父子进程、页表复制、写时复制、内存预留、THP 和监控指标”讲成一条链。只说 RDB/AOF 的区别不够,面试官问的是持久化背后的操作系统成本。