Redis(七)-持久化之(AOF持久化)

一 简介

针对RDB不适合实时持久化的问题,Redis提供了AOF持久化方式来解 决
AOF(append only file)持久化:以独立日志的方式记录每次写命令, 重启时再重新执行AOF文件中的命令达到恢复数据的目的。AOF的主要作用是解决了数据持久化的实时性,目前已经是Redis持久化的主流方式。理解掌握好AOF持久化机制对我们兼顾数据安全性和性能非常有帮助
与RDB持久化通过保存数据库中的键值对来记录数据库状态不同,AOF持久化是通过保存Redis服务器所执行的写命令来记录数据库状态的,如下图所示:
在这里插入图片描述

AOF持久化是通过保存服务器执行的命令来记录状态的。还原的时候再执行一遍即可。

二 AOF的工作流程

AOF的工作流程操作:
命令写入 (append):所有的写入命令会追加到aof_buf(缓冲区)中
文件同步(sync):AOF缓冲区根据对应的策略向硬盘做同步操作
文件重写(rewrite):随着AOF文件越来越大,需要定期对AOF文件进行重写,达到压缩的目的
重启加载 (load):当Redis服务器重启时,可以加载AOF文件进行数据恢复
如下所示:

在这里插入图片描述

三 命令写入 (append)

当AOF持久化功能处于打开状态时,服务器在执行完一个写命令之后,会以Redis协议格式将被执行的写命令追加到服务器状态的AOF缓冲区(aof_buf)

**AOF为什么直接采用文本协议格式?**可能的理由如下:
文本协议具有很好的兼容性
开启AOF后,所有写入命令都包含追加操作,直接采用协议格式,避免了二次处理开销
文本协议具有可读性,方便直接修改和处理
AOF为什么把命令追加到aof_buf中?
Redis使用单线程响应命令,如果每次写AOF文件命令都直接追加到硬盘,那么性能完全取决于当前硬盘负载
先写入缓冲区aof_buf中,还有另一个好处,Redis可以提供多种缓冲区同步硬盘的策略,在性能和安全性方面做出平衡

四 文件同步(sync)

Redis提供了多种AOF缓冲区同步文件策略,由参数appendfsync控制

配置为always时:每次写入都要同步AOF文件,在一般的SATA硬盘上,Redis只能支持大约几百TPS写入,显然跟Redis高性能特性背道而驰, 不建议配置
配置为no时:由于操作系统每次同步AOF文件的周期不可控,而且会加大每次同步硬盘的数据量,虽然提升了性能,但数据安全性无法保证
配置为everysec时:是建议的同步策略,也是默认配置,做到兼顾性能和数据安全性。理论上只有在系统突然宕机的情况下丢失1秒的数据。在这里插入图片描述

五 文件重写(rewrite)

因为AOF持久化是通过保存被执行的写命令来记录数据库状态的,所以随着服务器运行时间的流逝,AOF文件中的内容会越来越多,文件的体积也会越来越大,如果不加以控制的话,体积过大的AOF文件很可能对Redis服务器、甚至整个宿主计算机造成影响
AOF文件重写的原理:为了解决AOF文件体积膨胀的问题,Redis提供了AOF文件重写(rewrite)功能。通过该功能,Redis服务器可以创建一个新的AOF文件来替代现有的AOF文件,新旧两个AOF文件所保存的数据库状态相同,但新AOF文件不会包含任何浪费空间的冗余命令,所以新AOF文件的体积通常会比旧AOF文件的体积要小得多

如果AOF文件的体积越大,使用AOF文件来进行数据还原所需的时间就越多。AOF重写之后,更小的AOF文件可以更快地被Redis加载
重写后AOF文件变小的原因有:

  1. 进程内已经超时的数据不再写入文件
  2. 旧的AOF文件含有无效命令,如del key1、hdel key2、srem keys、set a111、set a222等。重写使用进程内数据直接生成,这样新的AOF文件只保 留最终数据的写入命令条写命令可以合并为一个,如:lpush list a、lpush list b、lpush list c可以转化为:lpush list a b c。为了防止单条命令过大造成客户端缓冲区溢出,对于list、set、hash、zset等类型操作,以64个元素为界拆分为多条

AOF重写时的内部过程
在这里插入图片描述
1)执行AOF重写请求
如果当前进程正在执行AOF重写,请求不执行并返回如下响应:ERR Background append only file rewriting already in progress
如果当前进程正在执行bgsave操作,重写命令延迟到bgsave完成之后再 执行,返回如下响应:Background append only file rewriting scheduled
2)父进程执行fork创建子进程,开销等同于bgsave过程
3.1)主进程fork操作完成后,继续响应其他命令。所有修改命令依然写 入AOF缓冲区并根据appendfsync策略同步到硬盘,保证原有AOF机制正确 性
3.2)由于fork操作运用写时复制技术,子进程只能共享fork操作时的内 存数据。由于父进程依然响应命令,Redis使用“AOF重写缓冲区”保存这部 分新数据,防止新AOF文件生成期间丢失这部分数据。
4)子进程根据内存快照,按照命令合并规则写入到新的AOF文件。每 次批量写入硬盘数据量由配置aof-rewrite-incremental-fsync控制,默认为 32MB,防止单次刷盘数据过多造成硬盘阻塞
5.1)新AOF文件写入完成后,子进程发送信号给父进程,父进程更新 统计信息,具体见info persistence下的aof_*相关统计
5.2)父进程把AOF重写缓冲区的数据写入到新的AOF文件
5.3)使用新AOF文件替换老文件,完成AOF重写

六 重启加载 (load)

加载AOF的流程与原理
因为AOF文件里面包含了重建数据库状态所需的所有写命令,所以服务器只要读入并重新执行一遍AOF文件里面保存的写命令,就可以还原服务器关闭之前的数据库状态
Redis读取AOF文件并还原数据库状态的详细步骤如下:
①创建一个不带网络连接的伪客户端(fake client):因为Redis的命令只能在客户端上下文中执行,而载入AOF文件时所使用的命令直接来源于AOF文件而不是网络连接,所以服务器使用了一个没有网络连接的伪客户端来执行AOF文件保存的写命令,伪客户端执行命令的效果和带网络连接的客户端执行命令的效果完全一样
②从AOF文件中分析并读取出一条写命令
③使用伪客户端执行被读出的写命令
④一直执行步骤2和步骤3,直到AOF文件中的所有写命令都被处理完毕为止
当完成以上步骤之后,AOF文件所保存的数据库状态就会被完整地还原出来,整个过程如下图所示:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值