Redis官方:Redis persistence | Redis
注:这里只说AOF工作原理,AOF其他功能请查阅官方文档
RedisAof是什么?
AOF(仅追加文件):
AOF 持久性记录服务器收到的每个写入操作。然后可以在服务器启动时再次重播这些操作,重建原始数据集。命令的记录格式与 Redis 协议本身相同。
AOF优点
官方原话:
AOF优势
- 使用 AOF Redis 更加持久:您可以拥有不同的 fsync 策略:完全没有 fsync,每秒 fsync 一次,每次查询时 fsync。使用每秒 fsync 的默认策略,写入性能仍然很高。fsync 是使用后台线程执行的,当没有 fsync
正在进行时,主线程将努力执行写入,因此您只能丢失一秒钟的写入。- AOF 日志是仅追加日志,因此在断电时不会有寻道或损坏问题。即使由于某种原因(磁盘已满或其他原因)日志以半写命令结束,redis-check-aof
工具也可以轻松修复它。- Redis 能够在 AOF 变得太大时在后台自动重写它。重写是完全安全的,因为当 Redis 继续追加到旧文件时,会使用创建当前数据集所需的最少操作集生成一个全新的文件,一旦第二个文件准备就绪,Redis
就会切换两者并开始追加到新文件。- AOF 以易于理解和解析的格式包含所有操作一个接一个的日志。您甚至可以轻松导出 AOF 文件。例如,即使您使用 `FLUSHALL`
命令意外刷新了所有内容,只要在此期间没有重写日志,您仍然可以通过停止服务器、删除最新命令并重新启动 Redis 来保存数据集。AOF缺点
- AOF 文件通常大于同一数据集的等效 RDB 文件。
- AOF 可能比 RDB 慢,具体取决于确切的 fsync 策略。一般来说,将 fsync 设置为每秒性能仍然非常高,并且在禁用 fsync 的情况下,即使在高负载下,它应该与 RDB一样快。尽管如此,RDB仍然能够提供更多关于最大延迟的保证,即使在巨大的写入负载的情况下也是如此。
- 而且在Redis Version < 7.0 如果在重写期间对数据库进行了写入,则 AOF 可能会使用大量内存(这些写入缓存在内存中并在最后写入新的 AOF)。重写期间到达的所有写入命令将写入磁盘两次。Redis 可以在重写结束时冻结写入并将这些写入命令同步到新的 AOF 文件。(注:这个问题在Redis > 7.0得到了解决)
优缺点总结:
优点:
- 每一次修改都同步,文件的完整性会更好
- 每秒同步一次,最多丢失一秒数据
- 从不同步策略,效率最高
缺点:
- 相对数据文件来说,AOF文件永远大于RDB数据文件(这个可以做限制,比如只保存100mb,也可以联合RDB一起使用来保证只记录最近一个时间节点的数据),修复的速度也比RDB慢。
- AOF运行效率要比RDB慢(这个在Redis7.0之后拥有不输于RDB的运行效率,但是RDB还是更有优势,这个官方有说明),所以Redis默认配置就是RDB持久化
AOF原理
在Redis版本7.0之前
1-> 开启一个Fork子进程
2-> 子进程创建了一个新的临时AOF文件,读取内存这个中数据快照,写入重构数据库状态指令
3->父进程将所有新增更改命令写入到内存缓冲区中(同时,它将新增更改命令写入旧的AOF文件中,仅追加文件)
4-> 子进程写入完毕,通知父进程进行下一步处理
5-> 父进程收到子进程信号,将缓存中的命令追加到临时AOF文件
6-> 父进程修改临时AOF文件名称为正式AOF文件
7-> 父进程将后续新的更改命令追加到正式AOF文件
在Redis版本7.0之后
1-> 父线程开启Frok子进程
2-> 子进程执行重写逻辑并生成新的基本AOF文件
3-> 当子进程重写时,父进程会打开一个新的增量 AOF 文件以继续写入
4-> 当子进程写入完毕后,通知父进程
5-> 父进程收到信号,读取增量AOF和基本AOF文件生成文件清单
6-> 父进程读取文件清单,重写基础AOF文件,并对其进行原子交换,确保重写成功
7-> 父进程清理旧的基本文件和任何未使用的增量文件
在redis.conf启动AOF之后,可以在Redis的默认工作目录看到一个appenddir目录,其中存放了增量AOF、基础AOF、文件清单。
基础AOF文件中存放了每次增量AOF和临时AOF生成文件清单后重写的AOF数据
文件清单中存储了base.rdb和incr.aof的名字
7.0之前与7.0之后Redis读取文件的区别
在Redis7.0之前,Redis启动时会去优先读appendonly.aof文件(在AOF和RDB同时存在的时候)来重构数据库状态
在Redis7.0之后,Redis启动时会去优先读appendonly.aof.1.base.rdb文件(在AOF和RDB同时存在的时候)来重构数据库状态