Redis 持久化机制:RDB 和 AOF 深度解析

一、引言

在现代应用中,数据的持久化是确保数据可靠性的重要环节。Redis 作为一个高性能的内存数据库,提供了两种主要的持久化机制:RDB(Redis DataBase)和 AOF(Append-Only File)。本文将详细介绍这两种持久化方式的原理、优缺点、使用场景及配置方法,以帮助读者更好地理解和选择适合自己应用的持久化策略。


二、RDB 快照机制

2.1、什么是 RDB ?

RDB 持久化是把当前进程数据生成快照保存到硬盘的过程,触发 RDB 持久化过程分为手动触发和自动触发。

2.2、如何触发?

触发分为两种,第一种是手动触发,手动触发又分为两种命令:

  1. save 命令:阻塞当前 Redis 服务器,直到 RDB 过程完成为止,对于内存比较大的实例造成长时间阻塞,基本不采用。
  2. bgsave 命令:Redis 进程执行 fork 操作创建子进程,RDB 持久化过程由子进程负责,完成后自动结束。阻塞只发生在 fork 阶段,⼀般时间很短。

Redis 内部的所有涉及 RDB 的操作都采用类似 bgsave 的方式。

除了手动触发之外,还会自动触发,这个自动触发的情况呢就有三种了:

  1. 满足 Redis 配置文件中的配置,如 save m n 表示 m 秒内数据集发生了 n 次修改,就会自动 RDB 持久化。
  2. 从节点触发全量复制的时候,主节点就会自动进行 RDB 持久化,然后将 RDB 文件发送给从节点。那如何会触发全量复制呢?下面会详细介绍。
  3. 执行 shutdown 命令关闭 Redis 时,也会触发 RDB 持久化。

2.3、bgsave 命令运行流程

首先执行 bgsave 命令的时候,Redis 父进程会判断是否存在其他正在执行的子进程,如 RDB / AOF 子进程,如果存在的话 bgsave 命令直接返回。

然后父进程执行 fork 创建子进程,这个子进程和 Java 中的子进程可不太一样,这是创建一个与父进程几乎完全相同的新进程。新进程称为子进程,它将继承父进程的所有资源,如内存空间、文件描述符等,就是直接共用一块物理内存。然后父进程可以继续执行业务逻辑,但是如果说父进程的业务逻辑有修改这部分内存中的数据的话,父进程就会单独开一片内存来放这部分修改的数据,这就是写时复制机制,只有父进程需要修改数据时,才会进行数据的复制,其他的数据继续共享,以此来大大减少内存的使用和提高性能。因为在大多数情况下,子进程并不需要立即复制所有的内存数据。

最后,创建好这个子进程之后,就由子进程执行完成 RDB。注意,此时子进程复制的是开始执行 bgsave 时的数据,因为修改之后的数据只有父进程有,接着执行完成之后,这就是一个新的 RDB 文件,直接替换掉原来的 RDB 文件。

2.4、什么时候会触发全量复制

我个人认为触发全量复制的时机就两种:

  1. 第一种是第一次连接主节点的时候,这时候会触发全量复制。举个例子,假如我写了十篇博客,有人想跟着我学习,那因为是第一次来找我要这博客,他手上肯定是没有数据的,所以我直接全部发给他。
  2. 第二种是缓冲区数据不够的时候,这时候也会触发全量复制。那什么是缓冲区呢?还是这个例子,十篇博客发了出去,但是这个人是之前就跟着我学了的,他先是把这十篇全部学完了,但是我又写了三篇,并没有发给他,这三篇就是缓冲区的,但是假如说他差的不只是三篇,那这时候就是我所说的缓冲区数据不够了,我也懒得去管你差了几篇,就直接都发给你了。

2.5、RDB 文件的优缺点

RDB 是一个紧凑压缩的二进制文件,代表 Redis 在某个时间点上的数据快照,非常适用于备份,全量复制等场所。比如每六个小时执行 bgsave 备份,并且把每个 RDB 文件复制到远程机器或者文件中(如 hdfs)用于灾备/

Redis 加载 RDB 恢复数据远远快于 AOF 的方式。

RDB 方式数据没办法做到实时持久化 / 秒计持久化。因为 bgsave 每次运行都要执行 fork 创建子进程,属于重量级操作,频繁执行成本过高。

RDB 文件使用特定的二进制格式保存,Redis 版本演进过程有多个 RDB 版本,兼容性可能有风险。


三、AOF 持久化机制

3.1、什么是 AOF ?

AOF 和 RDB 一样,也是一种持久化机制,它记录每一个写入命令,以追加的方式将数据持久化到硬盘中。AOF 文件通常以 .aof 为后缀。

3.2、如何触发?

每次写一条命令就会触发,但是默认是不开启 AOF 的,需要修改 Redis 的相关配置,找到配置文件中的 appendonly 这个属性,后面修改成 yes 就行了。

3.3、AOF 工作流程

首先是收到一个操作命令,然后所有的写入命令会追加到 aof_buf(缓冲区)中,这个缓冲区位于内存里,用于临时存储写入命令。然后就会进行 Sync 文件同步,这一步会严重影响性能,然后就是进行文件重写,因为用户的每一步操作都要记录,所以这个 AOF 文件会越来越大,就要进行定期的文件重写。

文件重写又分为自动重写和手动重写,自动重写就是修改 Redis 的配置文件,根据 auto-aof-rewrite-min-size 和 auto-aof-rewrite-percentage 参数确定自动触发时机。手动重写就是执行 bgrewriteaof 这个指令了。那新的 AOF 文件存储的是什么呢?他就是以二进制的形式存储的你表中的最终结果,比如说你先是 set key 111,然后再执行 set key 222,最后执行 set key 111,没有进行文件重写的 AOF 文件就会记录这三条指令,重写之后就是以二进制的形式把 key 的值设置成 111。最后当Redis服务重启时,会加载AOF文件进行数据恢复(有 AOF 一定优先加载 AOF)。

3.4、AOF 重写流程

首先呢肯定是先执行重写请求,如果当前进程正在执行 AOF 重写,请求不执行。如果当前进程正在执行 bgsave 操作,重写命令延迟到 bgsave 完成之后再执行。然后父进程执行 fork 创建子进程,这里的和上面 RDB 的一样,也是父子共用一块内存地址,如果要修改的话就把修改之后的数据放到缓冲区,所以子进程只有 fork 之前的信息。最后子进程完成重写,发信号告诉父进程,然后父进程把缓冲区里面的命令追加到新的 AOF 文件中,最后的最后执行新 AOF 文件代替老的 AOF 文件。这个 AOF 重写流程就算是完成了。


四、总结

在本文中,我们深入探讨了 Redis 的两种主要持久化机制:RDB 和 AOF。RDB 通过生成数据快照的方式,实现高效的备份和恢复,非常适合对性能要求高、能够容忍一定数据丢失的场景。这种机制的优势在于其操作的高效性,能够快速加载数据,但在频繁写入的应用中,其阻塞特性可能会导致性能瓶颈。而 AOF 则以追加的方式记录每一个写入命令,确保数据的实时性和完整性,非常适合对数据一致性有严格要求的应用。这种机制虽然在文件大小和写入延迟上有一定的开销,但其可以通过自动重写和手动管理来优化。开发者在选择持久化策略时,需结合具体的业务需求、系统架构以及对数据安全的期望,做出明智的决策。


五、结语

在当今数据驱动的时代,数据持久化的重要性愈加凸显。无论是构建实时应用、在线服务,还是进行大数据分析,良好的持久化策略都能为我们提供坚实的基础。作为开发者,我们不仅要掌握技术的细节,更要理解其背后的原理与适用场景。选择 RDB 以追求高性能,还是使用 AOF 以确保数据的完整性,都是需要深入思考的决策。

让我们在不断探索与实践中,提升自己的技术水平和解决问题的能力。未来的技术世界充满机遇与挑战,期待着我们每个人的创新与贡献。让我们携手共进,迎接每一个挑战,努力构建更高效、更可靠的系统,推动技术的进步与发展。记住,每一步都在为我们的职业生涯和技术成长奠定基础,唯有不断学习与实践,才能在这个快速发展的行业中立足并发光发热!

上一篇:kaptcha依赖maven无法拉取的问题


下一篇:java -jar启动 报错: Error: Unable to access jarfile