上节课我们讲了Redis持久化RDB的方式,今天我们讲AOF.我们先回忆一下RDB的缺点
相对来说AOF是可以避免丢数据(这个跟他的保存策略有关系),RDB由于是把内存的所有数据都要同步到磁盘,加上也是一个cpu密集操作,fork子进程也会消耗内存,所以是一个重操作,AOF只是一个追加日志的方式所以就比较轻量。
AOF介绍
默认情况下Redsi是没有开启AOF进行持久化的,当开启AOF的时候,我们每执行一条命令,都会将命令写到磁盘的AOF文件中。
下面我们演示一下,先按照下面参数修改配置
appendonly yes 开启AOF
appendfilename "appendonly.aof" aof文件名
appendfsync always 每次执行命令,都进行写入AOF文件
appendfsync everysec 每一秒,执行写入AOF文件 默认配置
appendfsync no 不主动写入AOF,有操作系统去执行,最快但是不安全
第一步先看一下配置文件的的大小
root@5a989f5f2782:/data# ls -lh
total 8.0K
-rw-r--r-- 1 root root 0 Sep 19 14:02 appendonly.aof //大小为0
-rw-r--r-- 1 redis root 217 Sep 19 14:02 dump.rdb
-rw-r--r-- 1 redis root 3.0K Sep 19 14:02 redis.log
第二步写入多条命令
127.0.0.1:6379> set s1 v1
OK
127.0.0.1:6379> set s2 v2
OK
127.0.0.1:6379> set s3 v3
OK
127.0.0.1:6379> lpush list a b c
(integer) 3
127.0.0.1:6379> zadd room 10 person 20 person1
(integer) 2
127.0.0.1:6379> sadd cladd student1 student2
(integer) 2
127.0.0.1:6379> exit
第三步查看aof文件
$3 //这个3代表命令的长度 如set 是3 s1是2
set
$2
s1
$2
v1
*3
$3
set
$2
s2
$2
v2
*3
$3
set
$2
s3
$2
v3
*5
AOF重写
Redis 可以在 AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写
重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合,整个重写操作是绝对安全的,因为 Redis 在创建新 AOF 文件的过程中,会继续将命令追加到现有的 AOF 文件里面,即使重写过程中发生停机,现有的 AOF 文件也不会丢失。而一旦新 AOF 文件创建完毕,Redis 就会从旧 AOF 文件切换到新 AOF 文件,并开始对新 AOF 文件进行追加操作,AOF 文件有序地保存了对数据库执行的所有写入操作, 这些写入操作以 Redis 协议的格式保存, 因此 AOF 文件的内容非常容易被人读懂, 对文件进行分析(parse)也很轻松
重写的方式有两种
我们现在演示一下
bgrewriteaof演示
第一步查看AOF文件
root@5a989f5f2782:/data# ls -l
total 16
-rw-r--r-- 1 root root 274 Sep 19 15:24 appendonly.aof//注意时间
-rw-r--r-- 1 root root 213 Sep 19 15:23 dump.rdb
-rw-r--r-- 1 redis root 4662 Sep 19 15:24 redis.log
第二步执行多个命令
127.0.0.1:6379> set s1 v1
OK
127.0.0.1:6379> set s1 v2
OK
127.0.0.1:6379> set s1 v3
OK
第三步执行bgrewriteaof
127.0.0.1:6379> bgrewriteaof
Background append only file rewriting started
第三步查看aof文件内容以及此时的aof生成时间是否被替换
SET //发现aof只保留了设置最新的值
$2
s1
$2
v3
省略其他
root@5a989f5f2782:/data# ls -lh
total 16K
-rw-r--r-- 1 root root 355 Sep 19 15:32 appendonly.aof //时间改变了说明进行了替换
-rw-r--r-- 1 root root 213 Sep 19 15:23 dump.rdb
-rw-r--r-- 1 redis root 4.6K Sep 19 15:24 redis.log
AOF文件配置重写
我们就不演示了,直接说一下他的配置参数
auto-aof-rewrite-percentage 100 表示当前aof文件大小超过上一次aof文件大小的百分之多少的时候会进行重写。如果之前没有重写过,以启动时aof文件大小为准
auto-aof-rewrite-min-size 64mb 限制允许重写最小aof文件大小,也就是文件大小大于64mb的时候,进行重写
aof_current_size AOF当前尺寸
aof_base_zize AOF上次启动和重写的尺寸
当满足下面规则就会自动触发时机
aof_current_size>auto-aof-rewrite-min-size
of_current_size-aof_base_zize/aof_base_zize>auto-aof-rewrite-percentage
AOF 优点
使用AOF 会让你的Redis更加耐久: 你可以使用不同的fsync策略:无fsync,每秒fsync,每次写的时候fsync.使用默认的每秒fsync策略,Redis的性能依然很好(fsync是由后台线程进行处理的,主线程会尽力处理客户端请求),一旦出现故障,你最多丢失1秒的数据.
AOF文件是一个只进行追加的日志文件,所以不需要写入seek,即使由于某些原因(磁盘空间已满,写的过程中宕机等等)未执行完整的写入命令,你也也可使用redis-check-aof工具修复这些问题.
Redis 可以在 AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写: 重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合。 整个重写操作是绝对安全的,因为 Redis 在创建新 AOF 文件的过程中,会继续将命令追加到现有的 AOF 文件里面,即使重写过程中发生停机,现有的 AOF 文件也不会丢失。 而一旦新 AOF 文件创建完毕,Redis 就会从旧 AOF 文件切换到新 AOF 文件,并开始对新 AOF 文件进行追加操作。
AOF 文件有序地保存了对数据库执行的所有写入操作, 这些写入操作以 Redis 协议的格式保存, 因此 AOF 文件的内容非常容易被人读懂, 对文件进行分析(parse)也很轻松。 导出(export) AOF 文件也非常简单: 举个例子, 如果你不小心执行了 FLUSHALL 命令, 但只要 AOF 文件未被重写, 那么只要停止服务器, 移除 AOF 文件末尾的 FLUSHALL 命令, 并重启 Redis , 就可以将数据集恢复到 FLUSHALL 执行之前的状态。
AOF 缺点
对于相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积。
根据所使用的 fsync 策略,AOF 的速度可能会慢于 RDB 。 在一般情况下, 每秒 fsync 的性能依然非常高, 而关闭 fsync 可以让 AOF 的速度和 RDB 一样快, 即使在高负荷之下也是如此。 不过在处理巨大的写入载入时,RDB 可以提供更有保证的最大延迟时间(latency)。
如何选择持久化方式
一般来说, 如果想达到足以媲美 PostgreSQL 的数据安全性, 你应该同时使用两种持久化功能。
如果你非常关心你的数据, 但仍然可以承受数分钟以内的数据丢失, 那么你可以只使用 RDB 持久化。
有很多用户都只使用 AOF 持久化, 但我们并不推荐这种方式: 因为定时生成 RDB 快照(snapshot)非常便于进行数据库备份, 并且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快, 除此之外, 使用 RDB 还可以避免之前提到的 AOF 程序的 bug (AOF 在过去曾经发生过这样的 bug :因为个别命令的原因,导致 AOF 文件在重新载入时,无法将数据集恢复成保存时的原样。(举个例子,阻塞命令 BRPOPLPUSH 就曾经引起过这样的 bug ))