Redis持久化方式RDB和AOF的区别 原创
Redis 持久化方式
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 执行原理相同
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 有专门的优化策略来优化日志记录文件过大的问题。
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 重写。
举例:
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 慢