Redis的RDB(Redis Database)是其数据持久化机制之一,通过快照的形式将内存中的数据保存到磁盘上,以实现数据备份和恢复。下面是关于Redis RDB的源码解析概要:
触发RDB快照的方式
-
手动触发:通过执行
SAVE
命令可以手动触发RDB快照生成。这个命令会导致Redis主进程阻塞,直到RDB文件生成完成。 -
自动触发:根据配置文件中的
save
指令,Redis会根据最近的数据更改频率自动触发RDB快照,例如save 900 1
表示如果900秒内至少有1个键被更改,则自动触发RDB。 -
BGSAVE:执行
BGSAVE
命令会在后台异步生成RDB文件,通过fork子进程来完成,这样主进程可以继续处理客户端请求,不会造成阻塞。
RDB保存流程
-
Fork子进程:当使用
BGSAVE
命令时,Redis会通过系统调用fork()
创建一个子进程。子进程继承了父进程的内存数据,但在此时,父子进程共享相同的物理页面(得益于Linux的写时复制COW机制)。 -
数据序列化:子进程负责实际的RDB文件创建,调用
rdbSave()
函数开始序列化进程。这个过程中,内存中的数据结构会被转换成一系列的RDB格式的指令序列,并写入到一个临时文件中。 -
文件写入与同步:使用
rio
模块(Redis I/O模块)进行文件操作,序列化后的数据被写入到临时文件,并在适当的时候调用fflush
、fsync
等系统调用来确保数据安全地写入磁盘。 -
文件命名与替换:一旦RDB文件生成完毕,临时文件会被重命名为最终的RDB文件名,并替换旧的RDB文件(如果存在)。同时,相关统计信息如
server.dirty
(自上次RDB以来的数据变更次数)会被清零。 -
压缩与校验:RDB文件可以配置是否进行压缩(通过
rdbcompression
配置),并且文件头部包含magic number和版本号,用于标识文件类型和兼容性检查。
关键源码文件
- rdb.c:包含了生成RDB文件的核心函数,如
rdbSave()
和相关序列化逻辑。 - networking.c:处理
SAVE
和BGSAVE
命令的网络请求。 - redis.h/redisServer.h:定义了Redis服务器和客户端状态的结构体,包括与RDB相关的标志位和配置。
- rio.c:Redis的I/O操作抽象层,支持高效的数据读写。
深入学习RDB的源码,应重点关注上述文件中的函数实现,特别是RDB的序列化逻辑、文件操作和进程管理相关部分,理解Redis如何高效、安全地将内存数据转化为持久化文件。