【Redis】持久化机制最全解析

RDB持久化

RDB全称Redis Database Backup file(Redis数据备份文件)。通过将Redis数据集的快照保存到磁盘上的二进制文件中来实现。生成 RDB 文件的过程可以通过手动命令或自动触发。

实现原理

开始 BGSAVE

  • Redis 主进程接收到 BGSAVE 命令后,调用 fork 创建一个子进程,子进程会先复制主进程的页表(记录虚拟地址与物理地址的映射关系),而不是立即复制实际的内存数据。
  • 在 fork 完成后,父子进程共享相同的内存页,子进程负责生成 RDB 文件,主进程可以继续处理客户端请求。

生成 RDB 文件

  • 子进程根据页表,扫描 Redis 数据集,将每个键值对序列化为二进制格式,并写入到临时 RDB 文件中。
  • 序列化后的数据被写入到一个临时 RDB 文件中,以避免影响现有 RDB 文件的使用。
  • 写时复制(Copy-On-Write, COW)
    • 在生成 RDB 文件的过程中,如果主进程执行了写操作(如插入、更新、删除数据),操作系统会触发写时复制机制。COW 机制会为被修改的内存页创建一个副本,并将写操作应用到这个副本上,而不是直接修改共享的内存页。
    • 主进程在读取被修改的数据时,会从生成的副本中读取,而子进程则继续读取原始的内存页。这种机制确保了子进程在生成 RDB 文件时看到的是一致且稳定的数据快照,而主进程可以不受影响地继续处理新的写操作。

完成 RDB 文件

  • 子进程生成 RDB 文件后,将临时 RDB 文件重命名为正式的 RDB 文件,确保文件替换过程是原子的。

手动启用

Redis 提供了以下两个命令来手动生成 RDB 快照文件:

save # 同步保存操作,由Redis主进程来执行RDB,会阻塞所有命令
bgsave # 开启子进程执行RDB,避免主进程受到影响

这里说 Redis 主线程而不是主进程的主要是因为 Redis 启动之后主要是通过单线程的方式完成主要的工作。如果你想将其描述为 Redis 主进程,也没毛病。

定时启用

可以通过配置文件中的 save 选项进行定时触发RDB持久化。

save 900 1	#900(15分钟)之后,如果至少有1个key发生变化,Redis就会自动触发bgsave命令创建快照。

save 300 10	#300(5分钟)之后,如果至少有10个key发生变化,Redis就会自动触发bgsave命令创建快照。

save 60 10000	#60(1分钟)之后,如果至少有10000个key发生变化,Redis就会自动触发bgsave命

AOF持久化

AOF全称为Append Only File(追加文件)。通过将每次写操作记录到AOF文件中来实现。这种方式的特点是将 Redis 接收到的每个写命令都追加到文件末尾。

实现原理

AOF 持久化功能的实现可以简单分为 5 步:

  1. 命令追加(append):所有的写命令会追加到 AOF 缓冲区中。
  2. 文件写入(write):将 AOF 缓冲区的数据写入到 AOF 文件中。这一步需要调用write函数(系统调用),write将数据写入到了系统内核缓冲区之后直接返回了(延迟写)。
  3. 文件同步(fsync):AOF 缓冲区根据对应的持久化方式( fsync 策略)向硬盘做同步操作。这一步需要调用 fsync 函数(系统调用), fsync 针对单个文件操作,对其进行强制硬盘同步,fsync 将阻塞直到写入磁盘完成后返回,保证了数据持久化。
  4. 文件重写(rewrite):随着 AOF 文件越来越大,需要定期对 AOF 文件进行重写,达到压缩的目的。
  5. 重启加载(load):当 Redis 重启时,可以加载 AOF 文件进行数据恢复。

启用AOF

与快照持久化相比,AOF 持久化的实时性更好。默认情况下 Redis 没有开启 AOF(Redis 6.0 之后默认开启),可以通过 appendonly 参数开启:

# 是否开启AOF,默认是no
appendonly yes
# AOF文件的名称
appendfilename "appendonly.aof"

刷盘策略

开启 AOF 持久化后,每执行一条会更改 Redis 中数据的命令,Redis 就会将该命令写入到 AOF 缓冲区 server.aof_buf 中,然后再写入到系统内核缓冲区中,最后根据刷盘策略的配置来决定何时将系统内核缓冲区中的数据同步到硬盘中。

AOF的命令记录的频率也可以通过redis.conf文件来配置。

# 表示每执行一次写命令,立即记录到AOF文件
appendfsync always
#写命令执行完先放入AOF缓冲区,然后表示每隔1秒将缓冲区数据写到A0F文件,是默认方案
appendfsync everysec
#写命令执行完先放入AOF缓冲区,由操作系统决定何时将缓冲区内容写回磁盘
appendfsync no
配置项刷盘时机优点缺点
always同步刷盘可靠性高,几乎不丢数据性能影响大
everysec每秒刷盘性能适中最多丢失1秒数据
no操作系统控制性能最好可靠性较差,可能丢失大量数据

文件重写

随着时间的推移,AOF 文件会因为不断追加写命令而变得越来越大,可能会导致磁盘空间不足和恢复速度变慢。可以通过重新生成一个新的 AOF 文件,将当前的数据集以最少的命令集记录下来,从而缩小文件大小

AOF 文件重写期间,Redis 还会维护一个 AOF 重写缓冲区,该缓冲区会在子进程创建新 AOF 文件期间,记录服务器执行的所有写命令。当子进程完成创建新 AOF 文件的工作之后,服务器会将重写缓冲区中的所有内容追加到新 AOF 文件的末尾,使得新的 AOF 文件保存的数据库状态与现有的数据库状态一致。最后,服务器用新的 AOF 文件替换旧的 AOF 文件,以此来完成 AOF 文件重写操作。

开启 AOF 重写功能,可以调用 bgrewriteaof 命令手动执行,也可以设置阈值进行自动执行。

  • auto-aof-rewrite-min-size:如果 AOF 文件大小小于该值,则不会触发 AOF 重写。默认值为 64 MB
  • auto-aof-rewrite-percentage:执行 AOF 重写时,当前 AOF 大小和上一次重写时 AOF 大小的比值。如果当前 AOF 文件大小增加了这个百分比值,将触发 AOF 重写。将此值设置为 0 将禁用自动 AOF 重写。默认值为 100。

AOF校验机制了解吗

AOF 校验机制是 Redis 在启动时对 AOF 文件进行检查,以判断文件是否完整,是否有损坏或者丢失的数据。

这个机制的原理其实非常简单,就是通过使用一种叫做 校验和(checksum) 的数字来验证 AOF 文件。这个校验和是通过对整个 AOF 文件内容进行 CRC64 算法计算得出的数字。如果文件内容发生了变化,那么校验和也会随之改变。因此,Redis 在启动时会比较计算出的校验和与文件末尾保存的校验和(计算的时候会把最后一行保存校验和的内容给忽略掉),从而判断 AOF 文件是否完整。如果发现文件有问题,Redis 就会拒绝启动并提供相应的错误信息。

类似地,RDB 文件也有类似的校验机制来保证 RDB 文件的正确性,这里就不重复进行介绍了。

如何选择RDB和AOF

RDB(Redis Database File)

优点:

  1. 持久化速度快:RDB 文件在持久化时会生成一个数据快照,可以快速地恢复大规模的数据集。
  2. 文件较小:RDB 文件是二进制格式的,通常比 AOF 文件更小,占用的磁盘空间较少。
  3. 恢复速度快:RDB 文件在恢复数据时,加载速度通常比 AOF 快,因为 RDB 文件是一个完整的数据快照,不需要逐条回放写操作。
  4. 对性能影响小:RDB 持久化是通过子进程完成的,主进程可以继续处理客户端请求,因此对 Redis 性能影响较小。

缺点:

  1. 数据丢失风险高:因为 RDB 持久化是定期执行的(如每隔几分钟或根据配置的触发条件),在上一次持久化到下一次持久化之间的数据可能会丢失。
  2. 生成过程消耗资源:生成 RDB 文件需要 fork 子进程并占用一定的 CPU 和内存资源,特别是数据量大时会影响性能。

AOF(Append-Only File)

优点:

  1. 数据丢失风险低:AOF 通过追加日志记录每次写操作,可以更频繁地持久化数据(甚至可以做到每秒持久化一次),因此数据丢失的风险较低。
  2. 可调的同步策略:AOF 提供了多种同步策略(如 alwayseverysecno),可以根据需要在性能和数据安全性之间做权衡。
  3. 更人性化:AOF 文件是可读的日志文件,方便人类阅读和分析,有助于调试和故障排查。

缺点:

  1. 文件较大:AOF 文件记录了每个写操作,文件大小通常比 RDB 大很多,占用更多的磁盘空间。
  2. 恢复速度慢:AOF 恢复数据时需要回放所有的写操作日志,恢复速度通常比 RDB 慢。
  3. 性能开销较大:因为 AOF 需要在每次写操作后追加日志,频繁的磁盘 I/O 操作会带来一定的性能开销,特别是在同步策略设置为 always 时。

综合比较

  1. 数据安全性:AOF 提供更高的数据安全性,适用于对数据丢失敏感的场景;RDB 在数据持久化频率较低时有较高的数据丢失风险。
  2. 性能:RDB 对 Redis 性能影响较小,适用于性能要求高的场景;AOF 因为频繁的磁盘 I/O 操作,对性能有一定的影响。
  3. 恢复速度:RDB 恢复速度更快,适用于需要快速恢复大规模数据集的场景;AOF 需要回放日志,恢复速度较慢。
  4. 磁盘空间:RDB 文件较小,节省磁盘空间;AOF 文件较大,占用更多磁盘空间。

混合持久化

Redis 4.0 引入了混合持久化机制,结合了 RDB 和 AOF 的优点,以提高持久化的效率和可靠性。混合持久化在重启恢复数据时使用 RDB 文件的快照来快速加载数据,并且将 AOF 日志应用于此快照以实现更高的数据恢复精度。

工作原理

  1. RDB 快照
    • Redis 生成 RDB 文件快照,保存整个数据库的二进制数据。
    • RDB 文件的生成是通过子进程完成的,主进程可以继续处理客户端请求。
  2. AOF 日志
    • 除了生成 RDB 文件外,Redis 还会将写操作记录到 AOF 日志中。
    • 在混合持久化模式下,AOF 文件的初始部分是一个 RDB 快照,后面紧接着的是增量的 AOF 日志。
  3. 持久化过程
    • 当 Redis 进行持久化操作时,它会首先生成一个 RDB 文件,并将这个文件内容写入 AOF 文件。
    • 在 AOF 文件中,RDB 文件的内容作为初始部分,然后紧跟着追加的 AOF 日志。
  4. 数据恢复
    • 当 Redis 重启时,它会首先加载 AOF 文件中的 RDB 部分(即快照)来快速恢复数据。
    • 然后,它会回放 AOF 文件中 RDB 部分后的增量日志,以确保数据的一致性和完整性。

优缺点

优点:

  1. 快速恢复:使用 RDB 部分可以快速加载大部分数据,而不需要逐条回放所有写操作日志,极大地提高了数据恢复的速度。
  2. 较高的数据安全性:结合了 RDB 和 AOF 的优点,RDB 部分确保了数据的快速恢复,而 AOF 部分提供了更高的数据持久化频率,降低了数据丢失的风险。
  3. 性能优化
    • 在持久化过程中,RDB 快照的生成是通过子进程完成的,对主进程处理客户端请求的性能影响较小。
    • AOF 的增量日志记录了自上次快照以来的所有写操作,减少了持久化过程中的 I/O 操作次数,提高了系统性能。

缺点:

  1. 配置复杂性:混合持久化的配置比单独使用 RDB 或 AOF 更加复杂,需要合理设置参数以实现最佳性能和数据安全性。
  2. 磁盘空间占用:混合持久化模式下,AOF 文件既包含 RDB 快照部分又包含增量日志,可能会占用更多的磁盘空间。

启用混合持久化

要启用混合持久化,可以在 Redis 配置文件 redis.conf 中设置以下参数:

# 启用 AOF 持久化
appendonly yes

# AOF 重写策略
# 在 AOF 文件达到指定大小或比例时触发重写
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

# 启用混合持久化
aof-use-rdb-preamble yes
s.conf` 中设置以下参数:

```shell
# 启用 AOF 持久化
appendonly yes

# AOF 重写策略
# 在 AOF 文件达到指定大小或比例时触发重写
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

# 启用混合持久化
aof-use-rdb-preamble yes
  • 18
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值