1. Redis 持久化方式

Redis持久化是指将数据写入持久化存储,如SSD。Redis提供了多种持久化方法:

  • RDB(Redis Database):RDB持久化是指Redis在指定的时间间隔内对数据集进行即时快照操作。
  • AOF (Append Only File):服务器以日志的形式将所有的写操作记录下来,只允许文件追加操作,不允许改写文件。服务重启后可以根据记录的写操作重新构建原始数据。命令使用与Redis协议本身相同的格式记录。
  • No persistence:不适用持久化。通常用于缓存。
  • RDB + AOF:同时使用RDB和AOF。

2. RDB

Redis RDB(Redis Database Backup)是 Redis 的一种持久化方式,用于将内存中的数据保存到磁盘上。在了解 Redis RDB 的工作原理之前,先了解一下 RDB 的特点:

  • RDB 是 Redis 的快照持久化方式,通过定期将内存中的数据快照保存到磁盘文件中,可以在服务启动时快速加载数据。
  • RDB 生成的文件是一个二进制文件,通常以 .rdb 作为扩展名,包含了 Redis 数据在某个时间点的快照。
  • RDB 是全量备份方式,即在每次备份时都会保存整个数据集的快照,因此生成的文件可能比较大。

了解了 RDB 的特点,接下来详细介绍 Redis RDB 的工作原理:

2.1 触发条件

Redis 会周期性地执行 RDB 操作,主要有以下两种触发条件:

  • 主动触发: 通过客户端发送 SAVEBGSAVE 命令,或者通过配置文件中的 save 指令设置定时保存规则。
  • 被动触发: 当满足条件时,Redis 会自动执行后台保存操作。比如在主从复制中,当从节点连接主节点时,主节点会触发后台保存操作。

2.2 快照生成

一旦触发了保存操作,Redis 将会开始生成 RDB 文件,过程如下:

  • Redis 主进程会调用 fork() 创建一个子进程,子进程负责生成 RDB 文件,而主进程则继续处理客户端请求。
  • 子进程会遍历所有的数据结构,并将其序列化到一个临时的内存缓冲区中。
  • 当子进程完成数据的序列化操作后,它将会将内存缓冲区的数据写入到一个临时的 RDB 文件中。

当临时 RDB 文件生成完毕后,Redis 会将其替换原先的 RDB 文件。这一步是原子性的,保证了在替换过程中不会影响到正在访问 Redis 的客户端。一旦 RDB 文件替换完成,Redis 就会向客户端发送一个持久化完成的信号,通知客户端持久化操作已完成。

默认情况下,当 Redis 重启时,它会尝试从磁盘上加载最近一次保存的 RDB 文件,并将其加载到内存中,恢复数据到原来的状态。

2.3 优缺点

RDB 有以下几个优点:

  • RDB 是 Redis 数据的一个非常进程的单文件时间点表示。RDB 文件分成适合备份。
  • RDB 是一个可以传输到远程数据中心或Amazon S3(加密后)的压缩文件,所以它非常适合灾后恢复。
  • RDB 最大限度的提高了 Redis 的性能,因为 Redis 父进程持久化要做的唯一工作就是派生一个完成所有琦玉工作的子进程。父进程永远不会执行磁盘 I/O 或类似操作。
  • 与 AOF 相比,RDB 使用大数据集重启时更快。
  • 在副本上,RDB支持重启和故障转移后的部分重新同步

同时 RDB 也有以下缺点:

  • 如果你需要在 Redis 停止工作时(如断电)将丢失的数据降到最低,那 RDB 并不适合。你可以配置不同的保存点,每个保存点都会生成一个 RDB 快照(例如,在至少五分钟内对数据集进行 100 次写操作后,你可以设置多个保存点)。然而,通常你会每隔五分钟或更长时间创建一个 RDB 快照,因此如果 Redis 由于任何原因停止工作而没有正确关闭,你应该准备好丢失最近几分钟的数据。
  • RDB 需要经常调用 fork() 函数以便使用子进程将数据持久化到磁盘上。如果数据集很大,fork() 可能会耗费较长的时间,并且如果数据集非常大且 CPU 性能不佳,可能会导致 Redis 在一些毫秒甚至一秒内停止为客户端提供服务。AOF 也需要调用 fork(),但频率较低,你可以调整日志重写的频率,而不会对持久性产生任何影响。

3. AOF

AOF 是 Redis 以日志的形式记录下每一个写操作,即 Redis 会将执行过的所有的写操作记录下来,重启之后会读取该文件来重新构建数据。

默认情况下,Redis 是没有开启 AOF 的,开启 AOF 需要修改文件:

# 默认配置
# appendonly no
# 启用 AOF 
appendonly yes

3.1 触发机制

Redis AOF(Append Only File)的触发机制是指确定何时将缓冲区中的写入操作同步到磁盘上的策略。Redis 提供了三种 AOF 文件同步策略,分别是 alwayseverysecno。以下是这三种策略的详细介绍:

  • always: 在这种策略下,Redis 会将每个写入操作都立即同步到磁盘上,确保了数据的完整性和持久性。这是最安全的策略,但也会对性能产生影响,因为每个写入操作都需要等待同步完成才能继续执行后续操作。
      appendfsync always
    
  • everysec: 这是默认的 AOF 同步策略。在这种策略下,Redis 每秒钟会将缓冲区中的写入操作同步到磁盘上一次。这种策略提供了良好的性能和较好的持久性,因为数据最多会丢失一秒钟。
      appendfsync everysec
    
  • no: 这种策略下,Redis 不会主动将写入操作同步到磁盘上,而是完全依赖操作系统的缓存机制来处理。这样可以获得最好的性能,但也会增加数据丢失的风险,因为操作系统可能会因为各种原因而延迟将数据同步到磁盘上。
      appendfsync no
    

通常情况下,everysec 是一个合理的折衷方案,它在性能和持久性之间取得了平衡。

处理上面介绍的三种策略可以被动触发 AOF 写入,还可以通过BGREWRITEAOF命令来主动触发 AOF 写入。

3.2 优缺点

AOF 有以下几个优点:

  • 使用 AOF,Redis 更加耐久:你可以有不同的 fsync 策略:完全不同步、每秒同步一次、每个查询都同步。即使使用每秒同步一次的默认策略,写入性能仍然非常出色。fsync 是使用后台线程执行的,当没有 fsync 在进行时,主线程会尽力执行写入操作,因此你只会丢失一秒钟的写入数据。
  • AOF 日志是一个追加日志,因此不存在搜索,也不会因为断电而导致损坏问题。即使由于某种原因(磁盘已满或其他原因)日志以一个半写的命令结尾,redis-check-aof 工具也能轻松修复。
  • 当 AOF 文件过大时,Redis 能够在后台自动重写 AOF。重写过程是完全安全的,因为在 Redis 继续追加到旧文件的同时,一个全新的文件会被生成,其中包含创建当前数据集所需的最小操作集。一旦第二个文件准备好,Redis 会切换两个文件,并开始追加到新文件。
  • AOF 包含了一系列操作,依次排列在易于理解和解析的格式中。你甚至可以轻松地导出 AOF 文件。例如,即使你不小心使用FLUSHALL命令刷新了所有数据,只要在此期间没有执行日志重写,你仍然可以通过停止服务器、移除最新的命令,然后再次启动 Redis 来保存数据集。

同时 RDB 也有以下缺点:

  • AOF 文件通常比相同数据集的等效 RDB 文件更大。
  • 根据确切的 fsync 策略,AOF 可能比 RDB 更慢。通常情况下,将 fsync 设置为每秒一次时,性能仍然非常高;而在禁用 fsync 的情况下,即使在高负载下,它也应该与 RDB 一样快。尽管如此,RDB 能够在大量写入负载的情况下,提供更多关于最大延迟的保证。

7.0 以前的 Redis 在使用 AOF 时:

  • 如果在重写期间有写操作到数据库,AOF 可能会消耗大量内存(这些操作会被缓存在内存中,并在重写结束时写入新的 AOF 文件)。
  • 在重写期间到达的所有写入命令都会被写入磁盘两次。
  • Redis 可以在重写结束时冻结写入和将这些写入命令同步到新的 AOF 文件。

4. 选 RDB?还是 AOF?

如果你希望获得与 PostgreSQL 类似的数据安全程度,一般建议同时使用这两种持久化方法。

如果你非常关心你的数据,但在灾难发生时可以接受几分钟的数据丢失,那么你可以只使用 RDB。

虽然有许多用户仅使用 AOF,但我们不建议这样做,因为定期使用 RDB 快照是进行数据库备份、快速重启以及在 AOF 引擎出现错误时的良好实践。

4.1 优先级

如果同时存在 dump.rdb 和 appendonly.aof, 那 Redis 重启后构建数据会优先使用哪个?

# AOF and RDB persistence can be enabled at the same time without problems.
# If the AOF is enabled on startup Redis will load the AOF, that is the file
# with the better durability guarantees.

配置文件已经给出了结果,如果启用了 AOF,那么重新构建数据时会使用 appendonly.aof 而非 dump.rdb。

4.2 混合模式

要开启混合模式,需要修改配置文件,将 aof-use-rdb-preamble 设置为 yes

启用混合模式后,RDB 镜像做全量持久化,AOF 做增量持久化:先使用 RDB 进行快照存储,然后使用 AOF 持久化记录所有的写操作,当满足重写策略或手动触发重写时,将最新的数据存储为新的 RDB 记录。这样重启服务的时候会从 RDB 和 AOF 两部分恢复数据,既保证了数据的完整性,又提高了恢复数据的性能。

startup

5. 纯缓存模式

除了持久化,Redis也可以单纯的作为高性能的内存数据存储系统来使用。

5.1 关闭 RDB

要关闭 RDB,只需要在配置文件进行如下设置即可:

save ""

该模式下我们仍可以通过SAVEBGSAVE命令来生成 RDB 文件。

5.2 关闭 AOF

要关闭 AOF,只需要在配置文件进行如下设置即可:

appendonly no

该模式下我们仍可以通过BGREWRITEAOF命令来生成 AOF 文件。


孟斯特

声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。

Author: mengbin

blog: mengbin

Github: mengbin92

cnblogs: 恋水无意

腾讯云开发者社区:孟斯特