bgsave时数据拷贝的过程

在 Redis 执行 RDB 快照时,BGSAVE 命令会创建一个子进程来执行持久化任务。具体来说,Redis 使用了**写时复制(Copy-On-Write, COW)**机制来避免阻塞主进程,并且减少内存开销。

BGSAVE 的工作原理:

  1. 当 Redis 接收到 BGSAVE 命令时,Redis 主进程会创建一个子进程,子进程负责将当前的内存数据写入到 RDB 文件中。

  2. 写时复制(Copy-On-Write, COW):在子进程生成的过程中,Redis 并不会立即复制整个内存数据。相反,子进程与父进程共享相同的内存页。当父进程(Redis 主进程)继续处理请求并修改数据时,只有被修改的部分内存(页面)才会被复制。这就是写时复制机制的关键所在:只有在写操作发生时,才会复制对应的数据

    • 共享内存页:父进程和子进程在生成时共享所有内存页。
    • 写时复制:当父进程修改某个数据时,这个数据所在的内存页会被复制一份给父进程,子进程仍然可以访问原来的内存页,而父进程访问修改后的内存页。
  3. 子进程使用共享的内存页将快照数据写入 RDB 文件,写入完成后子进程退出,RDB 文件生成完成。

写时复制的优势:

  • 性能影响最小化:通过使用 COW,主进程可以继续响应客户端请求,而不需要阻塞整个进程的执行。只有当需要修改数据时,才会触发内存页的复制,因此对性能的影响较小。
  • 节省内存:由于主进程和子进程共享大部分未被修改的数据,系统内存的占用得到有效控制。只有修改的数据页才会额外占用内存。

例子:

假设 Redis 当前有 1GB 的数据,当执行 BGSAVE 时,主进程创建子进程。如果没有任何修改发生,父子进程共享同一份 1GB 数据,而不需要额外复制。当父进程修改某个 key 时,才会触发这部分数据的复制。

总结:

BGSAVE 执行时,子进程并不会直接拷贝整个内存的数据,而是通过写时复制(COW)机制共享内存,只有当主进程修改数据时才会将被修改的部分内存复制一份给主进程。这种机制确保了持久化操作不会阻塞主进程,并且在大多数情况下节省了内存。