AOF持久化运作原理
-
保存数据
当有数据修改库的命令被执行时,服务器将被执行的命令写入到AOF文件的末尾 -
数据还原
因为AOF文件存储了服务器执行过的所有数据库修改命令,还原时将AOF文件给服务器重新执行一遍所有的命令,就可以达到还远数据库数据的目的
安全性问题
- 服务器每执行一个修改数据库的命令,就会将被执行的命令写入到 AOF 文件,但这并不意味着AOF 持久化不会丢失任何数据
- 在目前常见的操作系统中,执行系统调用 write 函数,将一些内容写入到某个文件里面 时,为了提高效率,系统通常不会直接将内容写入到硬 盘里面,而是先将内容放入到一个内存 缓冲区(buffer)里面,等到缓冲区被填满,或者用户执行 fsync 调用和 fdatasync 调用时,才将储存在缓冲区里面的内容真正地写入到硬盘里面
- 对于 AOF 持久化来说,当一条命令真正地被写入到硬盘里面时,这条命令才不会因为停机而意外丢失
- 因此,AOF 持久化在遭遇停机时丢失命令的数量,取决于命令被写入到硬盘的时间:
• 越早将命令写入到硬盘,发生意外停机时丢失的数据就越少;
• 越迟将命令写入到硬盘,发生意外停机时丢失的数据就越多
安全性控制
为了控制 Redis 服务器在遇到意外停机时丢失的数据量,Redis 为 AOF 持久化提供了 appendfsync选项,值可以是 always 、 everysec 或者 no
-
always
服务器每写入一个命令,就调用一次 fdatasync ,将缓冲区里面的命令写入到硬盘里面。这种模式下,服务器即使遭遇意外停机,也不会丢失任何已经成功执行的命令数据 -
everysec:默认值
服务器每秒钟调用一次 fdatasync ,将缓冲区里面的命令写入到硬盘里面。在这种模式下,服务器遭遇意外停机时,最多只丢失一秒钟内执行的命令数据 -
no
服务器不主动调用 fdatasync ,由操作系统决定何时将缓冲区里面的命令写入到硬盘里面。在这种模式下,服务器遭遇意外停机时,丢失命令的数量是不确定的运行速度: always 的速度慢, everysec 和 no 都很快
AOF 重写
- 让AOF文件的大小控制在合理的范 围,避免不停地增长,Redis 提供了 AOF 重写功能,通过这个功能,服务器可以产生一个新的 AOF 文件:
&emsp: 新 AOF 文件记录的数据库数据和原有 AOF 文件记录的数据库数据完全一样
&emsp: 新的 AOF 文件会使用尽可能少的命令来 记录数据库数据,因此新 AOF 文件的体积通常会比原有 AOF 文件的体积要小得多
&emsp: AOF重写期间,服务器不会被阻塞,可以正常处理客户端发送的命令请求
AOF重写的触发
-
客户端向服务器发送 BGREWRITEAOF 命令
-
通过设置配置选项来让服务器自动执行 BGREWRITEAOF 命令
auto-aof-rewrite-min-size :触发 AOF 重写所需的最小体积:只有在 AOF 文件的体积大于等于 size 时,服务器才会考虑是否需要进行 AOF 重写,这个选项用于避免对体积过小的AOF 文件进行重写auto-aof-rewrite-percentage :指定触发重写所需的 AOF 文件体积百分比:当 AOF文件的体积大于 auto-aof-rewrite-min-size 指定的体积,并且超过上一次重写之后的 AOF 文件体积的 percent% 时,就会触发 AOF 重写。(如果服务器刚刚启动不久,还没有进行过 AOF 重写,那么使用服务器启动时载入的 AOF 文件的体积来作为基准值。)将这个值设置为 0 表示关闭自动 AOF 重写
RDB和AOF对比
RDB持久化 | AOF持久化 |
---|---|
全量备份,一次保存整个数据库 | 增量备份,一次保存一个修改数据库的命令 |
保存的间隔较长 | 保存的间隔默认为一秒钟 |
数据还原速度快 | 数据还原速度一般,冗余命令越多, 还原速度越慢 |
执行 SAVE 命令时会阻塞服务器,但手动或者自动触发的 BGSAVE 都不会阻塞服务器 | 无论是平时还是进行 AOF 重写时,都不会阻塞服务器。 |
更适合数据备份 | 更适合用来保存数据,通常意 义上的数据持久化。在 appendfsync always 模式下运行时,Redis 的持久化方式和一般的 SQL 数据库的持久化方式是一样的 |