redis AOF原理理解
AOF(Append-Only-File)
AOF是redis的另一种持久化的方式。它是基于文本形式的,追加写入命令的方式来做持久化的。这个有些类似mysql中的binlog,它的持久化记录的粒度比RDB要更好,所以生产环境中一般会开启AOF持久化的。当然,在redis4之后的版本,rdb和aof是可以开启混合模式的。aof-use-rdb-preamble对这个进行配置即可
AOF持久化流程
如图:
- 客户端的请求写命令会被append追加到AOF缓冲区内;
- AOF缓冲区根据AOF持久化策略[always,everysec,no]将操作sync同步到磁盘的AOF文件中;
- AOF文件大小超过重写策略或手动重写时,会对AOF文件rewrite重写,压缩AOF文件容量;
- Redis服务重启时,会重新load加载AOF文件中的写操作达到数据恢复的目的;
AOF部分参数解释
# AOF开启开关
appendonly yes
# AOF文件名
appendfilename "appendonly.aof"
# AOF策略
appendfsync always # 每个命令都记录
# appendfsync everysec # 每秒记录一次
# appendfsync no # 看操作系统自身调度记录
# 是否阻止对主进程的fsync函数调用进行拦截。如果为no,则不拦截,主进程和子进程均可以操作磁盘的写入。但是可能会出现aof同步阻塞的问题。如果为yes,则不会阻塞,但是这也意味着,可能会损失最多30秒的日志(默认的linux设置情况下)
no-appendfsync-on-rewrite no
# AOF文件大小比起上次重写时的大小,增长100%触发重写。比如上次重写后大小为30mb,那么aof文件会达到60mb的时候触发重写
auto-aof-rewrite-percentage 100
# 如果文件超过64mb的时候,也会触发重写
auto-aof-rewrite-min-size 64mb
# 开启rdb和aof的混合模式
aof-use-rdb-preamble yes
重写
AOF持久化机制记录每个写命令,当服务器重启的时候会复现AOF文件中的所有命令,会消耗太多资源且重启很慢。因此为了避免AOF文件中的写命令太多造成的文件过大,redis引入了AOF的重写机制来压缩AOF文件体积。AOF文件重写是把redis进程内的数据转化为写命令同步到新AOF文件的过程。
触发重写方式有重写策略触发和手动触发两种
重写流程,如图:
- bgrewriteaof触发重写,判断当前是否有bgsave和bgrewriteaof正在运行,如果有,则等待该命令结束后再继续执行
- 主进程fork出子进程执行重写操作,保证主进程不会阻塞
- 子进程遍历redis内存中数据到临时文件,客户端的写请求同时吸入aof_buf缓冲区和aof_rewrite_buf重写缓存区,保证原aof文件完整以及新aof文件生成期间的新的数据修改动作不会丢失
- 子进程完成新的aof文件后,会向主进程发送信号,主进程更新统计信息,并且主进程把aof_rewrite_buf中的数据追加到新的aof文件中
- 使用新的aof文件替换旧的aof文件,完成aof重写
注意事项:
如果之前从未开启过aof,只使用了rdb,那么我们如果之间关闭redis服务,然后修改配置开启aof,会出现redis无数据的情况,因为才开启的aof文件是空文件,而redis会在aof开启状态下,优先读取aof文件还原数据。
为了避免这种事情的发生,我们可以先在redis中先热开启aof,然后把rdb中的数据同步到aof文件中,然后再关闭redis去修改配置,最后重启redis。
操作流程:
-
当前aof并未开启
-
输入测试数据
-
查看rdb文件
-
在redis中热修改aof配置:
config set appendonly yes
-
查看当前redis工作目录中是否产生aof文件
-
查看aof文件内容
我们可以看见,aof文件中是一堆二进制内容,说明当前aof文件已经同步rdb镜像了 -
删除rdb文件,并且关闭redis服务
-
修改redis.conf中的配置,启用aof服务
-
启动redis服务,并查看当前数据是否存在
查看aof持久化情况
info persistence
aof优缺点分析
- 优点
- 以文本形式保存,易读
- 记录写操作保证数据不丢失
- 缺点
- 存储所有写操作命令,且以文件为文本格式保存,未经压缩,文件体积高
- 恢复数据时重放AOF中所有代码,恢复性能弱于RDB方式