redis持久化详解

Redis持久化机制

  • RDB (默认机制)
  • AOF

RDB (快照)

按照一定的时间将内存的数据以快照的形式保存到硬盘中,对应产生的数据文件为dump.rdb。

生成快照方式

  • 客户端方式
    • BGSAVE 和 SAVE指令
  • 服务端方式
    • 服务器配置自动触发 和 shutdown

客户端方式

  1. BGSAVE
    客户端可以使用BGSAVE命令来创建一个快照,当接收到客户端的BGSAVE命令时,redis会创建一个子进程,子进程负责将快照写入磁盘中,而父进程继续处理命令请求。(在子进程创建之初,父子进程共享相同内存,知道父进程或子进程对内存进行了写之后,对于被写入的内存的共享就会结束服务)
  2. SAVE
    客户端使用SAVE命令创建一个快照,接收到SAVE命令的redis服务器在快照创建完毕之前将不再响应任何其他的命令。

服务端方式

  1. 配置文件持久化
    服务器通过配置方式来满足自动触发快照进行持久化,管理员需要在redis.conf中设置save配置选项,redis会在save选项条件满足之后自动触发一次BGSAVE命令,如果管理员设置了多个save配置选项,当任意save条件被满足,redis都会触发一次BGSAVE命令。
  2. shutdown指令
    当redis通过shutdown指令接受到关闭服务器的请求时,会触发一次SAVE命令,阻塞所有的客户端,不再执行客户端发送的任何命令,在SAVE命令执行完毕后关闭服务器。

优缺点

优点

  1. 文件单一: 只有一个dump.rdb文件,方便持久化
  2. 容灾性好: 一个文件可以保存到安全的磁盘中。
  3. 性能最大化: 子进程来完成写操作,主进程可以继续处理命令,实现IO最大化(使用单独的子进程来进行持久化,主进程不会进行任何IO操作,保证了redis的高性能)。
  4. 启动效率高: 相对于数据集大时,比AOF的启动效率更高。

缺点

  1. 数据安全性低: RDB是间隔一段时间进行持久化,如果持久化之间redis发生故障,会发生数据丢失。
  2. 版本兼容问题: dump.rdb文件是一个redis中特制的二进制文件,涉及到不同的redis版本,可能会发生版本不兼容问题。

AOF (追加日志文件)

将redis执行的所有写命令记录到日志文件中,将被执行的写命令写到AOF的文件末尾。

当redis重启时,redis会从头到尾执行一次AOF文件所包含的所有写命令,以此恢复AOF文件的记录的数据集。

开启AOF持久化

redis默认配置中AOF持久化机制是不开启的,需要在配置中开启。

修改redis.conf配置文件:

#开启持久化
appendonly yes
#指定生成文件名称
appendfilename "appendonly.aof"

设置日志追加频率

修改redis.conf配置文件同步频率

appendfsync everysec

同步频率包括:

  • always
  • everysec (推荐)
  • no

always
说明: 每个redis写命令都要同步写入硬盘,严重降低redis速度
解释: 如果用户使用了always选项,会将发生系统崩溃时出现的数据丢失减到最少,但因为这种同步策略需要对硬盘进行大量的写入操作,所以redis处理命令的速度会受到硬盘性能的限制。
注意: 使用固态硬盘(SSD)时需谨慎使用always选项,这种模式不断写入少量数据,可能会引发严重的写入放大问题,导致固态硬盘的寿命从原来的几年降低为几个月。

everysec
说明:每秒执行一次的同步显示,将多个写命令同步到磁盘
解释:同时保障了数据安全和写入性能,redis每秒一次对AOF文件进行同步,此时AOF文件性能和不使用任何持久化特性时的性能基本相同;通过每秒同步一次AOF文件,redis可以保证,即使系统崩溃,最多丢失一秒之内产生的数据。

no
说明:由操作系统决定何时同步
解释:这个选项不好对redis性能带来影响,但是当系统宕机时,丢失的数据量具有不确定性;另外,如果用户硬盘处理写入操作不够快,当缓冲区被等待写入硬盘数据填满时,redis会处于阻塞状态,导致redis的处理命令请求速度变慢。

AOF重写

AOF文件是以追加的方式记录接收到的写命令的,不断的追加会导致AOF文件过大。

文件过大导致的问题:

  1. 文件系统的限制:文件系统本身对文件的大小有限制,无法保存过大文件,如果超出限制,会导致 redis 宕机,redis 执行命令速度会降低。
  2. 追加效率降低:AOF文件采用追加的方式写入文件,每次要遍历寻找到文件尾部,如果文件过大,追加效率会大幅度降低。
  3. 执行效率降低:如果服务器发生宕机,AOF文件命令要逐一执行,文件过大导致执行内容过多,影响效率。

AOF重写:用来一定程度上减小AOF文件的体积,解决文件过大的问题。

触发重写方式

  • 客户端方式
  • 服务器配置文件自动触发方式

客户端方式:

执行BGREWRITEAOF命令 不会阻塞redis服务

服务器配置文件自动方式:

修改redis.conf配置文件:

#表示AOF写入文件大小大于64m才能触发重写操作。
auto-aof-rewrite-min-size 64mb
#100表示百分比,表示AOF文件的体积比上一次重写之后体积至少大了 “100%” 时会自动触发。
auto-aof-rewrite-percentage 100
重写原理
  1. 重写AOF的时候,创建一个重写子进程,然后读取旧的AOF文件,压缩并写入到一个临时AOF。
  2. 在此期间,主进程一边将接收到的指令累计到一个缓冲区中,一边将指令写入到旧的AOF。
  3. 子进程写完后,向主进程发送一个信号量,主进程就将缓冲区中的指令追加到新AOF。
  4. 用新的AOF替换旧的AOF,之后的新指令就追加到新的AOF。

优缺点

优点

  1. 数据安全: AOF持久化可以通过配置appendfsync属性,设置其记录频率。
  2. 数据一致: 通过append模式写文件,即使服务器宕机,也可以通过redis-check-aof工具解决数据一致问题。
  3. 灵活。AOF机制的 rewrite 模式,AOF文件没被rewrite之前(文件过大时会对命令进行合并重写),可以删除其中的某些命令。

缺点

  1. 恢复速度慢: AOF文件比RDB文件更大,且恢复速度更慢。
  2. 效率低: 数据集大时,AOF比RDB启动效率低。

当RDB和AOF同时开启时,redis数据恢复会优先选中 AOF 恢复。