在 Redis 中,可以通过执行
BGSAVE
命令来使用 RDB 持久化方式进行数据备份。BGSAVE
命令不会阻塞主进程的正常运行,并且会在后台创建一个子进程来完成数据备份的过程。
流程图:
- 执行 BGSAVE 命令。
- Redis 主进程创建一个子进程,通过调用 fork 函数来复制父进程的内存地址空间。
- 子进程开始遍历全局数据库,将数据库的状态写入到内存缓冲区中。
- 子进程将内存缓冲区的内容写入到磁盘文件中,这个过程可能会非常耗时。
- 子进程完成 RDB 文件的写入操作之后,向 Redis 主进程发送一个信号,通知备份操作已经完成。
- Redis 主进程在接收到子进程发送的信号后,持久化操作结束。
在 RDB 的
BGSAVE
命令中,主进程在执行fork
函数复制子进程的同时还会继续接收和处理客户端发送的命令请求,而这些写入操作可能会导致数据库状态发生变化。因此,在备份期间必须禁止任何写入操作,否则备份出来的结果可能并不是一个一致性的数据快照。
数据一致性:
执行 RDB 持久化过程中,在 fork
子进程时,主进程会尝试锁定自身的写操作,以保证在保存 RDB 快照期间不会出现数据不一致的情况。在持久化操作中,主进程会将所有写入操作缓存起来,直到快照生成的过程结束后,再将缓存中的写入操作进行回放。
在 RDB 持久化过程中,主进程会将所有写操作缓存起来,并暂停对外提供写入服务,直到生成 RDB 文件的过程结束后才会将缓存中的写入操作进行回放。如果在持久化期间有新的写操作,则这些写入操作将被追加到写操作缓存中并在 RDB 文件生成完后进行回放。
在 RDB 生成过程中继续进行写操作,这些写入操作就不能被缓存起来,因此可能会导致生成的 RDB 文件缺少这些写入操作的内容,从而造成数据丢失或不一致的情况。此外,由于主进程在这段时间内暂停了对外提供写入服务,因此可能会出现写入请求被阻塞的现象,从而影响服务的响应速度和性能。
因此,在 RDB 持久化过程中,建议尽量避免对主进程进行写入操作,以保证所生成的 RDB 文件是完整和可靠的。