Skip to content

Redis持久化方式RDB和AOF的区别 原创

Redis 持久化方式

plain
1、RDB    Redis DB
2、AOF    AppendOnlyFile 默认关闭

RDB 方式

默认情况下,Redis 将数据库快照保存在名字为 dump.rdb 的二进制文件中。

在 RDB 方式下,有两种保存方式:

(1)、手动执行持久化数据命令来让 redis 进行一次数据快照

  • save:在客户端手动执行 save 命令,它会阻塞 Redis 服务,无法响应客户端请求,创建新的 dump.rdb 替代旧文件
  • bgsave:它是一个异步命令,非阻塞,Redis 服务正常接收处理客户请求,这种方式,Redis 会 fork()一个新的子进程来创建 RDB 文件,子进程处理完后会向父进程发送一个信号,通知它处理完毕,然后父进程会用新的 dump.rdb 文件来替代旧文件

注意:Fork 发生时,父进程内存共享,所以为了不影响子进程做数据快照,在这期间修改数据,将会被复制一份,而不进共享内存,所以说:RDB 所持久化的数据,是 Fork 发生时的数据,在这样的条件下进程持久化数据,如果因为某些情况宕机,则会丢失一部分数据,如果在实际生产中对数据丢失没那么敏感,丢失的也可以从传统数据库中获取或者丢失部分也无所谓,那么就可以选择 RDB 持久化方式。

save 和 bgsave 的比较:

  • save 不用创建新的进程,速度略快,bgsave 需要创建子进程,消费额外的内存
  • save 适合停机维护,服务低谷时段,bgsave 适合线上执行

(2)、另一种则是根据你所配置的配置文件中的策略,达到策略的某些条件时自动持久化数据,和 bgsave 执行原理相同

shell
save 900 1
save 300 10
save 60 10000

这是配置文件默认的策略,它们之间是或的关系,每个 900 秒,在这期间变化至少一个键值,做快照。或者每 300 秒,变化 10 个键值做快照。或者每 60 秒,变化 10000 个键值,做快照。

AOF 方式

append only file,采用追加的方式保存,默认文件是:appendonly.aof

它记录所有的写操作命令,在服务启动的时候使用这些命令可以还原数据库,调整 AOF 持久化策略,可以在服务出现故障时,不丢失任何数据,也能丢失一秒数据,相对于 RDB 来说损失小的多。

(1)、AOF 写入机制

事实上,AOF 机制并不会立即将命令写入到硬盘文件中,而是写入到磁盘缓存,在接下来的策略中,配置多长时间来将硬盘缓存写入到硬盘文件,所以在一定条件下,还是会丢失数据,不过丢失很少一部分。所以 AOF 方式不能保证绝对不能丢失数据。

(2)、写入磁盘策略

Redis 默认使用 ervrysec,就是说每秒持久化一次,而 always 则是每次操作都会立即写入 aof 文件中,而 no 则是不主动进行同步操作,是默认 30s 一次。

  • Always:服务器每写入一个命令,就调用一个 fdatasync,将缓冲区里面的命令写入到硬盘。这中模式下,服务器出现故障,也不会丢失任何已经成功执行的命令数据。
  • Everysec:服务器每一秒调用一次 fdatasync,将缓冲区里面的命令写入到硬盘。这种模式下,服务器出现故障,最多只丢失一秒钟内的执行命令数据。
  • No:服务器不主动调用 fdatasync,由操作系统决定何时将缓冲区里面的命令写入到硬盘。这种模式下,服务器遭遇意外故障时,丢失命令的数量是不确定的。

运行速度:always 的速度慢,everysec 和 no 都很快。

(3)AOF 重写机制

AOF 有序的记录了 redis 的命令操作,意外情况下丢失数据很少,它不断地对 APF 文件添加操作日志记录,redis 有专门的优化策略来优化日志记录文件过大的问题。

plain
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

前者是指超过上一次 aof 重写 aof 文件大小的百分之多少,会再次优化,如果没有重写,则以启动时为主,后者是限制了允许重写的最小 aof 文件大小,bgrewritesof 命令是手动重写命令,会 fock 子进程,在临时文件中重写数据库状态对原 apf 无任何影响,当重建旧的状态后,也会把 fock 发生后的一段时间内的数据一并追加到临时文件,最后替换原有的 aof 文件,新的命令继续向新的 aof 文件中追加。

重写的过程:

(1)fock 一个子进程负载重写 AOF 文件

(2)子进程会创建一个临时文件写入 AOF 信息

(3)父进程会开辟一个内存缓冲区接收新的写入命令

(4)子进程重写完成后,父进程会获得一个信号,将父进程接收到的新的写入操作由子进程写入到临时文件中

(5)新文件替换旧文件

注:如果写入操作的时候出现故障导致命令写半截,可以使用 redis-check-aof 工具修复

AOF 重写触发:

手动:客户端向服务器发送 BGREWRITEAOF 命令

自动:配置文件中配置自动执行 BGREWRITEAOF 命令

auto-aof-rewrite-min-size <size>

触发 AOF 重写所需的最小体积:只要在 AOF 文件的体积大于等于 size,才会考虑是否需要进行重写 AOF,这个选项用于避免对体积过小的 AOF 文件重写

auto-aof-rewrite-percentage <percent>

指定触发所需的 AOF 文件体积的百分比:当 AOF 文件的体积大于指定的体积,并且超过上一次重写之后的 AOF 文件体积的 percent%时,就会触发 AOF 重写。这个值设置为 0 表示关闭自动 AOF 重写。

举例:

plain
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
appendonly no / yes

当 AOF 大于 64M 的时候,可以考虑 AOF 文件重写

只有当 AOF 文件的增量大于起始值 size 的 100%时,启动重写, 默认是关闭

RDB 和 AOF 比较

1、RDB

优点:

  • 完全备份,不同时间的数据集备份可以做到多版本恢复
  • 紧凑的单一文件,方便网络传输,适合容灾恢复
  • 恢复大数据集速度比 AOF 快

缺点:

  • 会丢失最近写入,修改的未能持久化的数据
  • fock 过程非常耗时,会造成毫秒级不能响应客户端请求

2、AOF

优点:

  • 写入机制,默认是 ervrysec 每秒执行,性能好不阻塞服务,最多丢失一秒数据
  • 重写机制,优化 AOF 文件
  • 如果误操作,比如 fulshall 等,只要 AOF 未被重写,停止服务,移除 AOF 文件尾部 FUSHALL 命令,重启 redis,可以将数据集恢复到 flushall 执行前的状态

缺点:

  • 相同数据集,AOF 文件体积比 RDB 大很多
  • 恢复数据库速度比 RDB 慢
最近更新