Redis之两种持久化机制:RDB和AOF

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/carson0408/article/details/84398262

1.快照持久化(RDB):只适用于那些即使丢失一部分数据也不会造成问题的应用程序

快照将被写入dbfilename选项指定的文件里面,并储存在dir选项的路径上面。如果在新的快照文件创建完毕之前,Redis、系统或者硬件这三者之中的任意一个崩溃了,那么Redis将丢失最近一次创建快照之后写入的所有数据。

1.创建快照的办法

1.客户端可以通过向Redis发送BGSAVE命令来创建一个快照。Redis会开一个子进程负责将快照写入硬盘,而父进程继续处理命令请求。

2.客户端可以通过向Redis发送SAVE命令来创建一个快照,接到SAVE命令的Redis服务器在快照创建完毕之前将不再响应任何其他命令。通常只有在没有足够内存执行BGSAVE命令时,才会使用这个命令。

3.如果用户设置了save配置选项,比如save 60 10000,从Redis最近一次创建快照之后算起,当"60秒内有10000次写入"满足时,即触发执行BGSAVE命令。

4.当Redis通过SHUTDOWN命令接收关闭关闭服务器的请求或者接收到标准TERM信号时,会执行一个SAVE命令,阻塞所有客户端,不再执行客户端发送的任何命令,并在SAVE命令执行完毕之后关闭服务器。

5.当一个Redis服务器连接另一个Redis服务器,并向对方发送SYNC命令来开始一次复制操作时,如果主服务器目前没有在执行BGSAVE操作,或者主服务器并非刚刚执行完BGSAVE操作,那么主服务器就会执行BGSAVE命令。

2.BGSAVE命令执行时的服务器状态

在BGSAVE命令执行期间,服务器可以继续处理除SAVE、BGSAVE、BGREWRITEAOF以外的命令。客户端发送的SAVE命令会被服务器拒绝,避免父子进程同时执行rdbSave调用,防止产生竞争条件。客户端发送的BGSAVE也会被拒绝。BGREWRITEAOF命令会被延迟到BGSAVE命令执行完毕之后执行。

3.自动间隔性保存

saveparams数组用于存储保存条件,dirty计数器记录距离上一次成功执行SAVE命令或者BGSAVE命令之后,服务器对数据库状态(服务器中的所有数据库)进行了多少次修改(包括写入、删除、更新等操作)。lastsave属性是一个UNIX时间戳,记录了服务器上一次成功执行SAVE命令或者BGSAVE命令的时间。

4.serverCron函数

Redis的服务器周期性操作函数serverCron默认每隔100ms就会执行一次,该函数用于对正在运行的服务器进行维护,检查所设置的保存条件是否已经满足。

5.RDB文件

RDB文件的最开头是REDIS五个字符。程序可以在载入文件时,快速检查所载入的文件是否是RDB文件。db_version代表RDB版本。database部分包含着零个或任意多个数据库。EOF为标记位,标志着RDB文件正文内容的结束。check_sum是一个8字节长的无符号整数,保存着一个校验号,根据前面四个部分计算得来,会进行校验。

SELECTED常量的长度为1字节,表示接下来是一个数据库号码。db_number保存着一个数据库号码。key_value_pairs部分保存了数据库数据库中所有键值对数据。

6.总结

1.RDB文件用于保存和还原Redis服务器所有数据库中的所有键值对数据。

2.SAVE命令由服务器进程直接执行保存操作,所以该命令会阻塞服务器。

3.BGSAVE命令由子进程执行保存操作,所以该命令不会阻塞服务器。

4.服务器状态中会保存所有用save选项设置的保存条件,当任意一个保存条件被满足时,服务器会自动执行BGSAVE命令。

5.RDB文件是一个经过压缩的二进制文件,由多个部分组成。

6.对于不同类型的键值对,RDB文件会使用不同的方式来保存它们。

2.AOF

        开启AOF持久化的配置,如下所示:

AOF持久化功能的实现可以分为命令追加、文件写入、文件同步三个步骤。

1.命令追加

当AOF持久功能处于打开状态时,服务器在执行完一个写命令之后,会以协议格式将被执行的写命令追加到服务器状态的aof_buf缓冲区的末尾。

2.文件写入与文件同步

当用户调用write函数,将一些数据写入到文件的时候,操作系统通常会将写入数据暂时保存在一个内存缓冲区里面,等到缓冲区的空间被填满、或者超过了指定的时限之后,才真正地将缓冲区中的数据写入到磁盘里面。

3.AOF文件的载入与数据还原

1.创建一个不带网络连接的伪客户端,因为Redis命令只能在客户端上下文执行。

2.从AOF文件中分析并读取出一条写命令。

3.使用伪客户端执行被读出的写命令。

4.AOF重写

AOF重写即根据当前数据库状态转化为指令追加到AOF文件中,省略了中间过程,因此减少了指令,减少了AOF文件的大小。重写时,如果元素的数量超过了redis.h/REDIS_AOF_REWRITE_ITEMS_PER_CMD常量的值,那么就会使用多条指令,每条指令的元素为REDIS_AOF_REWRITE_ITEMS_PER_CMD常量值。

为了避免重写时,Redis处理其它命令时对数据库状态进行修改,从而使得服务器当前的数据库状态和重写后的AOF文件所保存的数据库状态不一致,Redis服务器设置了一个AOF重写缓冲区,这个缓冲区在服务器创建子进程之后开始使用,当Redis服务器执行完一个写命令之后,它会同时将这个写命令发送给AOF缓冲区和AOF重写缓冲区。

当子进程完成AOF重写工作之后,它会向父进程发送一个信号,父进程在接收到该信号之后,会调用一个信号处理函数,并执行以下工作:

1).将AOF重写缓冲区中的所有内容写入到新AOF文件中,这时新AOF文件所保存的数据库状态将和服务器当前的数据库状态一致。

2)对新的AOF文件进行改名,原子地覆盖现有的AOF文件,完成新旧两个AOF文件的替换。

5.总结

1.AOF文件通过保存所有修改数据库的写命令请求来记录服务器的数据库状态。

2.AOF文件中的所有命令都以Redis命令请求协议的格式保存。

3.命令请求会先保存到AOF缓冲区里面,之后再定期写入并同步到AOF文件。

4.appendfsync选项的不同值对AOF持久化功能的安全性以及Redis服务器的性能有很大的影响。

5.服务器只要载入并重新执行保存在AOF文件中的命令,就可以还原数据库本来的状态。

6.AOF重写可以产生一个新的AOF文件,这个AOF文件体积更小。

7.在执行BGREWRITEAOF命令时,Redis服务器会维护一个AOF重写缓冲区,该缓冲区会在子进程创建新AOF文件期间,记录服务器执行的所有写命令。当子进程完成创建新AOF文件的工作之后,服务器就会将重写缓冲区中的所有内容追加到新AOF文件的末尾,使得新旧两个AOF文件所保持的数据库状态一致。最后,服务器用新的AOF文件替换旧的AOF文件,以此来完成AOF文件重写操作。

3.RDB使用示例

        首先对数据库进行清理,

        检查dump.rdb文件

         然后在数据库中添加数据,并用save指令进行rdb持久化

        再次检查dump.rdb

         然后再往数据库添加几个数据,并且关闭服务器,再启动服务器,检查rdb之后关闭前的数据是否存在。

         根据以上结果可以看出,rdb持久化之后的数据中断之后就会损失,而rdb文件的数据则会恢复。

猜你喜欢

转载自blog.csdn.net/carson0408/article/details/84398262