AOF持久化
- AOF持久化通过保存redis的写命令来记录数据库的状态,文件内容完全按照resp协议格式保存,是可读的。
- 在前面我们了解的RDB持久化方式是保存数据库中的键值对,假如执行了3次命令,数据库中有2个键值对,那么RDB就是保存
这2个键值对,而AOF则是将过程中执行的3个命令保存起来。
一、AOF实现
1.1 命令追加
- 执行完一个写命令之后,redis会将命令保存到AOF缓冲区
1.2 文件写入与同步
AOF缓冲 ---写入---> AOF文件 ---同步---> 磁盘的AOF文件
- 文件的写入和同步这两个动作,在源码中由flushAppendOnlyFile方法完成,但是该方法的行为取决于appendfsync配置决定,
appendfsync配置值 | 含义 | 效率 | 安全 |
---|
always | 每次都会将AOF缓冲中的内容写入并同步 | 最低 | 最多丢失一个事件循环中产生的数据(一个事件循环不等价一个命令,比如LUA脚本,批量设值等) |
everysec | 如果上一次同步时间大于1S,就进行写入和同步,反之不进行。即一秒一次,也是默认值 | 折中 | 最多丢失1S内的数据 |
no | 写入AOP文件但不进行同步,由OS决定什么时候同步 | 最高 | OS决定,和everysec类似,最多丢失上一次同步AOF后的全部数据 |
- 注意写入和同步的过程其实有区别,写入是针对应用程序而言(redis也是一个应用程序),同步是针对OS而言,应用程序的写入内容并不会立刻同步到磁盘,
而是会保存在OS的一个缓冲区,同步则是将这些缓存同步到磁盘。(OS提供了fsync和fdatasync这2个同步函数强制让OS将缓冲区数据同步到磁盘)
二、AOF载入与数据还原
- 创建伪客户端 -> 循环读取全部AOF的命令,发往redis服务器,直到所有命令执行完毕
三、AOF重写
- AOF重写其实是创建一个新的AOF文件,并且它和旧的AOF文件具有相同的数据库状态,但是占有空间更少。比如对一个key连续设置三次,这样的话保存其最后一条就行了没有必要三条命令都保存,在数据库状态上是等价的。
3.1 实现
- AOF重写并不依赖于旧的AOF文件,甚至不需要读取它,而是通过读取服务器当前数据库状态来实现的。在AOF重写的时候,其实我们已经不关心以前执行了多少命令,我们只需要保存当前redis的状态即可,因此重写的过程其实就是读取当前数据库状态来完成的。其实本质就是将对一个key的多条操作命令合并为一条。
3.2 重写触发
//配置相比前一个AOF文件大小增长的百分比,默认是100表示当前大小变为上一次rewrite时2倍就会触发重写,设置为0就会禁止
auto-aof-rewrite-percenttage = 100
//配置触发AOF重写的AOF文件的最小大小(默认64MB)
auto-aof-rewrite-min-size 64mb
3.3 后台重写(BGREWRITEAOF)
-
Redis使用单线程来处理命令请求,而且AOF会进行大量的读写操作,避免AOF重写过程阻塞请求命令,使用子线程进行后台重写,父进程依然可以处理请求。
-
子进程进行AOF重写期间,假设文件名为newAOF,旧的AOF文件名为oldAOF,服务器执行的命令会追加到AOF缓冲区,子进程完成重写之后会通知父进程,父进程再将缓冲区内的命令追加到newAOF文件,然后将newAOF文件名原子修改为oldAOF,替换旧的即可。
-
后台重写细节
1. 创建一个AOF重写缓冲区,重写期间的请求会保存到该缓冲区,创建一个newAOFFile文件
2. 子线程开始重写,重写完毕后告知父进程(重写过程就是读取数据库中的键值对)
3. 将AOF重写缓冲区中的内容写入到新的AOF文件(也就是重写期间的命令即会保存到AOF缓冲区,也会保存到AOF重写缓冲区)
4. 原子地将新的AOF文件改名为旧的AOF文件
注意前面的第3、4步骤会阻塞,但是已经将阻塞将至最低了
四、AOF配置
配置 | 作用 |
---|
appendonly | AOF开关,yes表示开启,默认关闭 |
appendfilename | 指定aof文件名称 |
配置 | 作用 |
---|
appendfsync=always | 同步持久化每一次修改操作 |
appendfsync=everysec | 每秒向aof文件同步一次 |
appendfsync=no | 关闭向aof文件写入修改 |
五、RDB和AOF对比
对比项 | RDB | AOP |
---|
原理 | 保存数据库快照状态 | 保存执行过的写操作 |
触发机制 | 一段时间内执行命令达到阈值就触发,比如900S内至少修改一次 | always / everysec /no根据时间频率 |
优点 | 文件紧凑占用空间小恢复快,适合备份和恢复,容灾 | 支持不同的fsync策略,数据丢失风险较小,AOF文件可读,重写机制保障不会过大 |
缺点 | 会有部分数据丢失,数据很大时后台svafork子进程占用资源造成"假死" | AOF文件一般比RDB文件更大,高安全性的fsync策略对性能有一定影响 |
默认 | 默认开启,如果开启了AOF则redis启动时使用AOF恢复 | 默认关闭,通过appendonly = yes开启 |
场景 | 适合备份,或者数据安全性不高的场景 | 数据可靠性较高的场景 |
六、小结
- 本文主要介绍了AOF重写。主要了解重写的配置和过程
七、参考