Redis的AOF持久化

Redis的AOF持久化

介绍

AOF持久化是Redis中的一种数据持久化机制,它通过将执行的所有写操作命令按照顺序保存到文件中来实现数据状态的持久化。当需要恢复数据时,系统只需重新执行这些命令即可。

例如,当在Redis中执行以下命令时:

sh 复制代码
redis> set msg 1
redis> set msg 2
redis> set msg 3

相应的AOF文件内容将会是(不是最终格式,只是方便观察写成这样):

txt 复制代码
select 0
set msg 1
set msg 2
set msg 3

这里的select 0是Redis系统自动加入的命令,其他则是用户执行的命令。AOF的名字"append of file"(文件追加)正是来源于这种追加命令到文件的行为。

在配置文件中,可以通过设置appendonly no/yes来关闭或开启AOF功能。

实现机制

Redis在内存中维护一个名为aof_buf的缓冲区,该缓冲区记录了两次写入文件操作之间的所有命令。每当执行一个命令时,它就会被追加到此缓冲区中。

Redis通过一个名为serverCron的定时任务机制(默认每100毫秒执行一次)来定期调用write方法,将aof_buf中的数据写入文件,并清空这个缓冲区。需要注意的是,这个write操作并不是直接写入文件,而是先写入操作系统的内核缓冲区,然后再在合适的时机同步到磁盘。为了控制数据的及时性和减少延迟,可以使用fsyncfdatasync命令来强制同步数据。

Redis提供了三种fsync调用时机的配置选项,通过appendfsync来设置:

  • always:每次调用write函数后立即执行fsync。
  • everysec:每隔一秒执行一次fsync,这个操作由另一个线程完成。
  • no:不执行任何操作,完全由操作系统决定何时同步。

默认配置为everysec。不同的配置选项在数据安全性和性能之间提供了不同的平衡。如果操作系统自身配置的频率较快时,会出现无需等到每秒调用就已经写入的情况。 。

AOF文件的载入

当Redis服务启动时,它会创建一个伪造的客户端,因为Redis的所有命令都必须在客户端上下文中执行。这个伪造的客户端不是从网络接收命令,而是直接从AOF文件读取命令。按照文件中的命令顺序执行,即可恢复数据库状态。

AOF重写

随着数据库运行时间的增长,AOF文件的体积可能会变得非常大。例如:

shell 复制代码
redis> set msg 1
redis> set msg 2
...
redis> set msg 100000000001

在这种情况下,AOF文件会变得非常大。此时,可以在客户端中输入bgrewriteaof命令来进行后台压缩。重写后的文件内容将不再是上述的许多条命令,而是最终的数据库状态,例如:

shell 复制代码
redis> set msg 100000000001

在AOF重写的过程中,Redis会遍历当前数据库中的所有键值对,并将它们当前的状态以命令的形式封装后写入到新的AOF文件中。这种方法能够确保只保存最终的数据库状态,从而显著减小AOF文件的体积。

在这个过程中,有一个重要的限制是单条命令的参数个数上限为64个。这个限制由宏AOF_REWRITE_ITEMS_PER_CMD定义。如果一个命令的参数超过了这个上限,Redis会将它分解成多个命令来实现。例如:

shell 复制代码
redis> rpush list1 1 ... 64
redis> rpush list1 65 ... 128

这样做可以保证即使在处理大量数据时,AOF文件也能有效地被重写。

AOF重写的过程使用bgrewriteaof命令来启动,其中"bg"代表后台(background)重写。这是因为AOF重写会涉及大量的IO操作,可能会花费较长时间。为了避免阻塞服务器的正常运行,Redis会创建一个子进程来执行实际的写入操作。

在这个子进程写入数据的同时,父进程仍然可以接收新的命令。为了处理这种情况,确保数据的一致性,Redis在内存中维护了一个aof_rewrite_buf缓冲区。在重写期间,新增的所有命令不仅会保留在原始的aof_buf中(以便正常写入现有的AOF文件),同时也会被复制到aof_rewrite_buf中。一旦重写操作成功完成,Redis会将aof_rewrite_buf中的数据追加到重写后的AOF文件中。然后,系统会用新的AOF文件替换掉旧的文件。

在整个重写过程中,服务器的运行几乎不会受到阻塞,唯一的例外是在信号处理阶段会短暂停顿,以完成文件的替换。通过这种方式,Redis能够在保证数据完整性的同时,最小化对服务性能的影响。

重点总结

  • AOF持久化通过记录所有修改数据库状态的写命令来保存数据状态。
  • 命令首先保存在AOF缓冲区,然后定期写入并同步到AOF文件。
  • appendfsync选项对数据安全性和性能有重要影响。
  • 通过载入并执行AOF文件中的命令,Redis可以还原数据库状态。
  • AOF重写能生成体积更小的新AOF文件,而不需要读取、分析或写入现有的AOF文件。
  • 执行BGREWRITEAOF命令时,Redis会维护一个AOF重写缓冲区,用于记录子进程创建新AOF文件期间的所有写命令。完成后,这些命令会被追加到新的AOF文件中,确保两个文件的数据库状态一致。
相关推荐
BergerLee8 小时前
对不经常变动的数据集合添加Redis缓存
数据库·redis·缓存
huapiaoy8 小时前
Redis中数据类型的使用(hash和list)
redis·算法·哈希算法
【D'accumulation】9 小时前
令牌主动失效机制范例(利用redis)注释分析
java·spring boot·redis·后端
Cikiss9 小时前
微服务实战——SpringCache 整合 Redis
java·redis·后端·微服务
一休哥助手10 小时前
Redis 五种数据类型及底层数据结构详解
数据结构·数据库·redis
盒马盒马11 小时前
Redis:zset类型
数据库·redis
Jay_fearless13 小时前
Redis SpringBoot项目学习
spring boot·redis
Wang's Blog13 小时前
Redis: 集群环境搭建,集群状态检查,分析主从日志,查看集群信息
数据库·redis
wclass-zhengge19 小时前
Redis篇(最佳实践)(持续更新迭代)
redis·缓存·bootstrap
Dylanioucn19 小时前
【分布式微服务云原生】探索Redis:数据结构的艺术与科学
数据结构·redis·分布式·缓存·中间件