深入理解Redis的持久化

 RDB是将当前数据生成快照保存到硬盘上。

 

RDB的工作流程:

1. 执行bgsave命令,Redis父进程判断当前是否存在正在执行的子进程,如RDB/AOF子进程,如果存在bgsave命令直接返回。

2. 父进程执行fork操作创建子进程,fork操作过程中父进程被阻塞。

3. 父进程fork完成后,bgsave命令返回“* Background saving started by pid xxx”信息,并不再阻塞父进程,可以继续响应其他命令。

4. 父进程创建RDB文件,根据父进程内存生成临时快照文件,完成后对原有文件进行原子替换。根据lastsave命令可以获取最近一次生成RDB的时间,对应info Persistence中的rdb_last_save_time。

5. 进程发送信号给父进程表示完胜,父进程更新统计信息。

 

对于大多数操作系统来说,fork都是个重量级操作,虽然创建的子进程不需要拷贝父进程的物理内存空间,但是会复制父进程的空间内存页表。

子进程通过fork操作产生,占用内存大小等同于父进程,理论上需要两倍的内存来完成持久化操作,但Linux有写时复制机制(copy-on-write)。父子进程会共享相同的物理内存页,当父进程处理写请求时会把要修改的页创建副本,而子进程在fork操作过程中会共享父进程的内存快照。

 

触发机制:

1. 手动触发

   包括save和bgsave命令。

    因为save会阻塞当前Redis节点,所以,Redis内部所有涉及RDB持久化的的操作都通过bgsave方式,save方式已废弃。

2. 自动触发

    1> 使用save的相关配置。

    2> 从节点执行全量复制操作。

    3> 执行debug reload命令。

    4> 执行shutdown命令时,如果没有开启AOF持久化功能则会自动执行bgsave。

 

RDB的优缺点:

优点:

1. RDB是一个紧凑压缩的二进制文件,代表Redis在某个时间点上的数据快照,适合备份,全量复制等场景。

2. 加载RDB恢复数据远远快于AOF的方式。

缺点:

没办法做到实时持久化/秒级持久化,因为bgsave每次运行都要执行fork操作创建子进程,属于重量级操作,频繁执行成本过高。

 

RDB的相关参数

复制代码
save 900 1 save 300 10 save 60 10000  stop-writes-on-bgsave-error yes  rdbcompression yes  rdbchecksum yes  dbfilename dump.rdb  dir ./
复制代码

 

其中,前三个参数的含义是,

复制代码
#   after 900 sec (15 min) if at least 1 key changed #   after 300 sec (5 min) if at least 10 keys changed #   after 60 sec if at least 10000 keys changed
复制代码

 

如果要禁用RDB的自动触发,可注销这三个参数,或者设置save ""。

stop-writes-on-bgsave-error:在开启RDB且最近一次bgsave执行失败的情况下,如果该参数为yes,则Redis会阻止客户端的写入,直到bgsave执行成功。

rdbcompression:使用LZF算法压缩字符对象。

rdbchecksum:从RDB V5开始,在保存RDB文件时,会在文件末尾添加CRC64校验和,这样,能较容易的判断文件是否被损坏。但同时,对于带有校验和的RDB文件的保存和加载,会有10%的性能损耗。

dbfilename: RDB文件名。

dir:RDB文件保存的目录。

 

RDB的相关变量

复制代码
127.0.0.1:6379> info Persistence # Persistence loading:0 rdb_changes_since_last_save:0 rdb_bgsave_in_progress:0 rdb_last_save_time:1538447605 rdb_last_bgsave_status:ok rdb_last_bgsave_time_sec:0 rdb_current_bgsave_time_sec:-1
                        
关键字:
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信