Redis两种持久化策略——RDB和AOF

Redis持久化

​ Redis是一个内存数据库,它将自己的数据存储在内存中,一旦出现服务器进程退出,存储在内存中的数据将不复存在。为了解决这个问题,Redis提供了持久化功能,这个功能将Redis在内存中的数据库状态持久化到磁盘中,避免因进程退出而导致的数据丢失。

​ Redis的持久化有两种方式:RDB和AOF

RDB持久化

​ RDB持久化既可以手动执行,亦可以根据服务器配置选项定期执行,该功能可以将某个时间点上的数据库状态保存到一个RDB文件中。RDB文件是一个经过压缩的二进制文件,通过该文件可以还原生成RDB文件时的数据库状态。

RDB文件的创建与载入

​ 有两个Redis命令可以用于生成RDB文件,一个是SAVE,另一个是BGSAVE

​ SAVE命令会阻塞Redis服务器进程,在服务器进程阻塞期间,Redis服务器不能处理任何来自客户端的请求;

​ BGSAVE则不会阻塞服务器进程,该命令会派生一个子进程,由子进程负责创建RDB文件,服务器进程继续为客户端提供服务。

​ RDB文件的载入工作是在服务器启动时自动执行的,Redis并没有专门用于载入RDB文件的命令,只要Redis服务器在启动时检测到RDB文件存在,就会自动载入RDB文件。

​ 如果Redis开启了AOF持久化功能,那么优先使用AOF文件来还原数据库状态;只有在AOF持久化功能关闭时,服务器才会使用RDB文件来还原数据库状态。

因为BGSAVE可以在不阻塞服务器进程的情况下执行,所以Redis允许用户通过设置服务器配置的save选项,让服务器每隔一段时间自动执行一次BGSAVE命令。用户可以设置多个save保存条件,只要其中任意一个条件满足,服务器就执行BGSAVE命令开始创建RDB文件保存当前数据库状态。

RDB文件结构

在这里插入图片描述
​ 大写表示常量,小写表示变量。

  • REDIS:魔数,5个字节长,保存则“REDIS”这五个字符。通过这五个字符,程序可以在载入文件时确定该文件是RDB文件。

  • db_version:长度4个字节,它的值是一个用字符串表示的整数,代表RDB文件的版本号,譬如“0004”代表RDB文件的版本为第四版。

  • database:该部分包含着0个或任意多个数据库,以及各个数据库中的键值对数据。

    • 每个非空数据库在RDB文件中都有三部分组成:如下

在这里插入图片描述
- key_value_pairs部分:分为不带过期时间的键值对和带过期时间的键值对,如下
在这里插入图片描述
在这里插入图片描述

  • EOF:1个字节,标志着RDB文件正文内容的结束。

  • check_sum:8字节长的无符号整数,保存着一个校验和,该校验和是通过前4部分内容计算得来的。主要用于在载入RDB文件时用来检查RDB文件是否出现错误或损坏的情况。

分析RDB文件

​ 使用od命令来分析RDB文件,生成dump转储文件。

AOF持久化

​ 与RDB持久化通过保存数据库中的键值对来记录数据库状态不同,AOF持久化是通过保存Redis服务器所执行的写命令来记录数据库状态。被写入AOF文件的所有命令都是以Redis的命令请求协议格式保存的。

AOF持久化的实现

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

命令追加

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

写入与同步

​ appendfsync的不同值代表着不同的同步策略,有always、everysec、no三种。appendfsync的值直接决定AOF持久化的效率和安全性。

  • always:将aof_buf缓冲区的所有内容写入并同步到AOF文件
  • everysec:写入,如果距离上次同步时间超过一秒,则对AOF文件进行同步
  • no:写入,但不同步,何时同步交由操作系统来决定

AOF文件的载入与数据还原

​ 因为AOF里面包含了重建数据库状态的所有写命令,因此服务器只要读入并重新执行一遍AOF文件里面保存的写命令,就可以还原服务器关闭之前的数据库状态。

​ 还原数据库状态的步骤如下:

  • 创建一个不带网络连接的伪客户端。
  • 从AOF文件中分析并读取出一条写命令。
  • 使用伪客户端执行被读出的写命令
  • 重复以上,直到AOF中的写命令被处理完为止。

AOF重写

​ 因为AOF持久化是通过保存被执行的写命令来记录数据库状态的,因此随着时间的推移,AOF文件的内容会越来越多,文件的体积也会越来越大,不论是在存储方面,还是在服务器启动后载入AOF文件还原数据库的方面,都会带来对性能具有负面的影响。并且经过我们的分析,AOF文件是存在可压缩或可精简空间的,因此它是把所有的写命令都记录起来,一定存在许可可以删除并且不影响恢复后数据库状态的命令。AOF重写目的就是要创建一个新的AOF文件来代替现有的AOF文件,并且不能对数据库的状态产生影响。

AOF重写的实现

AOF重写并不需要对AOF文件进行读取、分析或写入操作,而是通故读取服务器当前的数据库状态来实现的。直接数据库中的所有键值对,并记录下能够完美还原出这些命令的内容到写的AOF文件中,然后用新的AOF文件替换掉旧的AOF文件,即可实现AOF的重写,达到精简AOF文件的目的。

​ AOF重写通过aof_rewrite函数来实现。

AOF后台重写

​ aof_rewrite能完成创建新AOF文件的任务,但是由于其内部存在大量的写入操作,所以调用这个函数的线程将被长时间阻塞,同时Redis又是单线程的,因此在调用aof_reerite重写AOF文件期间,服务器将无法处理客户端发来的命令。因此有了BGREWRITEAOF命令AOF重写缓冲区的存在

​ BGREWRITEAOF命令实现原理:

  • 调用BGREWRITEAOF命令后,服务器创建一个子进程用于执行AOF后台重写逻辑,同时设置了AOF重写缓冲区。父进程负责执行客户端发送的命令请求,子进程负责创建新的AOF文件,将调用BGREWRITEAOF命令之前的数据库状态记录到新AOF文件当中。

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

    • 将AOF重写缓冲区中的内容写入到新的AOF文件中,这是新AOF文件保存的数据库状态和真实数据库状态一致。
    • 对新AOF文件进行改名,原子地覆盖现有的AOF文件,完成新旧两个AOF文件的替换。

    信号处理函数执行完毕后,后台AOF重写就完成了。在整个过程中,只有信号处理函数执行时会对服务器进程造成阻塞,这个时候服务器是无法响应客户端请求的。通过这样的设计将对性能造成的负面影响降至最低。

以上就是对Redis的两种持久化策略进行的总结。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值