Redis的RDB(Redis DataBase)持久化是一种将Redis内存中的数据快照(snapshot)定期保存到磁盘上的持久化机制。
RDB的执行原理:
-
触发条件:
- RDB持久化通过定时器和事件处理来触发。可以通过配置文件指定触发持久化操作的条件,比如达到一定的时间间隔或者写入操作的数量。
-
生成快照:
- 当触发条件满足时,Redis会fork出一个子进程,该子进程负责将内存中的数据写入到一个临时的RDB文件中。为避免阻塞主进程,子进程将会使用Copy-On-Write机制,通过写时复制的方式来避免多进程同时写一个资源可能带来的不一致性。
-
生成RDB文件:
- 在生成快照的过程中,写操作会被记录在一个缓冲区,以确保生成的RDB文件包含了快照生成时刻的所有写操作。一旦快照生成完毕,Redis会进行原子性地将临时的RDB文件移动到指定位置(或替换已有的RDB文件),从而完成持久化。
-
加载RDB文件:
- 当Redis重新启动时,可以通过加载RDB文件来还原内存中的数据。Redis会先读取RDB文件的元数据,再利用子进程fork和Copy-On-Write机制,将数据恢复到内存中。
bgsave的执行过程 :
当执行BGSAVE命令时,Redis会创建一个子进程来执行持久化操作,而不会阻塞主线程的正常操作。以下是BGSAVE开始时fork主进程的总体过程:
-
接收BGSAVE命令: 当Redis接收到BGSAVE命令时,它将在操作系统级别执行以下步骤:
-
创建子进程:
- Redis调用fork()系统调用,创建一个子进程,该子进程是父进程的完整副本,包括内存、文件描述符等信息。子进程开始时,它的内存内容与主进程相同。
-
Copy-On-Write机制:
- 由于子进程共享内存空间和文件描述符,为了避免复制整个内存空间,操作系统使用Copy-On-Write(写时复制)机制。这意味着除非子进程试图修改与父进程共享的内存空间,否则它们会共享相同的内存页。
-
执行BGSAVE操作:
- 子进程开始执行BGSAVE操作,遍历Redis内存中的数据结构,生成内存快照,并将其写入到临时的RDB文件中。
-
持久化操作:
- 在持久化操作完成后,子进程将临时的RDB文件保存到指定位置,通常是将其替换已有的RDB文件。
-
子进程退出:
- BGSAVE操作完成后,子进程将退出。如果持久化操作完成成功,父进程会继续执行正常的操作。
总的来说,BGSAVE开始时fork主进程的过程包括创建子进程、使用Copy-On-Write机制避免复制整个内存空间、执行持久化操作,最后子进程退出。这种方式可以确保持久化操作在后台异步执行,而不会阻塞主线程的正常操作。