Redis提供了2个不同形式的持久化策略:

 

  • RDB (redis database)
  • AOF (append of file)

这篇文章则记录一下我学习RDB过程中的一些笔记,分享给大家。

目录

RDB 模式

1  Redis何时创建rdb文件以及何时载入

1.1  SAVE和BGSAVE命令     

1.2  通过配置文件配置RDB策略

1.3  Redis何时载入rdb文件

2  原理实现

3  RDB的优缺点


RDB 模式

rdb是redis默认的持久化策略,在RDB模式下,可以将redis在内存中的数据库状态保存到磁盘里面(以内存快照的形式),避免数据意外丢失。

RDB持久化功能既可以手动执行,也可以通过配置文件定期执行。

RDB通过生成一个经过压缩的二进制文件,保存数据库状态,可以通过该文件进行还原。

1  Redis何时创建rdb文件以及何时载入

        redis创建rdb文件有两种方式:

                ①手动执行SAVE或BGSAVE时;

                ②满足配置条件进行rdb持久化时;

1.1  SAVE和BGSAVE命令     

        SAVE命令和BGSAVE命令都可以生成RDB文件,这两种命令以不用的方式调用 rdbSave 函数完成RDB文件的生成。

        SAVE命令是阻塞式的创建RDB文件,阻塞Redis服务器进程,直到RDB文件创建完毕;

        BGSAVE则会fork一个子进程,由子进程负责创建RDB文件,服务器进程(父进程)继续处理命令;

         通过以下伪代码可以看出两个命令的差别:

def SAVE():
    rdbSave()

def BGSAVE():
    # 创建子进程
    pid = fork()
    
    if pid == 0:
        # 子进程负责创建RDB文件
       rdbSave()
       # 完成后向父进程发送信号
       signal_parent()
    elif pid > 0:
       # 父进程继续处理请求,饼通过轮询等待子进程信号
       handle_request_and_wait_signal()
    else:
       # 处理出错情况
       handle_fork_error() 

        SAVE命令执行时:服务器处于阻塞状态,所有客户端请求都会被拒绝。

        BGSAVE执行时:由于保存工作是由子进程执行,在BGSAVE过程中redis服务器仍然可以处理客户端请求,但是处理SAVE、BGSAVE、BGREWRITEAOF会有所不同:

  • BGSAVE执行过程中,服务器拒绝SAVE请求,避免产生2个rdbSave()调用,防止产生竞争条件
  • BGSAVE执行过程中,服务器拒绝BGSAVE请求,避免产生2个rdbSave()调用,防止产生竞争条件
  • BGSAVE和BGREWRITEAOF(AOF重写命令,后面详细说明)命令不能同时执行,如果BGSAVE执行中,BGREWRITEAOF命令会延后到BGSAVE命令执行完毕后执行。如果BGREWRITEAOF执行中,BGSAVE则会被服务器拒绝。因为这两个指令都是由子进程完成,并发出2个子进程并同时执行大量磁盘写入操作,影响性能。

1.2  通过配置文件配置RDB策略

        Redis允许用户通过配置文件(一般情况下在/etc/redis/redis.conf)修改save选项,定期自动执行一次BGSAVE命令。且可以同时设置多个保存条件,只要满足任意一个条件,就会执行BGSAVE。

        意思是服务器在 seconds 秒以内完成 changes 次修改,则会自动执行一次RDB持久化。下面是REDIS在执行RDB持久化时的打印日志:

        我添加了一项 SAVE 30 5 的策略,30秒内服务器发生5次数据修改,则进行一次RDB。如上图。

1.3  Redis何时载入rdb文件

        RDB文件载入是在服务器启动的时候自动进行的,当服务器启动时检测到RDB文件(默认当前目录下的rdb文件)就会自动载入。以下是redis-server启动时打印日志,其中DB loaded from disk:...就是成功载入RDB文件后打印的。RDB文件载入时,服务器一直会处于阻塞状态,直到完成。

         RDB文件名默认为dump.rdb,可以通过配置文件 rdbfile修改:

         RDB文件默认保存目录为服务器启动目录(建议修改为绝对路径),可以通过配置dir修改:

2  原理实现

        redisServer结构保存了一个saveparams属性:

        

        saveparms是一个数组,每个元素都是saveparam结构,每个saveparam结构保存了一个save选项保存条件

        比如默认条件下,服务器状态的saveparms数组样子如下:

        除了saveparams数组外,redisServer结构还保存了一个dirty计数器和一个lastsave属性。dirty计数器记录距离上次执行SAVE或BGSAVE后,服务器修改了多少次;lastsave属性是一个unix时间戳,记录了上次成功SAVE/BGSAVE的时间。

        当服务器成功执行一个数据库修改命令以后,会对dirty计数器进行更新。如

        dirty计数器的值会+1

        dirty计数器的值会+3

        redis服务器周期性操作函数severCron默认每隔100毫秒执行一次,该函数用户对正在运行的服务器进行维护,其中一项工作就是检查save选项设置保存的条件是否满足,如果满足就执行BGSAVE命令。

         举个例子,redis-server的当前状态如下:

        当时间到1378270800+301=1378271101之后,服务器将自动执行BGSAVE命令,因为saveparams数组的第二个保存条件(300秒之内有10次修改)已经被满足。

3  RDB的优缺点

        优点:

                ①由于rdb文件是二进制存储的,节省磁盘空间。

                ②由于rdb保存的是数据库状态快照,恢复速度快。

        缺点:

                ①虽然redis在fork时使用了写时拷贝技术,但是如果数据庞大时还是比较消耗性能

                ②由于rdb的save策略,如果redis服务器意外宕机,会导致最后一次保存快照后的修改数据丢失。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐