RDB和AOF持久化

参考:Redis AOF 持久化详解 (juejin.cn)

Redis 提供了 RDBAOF 两种数据持久化方案:

  • RDB —— 快照
  • AOF —— 增量日志

1 RDB 持久化

将当前 Redis 进程的内存数据生成时间点快照(point-in-time snapshot),序列化成二进制,写入磁盘文件,默认文件名为 dump.rdb。

1.1 RDB 使用

RDB 持久化功能可以通过指令触发和基于 redis.conf 配置文件自动触发两种:

  • 指令触发
save 指令

该指令会阻塞当前 Redis 服务器,执行 save 指令期间,Redis 不能处理其他命令,直到 RDB 过程完成为止。

bgsave 指令

执行该命令时,Redis 会在后台异步执行快照操作,此时 Redis 仍然可以响应客户端请求。具体操作是 Redis 进程执行 fork 操作创建子进程,RDB 持久化过程由子进程负责,完成后自动结束。Redis 只会在 fork 期间发生阻塞,但是一般时间都很短。但是如果 Redis 数据量特别大, fork 时间就会变长,而且占用内存会加倍,这一点需要特别注意。

  • redis.conf 配置自动触发

配置如下:

save 900 1    # 900 秒内如果至少有 1 个 key 的值变化,则触发 RDB
save 60 1000  # 60 秒内如果至少有 1000 个 key 的值变化,则触发 RDB

基于配置文件的自动触发使用的是 bgsave 指令,异步处理,不阻塞 Redis。

Redis 服务器的周期操作函数serverCron默认是每隔 100 毫秒执行一次检查,其中就会去检查 redis.conf 文件中 save 配置项的条件是否满足,如果满足就执行bgsave指令。

另外:

  1. 在执行 flushall (清空 Redis)的时候,会触发自动持久化,把 RDB 文件清空。
  2. 在 Redis 主从复制中,当从节点执行全量复制操作的时候,主节点会执行 bgsave 命令,并将 RDB 文件发送给从节点,该过程会自动触发 Redis 持久化。

1.2 RDB 流程

RDB 持久化调用bgsave 指令流程大致如下:

  1. 首先主进程fork 出一个子进程;
  2. 子进程将当前时刻 Redis 内存中的数据序列化成二进制,写入到磁盘中;
  3. 主进程继续处理客户端请求,通过 COW(Copy On Write)机制,复制一份内存中的数据,在新复制的数据上进行写操作。因此主进程可以继续处理客户端的请求,而不会影响子进程执行 RDB 操作的数据。

2 AOF 持久化

以独立日志的方式记录每次的写命令,并在 Redis 重启时去重新执行 AOF 文件中的命令以达到恢复数据的目的。

2.1 AOF 使用

Redis 默认使用的是 RDB 持久化,未开启 AOF 持久化。

通过在 redis.conf 文件中配置开启 AOF 持久化:

appendonly yes
appendfilename "appendonly.aof"

# appendfsync always
appendfsync everysec
# appendfsync no
  • appendonly yes

表示是否开启 AOF 持久化,默认是 no,不开启。

  • appendfilename "appendonly.aof"

表示 AOF 持久化写入的文件名。

  • appendfsync everysec

表示 AOF 持久化策略,有三种策略:

  1. always:同步持久化,每次发生数据变更会被立即记录到磁盘,性能差但数据完整性比较好。
  2. everysec:异步操作,每秒记录,如果一秒钟内宕机,有数据丢失。
  3. no:由操作系统保证数据同步到磁盘,linux 默认是 30 秒将缓冲区的数据回写硬盘。

通常选择 everysec ,兼顾安全性和效率。

2.2 AOF 流程

在这里插入图片描述

如上图所示,AOF 持久化功能的实现可以分为 命令追加 ( append )文件写入 ( write )文件同步 ( sync )文件重写(rewrite)重启加载(load)。其流程如下:

  1. 所有的写命令会追加到 AOF 缓冲区里面;
  2. AOF 缓冲区根据对应的策略向磁盘进行同步操作。
  3. 随着 AOF 文件越来越大,需要定期对 AOF 文件进行重写,达到压缩的目的。
  4. 当 Redis 重启时,可以加载 AOF 文件进行数据恢复。

2.2.1 AOF 数据恢复

AOF 文件里边记录了重建 Redis 数据所需的所有写命令,所以 Redis 只要读入并重新执行一遍 AOF 文件里边保存的写命令,就可以还原 Redis 关闭之前的状态。

在这里插入图片描述

详细流程如下:

  1. 创建一个不带网络连接的的伪客户端(fake client)。因为 Redis 的命令只能在客户端上下文中执行,而载入 AOF 文件时所使用的的命令直接来源于 AOF 文件而不是网络连接,所以服务器使用了一个没有网络连接的伪客户端来执行 AOF 文件保存的写命令,伪客户端执行命令的效果和带网络连接的客户端执行命令的效果完全一样的。
  2. 伪客户端从 AOF 文件中分析并取出一条写命令。
  3. 使用伪客户端执行被读出的写命令。
  4. 一直执行步骤 2 和步骤 3,直到 AOF 文件中的所有写命令都被处理完毕为止。

当完成以上步骤之后,AOF 文件所保存的数据库状态就会被完整还原出来。

2.2.2 AOF重写

因为 AOF 持久化是通过保存被执行的写命令来记录 Redis 状态的,所以随着 Redis 长时间运行,AOF 文件中的内容会越来越多,文件的体积也会越来越大,如果不加以控制的话,体积过大的 AOF 文件很可能对 Redis 甚至宿主计算机造成影响。

为了解决 AOF 文件体积膨胀的问题,Redis 提供了 AOF 文件重写( rewrite) 功能。通过该功能,Redis 可以创建一个新的 AOF 文件来替代现有的 AOF 文件。新旧两个 AOF 文件所保存的 Redis 状态相同,但是新的 AOF 文件不会包含任何浪费空间的冗余命令,所以新 AOF 文件的体积通常比旧 AOF 文件的体积要小得很多。

AOF 文件重写并不需要对现有的 AOF 文件进行任何读取、分析或者写入操作,而是通过读取服务器当前的Redis数据库状态来实现的。首先从Redis数据库中读取键现在的值,然后用一条命令去记录键值对,代替之前记录这个键值对的多条命令,这就是 AOF 重写功能的实现原理。

rewrite的触发机制主要有一下三个

  • 手动调用 bgrewriteaof 命令,如果当前有正在运行的 rewrite 子进程,则本次rewrite 会推迟执行,否则,直接触发一次 rewrite。
  • 通过配置指令手动开启 AOF 功能,如果没有 RDB 子进程的情况下,会触发一次 rewrite,将当前数据库中的数据写入 rewrite 文件。
  • 在 Redis 定时器中,如果有需要退出执行的 rewrite 并且没有正在运行的 RDB 或者 rewrite 子进程时,触发一次或者 AOF 文件大小已经到达配置的 rewrite 条件也会自动触发一次。

AOF 重写函数会进行大量的写入操作,调用该函数的线程将被长时间阻塞,所以 Redis 在子进程中执行 AOF 重写操作。

但是,在子进程进行 AOF 重写期间,主进程会继续处理客户端命令,这样会对现有数据库状态进行修改,从而导致数据库当前状态和 重写后的 AOF 文件所保存的数据库状态不一致。为此,Redis 设置了一个 AOF 重写缓冲区,这个缓冲区在服务器创建子进程之后开始使用,当主进程执行完一个写命令之后,它会同时将这个写命令发送给 AOF 缓冲区和 AOF 重写缓冲区。

在这里插入图片描述

当子进程完成 AOF 重写工作之后,它会向父进程发送一个信号,父进程在接收到该信号之后,会调用一个信号处理函数,并执行以下工作:

  1. 将 AOF 重写缓冲区中的所有内容写入到新的 AOF 文件中,保证新 AOF 文件保存的数据库状态和服务器当前状态一致。

  2. 对新的 AOF 文件进行改名,原子地覆盖现有 AOF 文件,完成新旧文件的替换。

  3. 继续处理客户端请求命令。

在整个 AOF 重写过程中,只有信号处理函数执行时会对 Redis 主进程造成阻塞,在其他时候AOF 重写都不会阻塞主进程。

3 RDB 和 AOF 优缺点比较

RDB 持久化

  • 优点
    1. 只有一个dump.rdb文件,方便持久化;
    2. 容灾性好,一个文件可以保存到安全的磁盘;
    3. 性能最大化,fork一个子进程来完成写操作,能够让主进程继续处理客户端请求。
    4. 数据集比较大的时候,比AOF启动效率高。
  • 缺点
    1. 数据安全性低。RDB是每间隔一段时间进行持久化,如果两次持久化之间Redis发生了故障,会导致数据丢失。

AOF 持久化

  • 优点
    1. 更安全。AOF持久化可以配置appendfsync属性,来决定持久化策略,如果使用always,可以做到没进行一次命令操作都记录到aof文件中一次;
    2. 通过append模式写文件,即使中途服务器宕机,也可以通过redis-check-aof工具解决数据一致性问题;
    3. AOF的重写机制可以优化aof文件的大小。
  • 缺点
    1. 一般来说,AOF文件比RDB文件更大,恢复的速度也更慢。
    2. 如果数据集比较大,使用AOF持久化的Redis启动会更慢。

4 RDB+AOF 混合型持久化方案

重启 Redis 的时候,很少会使用 RDB 方案来恢复内存状态,因为会存在丢失大量数据的问题。

通常使用 AOF 方案,重放日志恢复内存数据,但是 AOF 日志可能很大,重建数据的性能相对 RDB 来说要慢很多,会导致 Redis 启动耗费很长的时间。

因此,可以采用 RDB + AOF 混合型方案。

混合持久化,将 RDB 文件内容和增量 AOF 日志存在一起,这里的 AOF 日志不再是全量的日志,而是自 RDB 持久化开始到结束这段时间发生的增量 AOF 日志,通常来说这段时间的日志很小。

在 Redis 重启的时候,先加载 RDB 的内容,然后重放增量 AOF 日志就可以了,这样重启效率将会得到大幅提升。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值