Redis持久化——AOF
一.是什么?
AOF是以日志的形式来记录每个写操作,将Redis执行过的所有写操作记录下来(读操作不做记录),只许追加文件不可以改写文件,Redis启动之初会读取该文件重新构建数据,换言之,Redis重启的话就根据日志文件的内容将写操作指令从前到后执行一次以完成数据的恢复工作。
二.配置方式?
配置 redis.conf 文件中 APPEND ONLY MODE 下的属性。
三.AOF如何恢复?(默认RDB文件名称:appendonly.aof)
1.将redis.conf 文件中 APPEND ONLY MODE 下appendonly属性修改为yes开启 AOF 持久化方式。
2.将AOF文件 (appendonly.aof) 移动到 redis 安装目录(可以使用 config get dir 命令获取 redis 的安装目录)
3.备份AOF文件(可选)
4.使用redis-check-aof --fix appendonly.aof对AOF文件进行修复(如果AOF文件没有异常可以忽略此步骤)
5.重启Redis服务,Redis自动重新加载AOF文件。
四.AOF重写
AOF持久化是采用文件追加的方式,Redis不断将写命令记录到 AOF 文件中,随着数据越来越多,AOF文件也会随之越来越大,文件越大,占用服务器内存越大以及 AOF 恢复要求时间越长。为了解决这个问题,Redis新增了重写机制,当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集。可以使用命令 bgrewriteaof 。
当需要重写AOF文件时,Redis会fork出一条新进程来将文件重写(也是先将数据写到临时文件中然后再替换原来的AOF文件),遍历新进程内存中的数据,然后用一条命令去代替之前的多条命令生成一个新的文件后去替代原来的AOF文件。这样做1.子进程进行 AOF 重写期间,服务器进程(父进程)可以继续处理其他命令。2.子进程带有父进程的数据副本,使用子进程而不是线程,可以在避免使用锁的情况下,保证数据的安全性。
使用子进程解决了上面的问题,但是新问题也产生了:因为子进程在进行 AOF 重写期间,服务器进程依然在处理其它命令,这新的命令有可能也对数据库进行了修改操作,使得当前数据库状态和重写后的 AOF 文件状态不一致。
为了解决这个数据状态不一致的问题,Redis 服务器设置了一个 AOF 重写缓冲区,这个缓冲区是在创建子进程后开始使用,当Redis服务器执行一个写命令之后,就会将这个写命令也发送到 AOF 重写缓冲区。当子进程完成 AOF 重写之后,就会给父进程发送一个信号,父进程接收此信号后,就会调用函数将 AOF 重写缓冲区的内容都写到新的 AOF 文件中。
这样将 AOF 重写对服务器造成的影响降到了最低。
触发机制:通过 redis.conf 配置文件中的 auto-aof-rewrite-percentage:默认值为100,以及auto-aof-rewrite-min-size:64mb 配置,也就是说默认Redis会记录上次重写时的AOF大小,默认配置是当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发。
五.总结
1.劣势
1).相同数据集的数据而言,AOF 文件通常会比 RDF 文件体积更大,且恢复速度慢于RDB。
2).虽然 AOF 提供了多种同步的频率,默认情况下,每秒同步一次的频率也具有较高的性能。但在 Redis 的负载较高时,RDB 比 AOF 具好更好的性能保证。
3).RDB 使用快照的形式来持久化整个 Redis 数据,而 AOF 只是将每次执行的命令追加到 AOF 文件中,因此从理论上说,RDB 比 AOF 方式更健壮。官方文档也指出,AOF 的确也存在一些 BUG,这些 BUG 在 RDB 没有存在。
2.优势
1).AOF 持久化的方法提供了多种的同步频率,即使使用默认的同步频率每秒同步一次,Redis 最多也就丢失 1 秒的数据而已。
2).AOF 文件使用 Redis 命令追加的形式来构造,因此,即使 Redis 只能向 AOF 文件写入命令的片断,使用 redis-check-aof 工具也很容易修正 AOF 文件。
3).AOF 文件的格式可读性较强,这也为使用者提供了更灵活的处理方式。例如,如果我们不小心错用了 FLUSHALL 命令,在重写还没进行时,我们可以手工将最后的 FLUSHALL 命令去掉,然后再使用 AOF 来恢复数据。