持久化之AOF

xiaohai 2021-05-28 20:47:48 1972人围观 标签: Redis 
简介在前面我们学习了Redis的RDB的持久化,我们都知道RDB持久化会根据配置中的save对应的键和时间的触发机制来进行快照。但是不管怎么样,两次快照之间如果存在系统异常崩溃或者服务器宕机等情况,RDB就不能保证数据的强一致性了。这时候Redis提供了另外一种持久化方法AOF,AOF(Append Only File)记录Redis写入命令追加到日志文件。每写入一个命令都会被追加到文件中,所以AOF的数据一致性高于RDB。但是在默认情况下AOF是没有开启的,所以本文我们将介绍AOF的配置参数;

  在前面我们学习了Redis的RDB的持久化,我们都知道RDB持久化会根据配置中的save对应的键和时间的触发机制来进行快照。但是不管怎么样,两次快照之间如果存在系统异常崩溃或者服务器宕机等情况,RDB就不能保证数据的强一致性了。这时候Redis提供了另外一种持久化方法AOF,AOF(Append Only File)记录Redis写入命令追加到日志文件。每写入一个命令都会被追加到文件中,所以AOF的数据一致性高于RDB。但是在默认情况下AOF是没有开启的,所以本文我们将介绍AOF的配置参数;

1、先获取AOF持久化配置信息

127.0.0.1:6379> CONFIG GET appendonly
1) "appendonly"
2) "no"

no表示默认情况下AOF是没有开启

2、可以通过以下两种方式打开AOF

#方法1、使用CONFIG SET命令
127.0.0.1:6379> CONFIG SET appendonly yes
OK
#方法2、修改配置文件,将no改成yes
[root@localhost ~]# cat /apps/redis/redis.conf |grep "^appendonly"
appendonly no

3、如果要禁用AOF也是通过CONFIG SET和配改配置文件的两种方式,但是CONFIG SET可以在运行的过程中进行修改,而修改了配置文件就需要重启Redis服务器

4、使用INFO PERSISTENCE命令检查AOF相关内容可以判断是否启用了AOF功能

127.0.0.1:6379> INFO PERSISTENCE
# Persistence
loading:0
rdb_changes_since_last_save:0
rdb_bgsave_in_progress:0
rdb_last_save_time:1534098902
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:0
rdb_current_bgsave_time_sec:-1
rdb_last_cow_size:4308992
aof_enabled:1
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:1
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok
aof_last_write_status:ok
aof_last_cow_size:4411392
aof_current_size:258
aof_base_size:258
aof_pending_rewrite:0
aof_buffer_length:0
aof_rewrite_buffer_length:0
aof_pending_bio_fsync:0
aof_delayed_fsync:0

5、查看AOF文件

[root@localhost ~]# ll /apps/redis/appendonly.aof 
-rw-r--r--. 1 root root 258 Aug 12 15:45 /apps/redis/appendonly.aof

6、查看AOF相关配置文件信息

[root@localhost ~]# cat /apps/redis/redis.conf |grep "append"|grep -Ev '^$|^#'
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no

当AOF功能被开启后,Redis将会在数据目录下创建一个AOF文件,AOF的文件名为appendfilename参数设置的文件名,同时Redis还会降当前内存中的数据填充到AOF这个文件中。

当Redis服务器接收到一个修改内存数据的写入命令的时候,Redis会将该命令追加到AOF文件中。但是,当我们深入研究AOF文件的写入过程,就会发现操作系统实际上维护了一个缓冲区,Redis的命令首先会被写入到这个缓冲区中。而缓冲区转给你的数据必须被刷新到磁盘中才会被永久的保存。这个过程通过Linux系统调用fsync()来完成,这是一个阻塞调用,只有磁盘设备报告缓冲区中的数据写入完成后才会返回。

在将命令追加到AOF文件是,我们可以通过Redis的配置参数appendfsync来调整调用fsync()的频率,该参数有三个选项:

  • always:每写入一个命令都调用fsync()。这个选项可以确保在发生意外的服务器崩溃或硬件故障时,只丢失一条命令。但是fsync()是一个阻塞调用,Redis的性能会受到物理磁盘写入性能的限制。设置成该选项其实不很好,这样会造成Redis服务器的性能显著下降;
  • everysec:每秒钟调用一次fsync()。使用这个选项,在出现意外的情况下只有一秒钟的数据会丢失。这里需要自己考虑数据和性能之间进行平衡了。
  • no:永远不调用fsync()。采用该选项,就会由操作系统来决定何时将数据从缓冲区写入到磁盘。大多数Linux系统是30秒

注意:当Redis服务器关闭是,fsync()会被显式的调用,以确保写入缓冲区的数据都会被刷新到磁盘。当Redis服务器启动时,AOF文件会被用来恢复数据,Redis只需要通过读取命令来重放文件,并将它们逐个应用到内存中即可,当所有命令执行完后,数据也就被重建好了。

随着Redis将写入命令追加到AOF文件中,AOF文件的大小可能会显著增加,而这个会拖慢Redis启动时的数据重建过程。Redis提供了一种机制,即通过AOF重写(AOF rewrite)来压缩AOF文件。Redis中某些键可能已经被删除或过期了,所以可以在AOF文件中将其清理;同时某些键可能被更新了多次,但只有最新的值才需要记录在AOF文件中。这就是AOF重写数据压缩的基本思想。我们可以使用BGREWRITEAOF命令来启动重写过程。

如果操作系统崩溃,那么AOF文件最后可能会遭到损坏或截断。Redis提供了一个工具,redis-check-aof,用于修复损坏的文件。如果要修复一个AOF文件,只需运行下面的命令:

[root@localhost redis]# src/redis-check-aof --fix appendonly.aof