?作者简介:小明java问道之路,2022年度博客之星全国TOP3,专注于后端、中间件、计算机底层、架构设计演进与稳定性建工设优化。文章内容兼具广度深度、大厂技术方案,对待技术喜欢推理加验证,就职于知名金融公司后端高级工程师。
? 热衷分享,喜欢原创~ 关注我会给你带来一些不一样的认知和成长。
? 2022博客之星TOP3 | CSDN博客专家 | 后端领域优质创作者 | CSDN内容合伙人
? InfoQ(极客邦)签约作者、阿里云专家 | 签约博主、51CTO专家 | TOP红人、华为云享专家
?如果此文还不错的话,还请?关注、点赞、收藏三连支持?一下博主~
? 文末获取联系 ? ?? 精彩专栏推荐订阅收藏 ??
专栏系列(点击解锁) | 学习路线(点击解锁) | 知识定位 |
?Redis从入门到精通与实战? | Redis从入门到精通与实战 | 围绕原理源码讲解Redis面试知识点与实战 |
?MySQL从入门到精通? | MySQL从入门到精通 | 全面讲解MySQL知识与企业级MySQL实战 |
?计算机底层原理? | 深入理解计算机系统CSAPP | 以深入理解计算机系统为基石,构件计算机体系和计算机思维 |
Linux内核源码解析 | 围绕Linux内核讲解计算机底层原理与并发 | |
?数据结构与企业题库精讲? | 数据结构与企业题库精讲 | 结合工作经验深入浅出,适合各层次,笔试面试算法题精讲 |
?互联网架构分析与实战? | 企业系统架构分析实践与落地 | 行业最前沿视角,专注于技术架构升级路线、架构实践 |
互联网企业防资损实践 | 互联网金融公司的防资损方法论、代码与实践 | |
?Java全栈白宝书? | 精通Java8与函数式编程 | 本专栏以实战为基础,逐步深入Java8以及未来的编程模式 |
深入理解JVM | 详细介绍内存区域、字节码、方法底层,类加载和GC等知识 | |
深入理解高并发编程 | 深入Liunx内核、汇编、C++全方位理解并发编程 | |
Spring源码分析 | Spring核心七IOC/AOP等源码分析 | |
MyBatis源码分析 | MyBatis核心源码分析 | |
Java核心技术 | 只讲Java核心技术 |
本文目录
本文目录
本文导读
一、什么是Redis AOF
二、如何开启AOF持久化
三、AOF的原理
1、AOF持久化实现
2、AOF数据恢复
3、AOF三种写回硬盘策略
4、AOF重写机制
5、为什么Redis AOF要先执行命令后写日志?
四、AOF和RDB对比
五、Redis4.0的混合持久化模式
总结
本文导读
本文为Redis持久化系列第二篇,上一篇【Redis】Redis持久化之RDB详解,本文讲解兼具广度与深度,首先讲解什么是RedisAOF、如何开启AOF持久化,深入其AOF的原理,AOF持久化实现、AOF数据恢复、AOF三种写回硬盘策略、AOF重写机制,解析RedisAOF要先执行命令后写日志,以及在实战过程中AOF和RDB对比,最后扩展Redis4.0新特性的混合持久化模式。
一、什么是Redis AOF
Redis提供了两种持久性机制:一种是RDB也称为快照模式,一种是AOF日志也称为追加模式。
AOF是一个日志文件,Redis的每个命令都将以AOF格式写入AOF文件,AOF日志仅记录修改内存的指令,AOF日志记录不同于MySQL先写入日志然后再执行操作(两阶段提交),AOF是执行成功的命令,然后记录命令在日志文件中,当需要恢复时,直接导入AOF文件以执行其中的记录,并且记录是实时的,AOF日志存储Redis服务器的顺序指令序列。
二、如何开启AOF持久化
AOF 机制默认处于未开启状态,通过在配置文件中将appendonly参数配置为yes来启用AOF持久性。
#修改配置文件:vim /etc/redis/redis.confappendonly yes # 把 no 改为 yes#确定存储文件名是否正确appendfilename "appendonly.aof"#重启服务:sudo /etc/init.d/redis-server restart
三、AOF的原理
每当修改Redis的命令时,服务器都会将该命令写入appendonly.aof 文件,该文件存储服务器执行的所有修改(成功的)命令。因此,只要服务器执行aof文件,可以达到恢复数据的目的,这个过程也称为命令重演。
1、AOF持久化实现
AOF持久性的实现可以分为:命令追加( append ,当AOF持久性功能打开时,Redis将在执行写入命令后,以协议格式(即RESP,Redis客户端和服务器之间的通信协议)将执行的写入命令附加到Redis服务器维护的AOF缓冲区的末尾。)、文件写入( write,Redis将调用flushAppendOnlyFile函数,以确定是否需要在每个事件周期结束之前将AOF缓存中的内容写入并同步到AOF文件)、文件同步( sync )、文件重写(rewrite)和重启加载(load)这几步。如下图所示
Redis将在执行写操作命令会将命令追加到 server.aof_buf 缓冲区,所有写入命令都将添加到AOF缓存中,然后通过 write() 系统调用,将aof_buf 缓冲区中数据写入aof文件。此时,数据还没有写入硬盘,而是复制到内核缓冲区的页面缓存 page cache,等待内核将数据写入硬盘,内核缓冲区中的数据何时写入硬盘由内核决定。
AOF缓存将根据相应的策略与硬盘同步,AOF日志将越来越大就需要定期重写以实现压缩,当Redis重新启动时,可以加载AOF文件进行数据恢复。
2、AOF数据恢复
AOF文件包含重建Redis数据所需的所有写入命令,因此只要重新读入并执行保存在AOF文件中的写入命令,Redis就可以恢复Redis关闭前的状态。伪客户端是指 Redis命令只能在客户端的上下文中执行,用于加载AOF文件的命令直接来自AOF文件,而不是网络连接。因此,服务器使用没有网络连接的伪客户端来执行保存在AOF文件中的命令。伪客户端执行命令的效果与具有网络连接的客户端的效果完全相同。
3、AOF三种写回硬盘策略
Redis 3 种写回硬盘的策略,说的是在 redis.conf 配置文件中的 appendfsync 配置项可以有以下 3 种参数可填。
Redis将在结束每个事件之前调用 flushAppendOnlyFile() 函数,以确定是否需要将AOF缓存中的内容写入并同步到AOF文件。flushAppendOnlyFile() 函数的行为由redis.conf 配置中appendfsync选项的值决定,有三个可选值:always、everysec和no。
Always(同步写回):在执行每个写操作命令后,AOF日志数据将同步写回硬盘;
Everysec(每秒写回):在执行每个写操作命令后,将命令写入AOF文件的内核缓冲区,然后每秒将缓冲区的内容写回硬盘;
No(操作系统控制的回写)意味着回写硬盘的时间不受Redis控制,而是转移到由操作系统所控制的回写入时间。也就是说,在执行每个写操作命令之后,该命令首先被写入AOF文件的内核缓冲区,然后操作系统决定何时将缓冲区内容写回硬盘。
这三种方法都有缺点:Always(同步写回),如果每次执行后命令都同步到瓷盘中,这会影响主线程的性能;Everysec(每秒回写)使用每秒回写一次的频率,以避免同步回写的性能开销。虽然它减少了对系统性能的影响,但如果发生中断,在最后一秒没有中断的命令操作仍将丢失;No(操作系统控制写回)。保存到磁盘的操作由操作系统控制。只要AOF中没有写回命令,一旦服务器停机,数据就会丢失;
写回策略 | 写回时间 | 优点 | 缺点 |
Always | 同步写回 | 可靠性高,最大程度保证安全性 | 性能开销大 |
Everysec | 每秒写回 | 性能适中 | 宕机时有1秒的数据丢失 |
No | 操作系统控制的回写 | 性能好 | 宕机存在丢失数据较大 |
4、AOF重写机制
重写机制,就是重写旧日志中的多个命令变为新日志中的一个命令。
假设对列表进行n次修改后,一条数据处于“***”状态。只有LPUSH u:list“**” 命令可以恢复数据,这为n-1个命令节省了空间,AOF重写后,日志文件将收缩,但将整个数据库的最新数据的操作日志写回磁盘仍然是一个耗时的过程。
重写不会阻塞主线程,重写过程由后台线程bgrewriteaof完成,这也是为了避免阻塞主线程,从而导致数据库性能下降。
Redis设置了一个AOF重写缓冲区,该缓冲区将在服务器创建子进程后使用,当Redis执行写命令时,它将同时向AOF缓冲区和AOF重写缓冲区发送写命令。当子进程完成AOF重写时,它将向父进程发送信号。在接收到信号后,父进程将调用信号处理函数将AOF重写缓冲区中的所有内容写入新的AOF文件,以确保新AOF文件保存的数据库状态与服务器的当前状态一致,并重命名新的AOF文件,自动覆盖现有AOF文件并完成新旧文件的替换继续处理客户端请求命令。
5、为什么Redis AOF要先执行命令后写日志?
Redis在向AOF里面记录日志的时候,不会首先检查这些命令。因此,如果它先记日志然后执行命令,则可能会在日志中记录错误的命令,Redis在使用日志恢复数据时可能会出错,如果Redis也先写日志,然后再操作,那么AOF日志中会有许多无效/错误的命令记录。
与MySQL和其他数据库的事务机制相比,Redis事务可以称为弱事务。如果事务中发生错误,将继续执行。如果事务失败,Redis不会回滚,对于此类事务,将有许多命令无法成功修改数据,如果先写日志,也会有很多无效的命令。
这两种风险都与AOF写回磁盘的时间有关。如果控制线写命令,再写AOF日志就可以解决这两个问题。
四、AOF和RDB对比
RDB持久化 | AOF持久化 |
---|---|
全量备份,一次保存整个数据库。 | 增量备份,一次只保存一个修改数据库的命令。 |
每次执行持久化操作的间隔时间较长。 | 保存的间隔默认为一秒钟(Everysec) |
数据保存为二进制格式,其还原速度快。 | 使用文本格式还原数据,所以数据还原速度一般。 |
执行 SAVE 命令时会阻塞服务器,但手动或者自动触发的 BGSAVE 不会阻塞服务器 | AOF持久化无论何时都不会阻塞服务器。 |
1、进行数据恢复时,既有 dump.rdb文件,又有 appendonly.aof 文件,应该首先通过appendonly.aof 恢复数据,这可以最大程度地确保数据安全。
2、只需要数据备份,不太关心一小部分数据的丢失,那么可以使用RDB模式,RDB文件也易于迁移并放入多个实例中进行数据恢复
五、Redis4.0的混合持久化模式
Redis 4.0的新特性是混合持久化模式,混合持久化模式同时使用RDB快照和AOF日志的混合持久模式,将RDB文件内容和增量AOF文件内容存储在同一个文件(相同的AOF格式文件)中,可以通过配置参数 aof-use-rdb-preamble 来启用混合持久性模式,config get aof-use-rdb-preamble命令进行查看。
由于RDB快照数据和AOF日志数据存储在同一个文件中,因此AOF格式文件不再只存储全部AOF日志,而是第一部分存储RDB快照,第二部分存储从RDB快照持久化开始到持久化结束的增量AOF日志。因此,RDB数据通常占大多数,AOF日志只是增量日志的一小部分
在混合持久策略下,当重新启动下一个Redis实例时,首先加载RDB快照的内容,然后重放增量AOF日志。这可以取代以前的RDB完全导入或AOF完全重放。
总结
本文为Redis持久化系列第二篇,上一篇【Redis】Redis持久化之RDB详解,本文讲解兼具广度与深度,首先讲解什么是RedisAOF、如何开启AOF持久化,深入其AOF的原理,AOF持久化实现、AOF数据恢复、AOF三种写回硬盘策略、AOF重写机制,解析RedisAOF要先执行命令后写日志,以及在实战过程中AOF和RDB对比,最后扩展Redis4.0新特性的混合持久化模式。