Redis持久化之RDB和AOF详解

持久化是确保 Redis 数据在服务器重启或崩溃时不丢失的关键功能。由于 Redis 是基于内存的数据库,如果不进行持久化,所有数据都存在于内存中,一旦服务器进程退出,内存中的数据就会丢失。持久化机制可以将 Redis 的数据库状态保存到磁盘上,以便在需要时进行恢复,保证数据的持久性和可靠性。

Redis 提供了两种主要的持久化方式来确保数据在重启或崩溃后不丢失:RDB(Redis DataBase)和 AOF(Append Only File)。

RDB(Redis DataBase)

RDB全称Redis Database Backup file(Redis数据备份文件),也被叫做Redis数据快照。简单来说 它将 Redis 在某个时间点的数据以二进制格式保存到硬盘上的文件中。RDB 持久化是通过执行 SAVE 或 BGSAVE 命令来实现的。

执行时机

在 Redis 中,RDB 持久化会在以下四种情况下执行:

  • 执行 SAVE 命令:SAVE 命令会阻塞 Redis 服务器,直到 RDB 文件创建完毕。在这期间,Redis 不能处理任何其他命令请求。
  • 执行 BGSAVE 命令:BGSAVE 命令会在后台异步进行,这意味着 Redis 仍然可以响应其他命令请求,不会阻塞客户端。这是 RDB 持久化的推荐方式,因为它不会影响 Redis 的正常操作。
  • Redis 服务器停机时:当 Redis 服务器正常停止(如通过 shutdown 命令)时,会执行一次自动的 BGSAVE 操作,将当前内存中的数据库状态保存到磁盘上。
  • 达到指定的 RDB 条件时:通过在配置文件中设置 save 指令,可以指定当满足一定条件(如在指定的时间内有多少次写操作)时执行 BGSAVE 操作。这种方式允许在数据修改较多但不希望频繁进行持久化的情况下进行控制。

这四种情况下,Redis 将执行 RDB 持久化操作,将当前数据库的快照保存到磁盘上,以确保数据在重启或崩溃后能够恢复。

1)save命令

执行下面的命令,可以立即执行一次RDB:

save命令会导致主进程执行RDB,这个过程中其它所有命令都会被阻塞。只有在数据迁移时可能用到。

2)bgsave命令

下面的命令可以异步执行RDB:

这个命令执行后会开启独立进程完成RDB,主进程可以持续处理用户请求,不受影响。

3)停机时

Redis停机时会执行一次save命令,实现RDB持久化。

4)触发RDB条件

Redis内部有触发RDB的机制,可以在redis.conf文件中找到,格式如下:

# 900秒内,如果至少有1个key被修改,则执行bgsave , 如果是save "" 则表示禁用RDB
save 900 1  
save 300 10  
save 60 10000 

RDB的其它配置也可以在redis.conf文件中设置:

# 是否压缩 ,建议不开启,压缩也会消耗cpu,磁盘的话不值钱
rdbcompression yes

# RDB文件名称
dbfilename dump.rdb  

# 文件保存的路径目录
dir ./ 

RDB原理

在 Redis 中,RDB 持久化的原理涉及了操作系统的 fork 系统调用和 Copy-on-Write(写时复制)技术。

RDB 持久化的过程

1、触发 BGSAVE 命令:

  • 当执行 BGSAVE 命令时,Redis 会调用操作系统的 fork 系统调用来创建一个子进程。

2、主进程和子进程:

  • 主进程(即 Redis 服务器进程)在 fork 时会复制自身的地址空间,包括所有的内存数据。
  • 子进程最初会与主进程共享相同的内存数据和状态。

3、Copy-on-Write 技术:

  • 在 Copy-on-Write 技术下,当主进程或子进程需要修改内存中的数据时,操作系统并不会立即复制整个内存页。相反,它会将需要修改的部分复制到新的内存页,这样主进程和子进程的内存页变成了两份不同的数据。
  • 这意味着,当主进程执行读操作时,它仍然访问共享的内存数据。但当主进程执行写操作时,操作系统会为主进程分配一个新的内存页,确保修改不会影响到子进程的数据。

4、子进程的任务:

  • 子进程在 fork 后负责将当前内存中的数据库状态写入到一个新的 RDB 文件中。
  • 因为主进程继续处理客户端的请求,所以子进程在后台进行持久化操作,这样可以保证 Redis 在持久化过程中仍然可以响应客户端的命令请求。

总结

RDB 持久化利用了操作系统的 fork 和 Copy-on-Write 技术来实现数据的安全持久化。主进程在执行写操作时会进行内存页的复制,以保证主进程和子进程在写操作时不会相互影响。这种机制使得 Redis 在执行 BGSAVE 时能够保持高效和安全,确保数据在持久化到磁盘后的一致性和可靠性。

小结

RDB方式bgsave的基本流程?

  1. fork主进程得到一个子进程,共享内存空间:当执行 BGSAVE 命令时,Redis 主进程调用操作系统的 fork 系统调用,创建一个子进程。子进程最初与主进程共享相同的内存数据和状态。
  2. 子进程读取内存数据并写入新的RDB文件:子进程负责遍历内存中的所有数据,并将当前的数据库状态写入到一个新的 RDB 文件中。这个过程是在后台异步执行的,主进程继续处理客户端的命令请求。
  3. 用新RDB文件替换旧的RDB文件:当子进程完成将内存数据写入新的 RDB 文件后,Redis 会用新生成的 RDB 文件替换掉原来的旧 RDB 文件。

RDB执行时机和 save 60 1000 含义?

RDB执行时机:

RDB 可以在两种情况下执行:

  1. 手动执行 BGSAVE 命令。
  2. 自动执行,根据配置的条件触发,比如根据 save 配置项。

save 60 1000 的含义:

这是 save 配置项的一种设置,表示在60秒内,如果至少有1000个键被修改(即写入操作),则执行一次 BGSAVE。这个配置项的格式是 <seconds> <changes>,其中 <seconds> 表示执行条件的时间间隔, <changes> 表示在指定时间内修改的键的数量。

RDB的缺点?

  • 定期执行导致数据可能丢失:RDB 是定期执行的,因此两次执行之间如果发生故障或服务停止,这期间的数据可能会丢失。
  • fork子进程耗时:在执行 BGSAVE 时,Redis 需要进行 fork 操作来创建子进程,这个过程可能会消耗大量的 CPU 和内存资源,尤其是对于大型内存数据库而言。
  • 压缩和写出RDB文件耗时:将内存中的数据压缩并写出到磁盘上的 RDB 文件也会耗费一定的时间和系统资源,可能会在高负载情况下影响 Redis 的性能。

总体而言,RDB 是一种通过定期快照的方式来持久化数据的方法,适合于数据相对静态且对一定数据丢失可以容忍的场景。

AOF(Append Only File)

AOF 以追加方式记录每次 Redis 服务器接收的写命令请求,将这些命令追加到文件末尾。

AOF 持久化可以通过配置文件控制:

  • appendfsync 选项:指定在什么情况下将缓冲区中的写命令同步到磁盘中的 AOF 文件,可以选择每次写入、每秒钟写入一次或者不同步(由操作系统负责异步同步)。
  • AOF 重写:通过启动一个后台进程来重写 AOF 文件,删除冗余的命令,减小文件体积,同时保留完整的数据集状态。

appendfsync 选项

AOF默认是关闭的,需要修改redis.conf配置文件来开启AOF:

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

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

# 表示每执行一次写命令,立即记录到AOF文件
appendfsync always 
# 写命令执行完先放入AOF缓冲区,然后表示每隔1秒将缓冲区数据写到AOF文件,是默认方案
appendfsync everysec 
# 写命令执行完先放入AOF缓冲区,由操作系统决定何时将缓冲区内容写回磁盘
appendfsync no

三种策略对比:

AOF 重写

AOF(Append-Only File)文件记录了Redis服务器接收到的每个写命令,因此在一段时间后,AOF文件可能会比起RDB文件更大,因为它包含了所有写操作的历史记录。这种特性使得AOF在恢复时能提供更精确的恢复点。

AOF 文件重写的目的

AOF 文件重写的主要目的是减小AOF文件的体积,去除多余的写操作记录,以达到以下效果:

  • 减少文件体积:通过去除多余的写操作,可以显著减少AOF文件的体积,从而节省磁盘空间。
  • 优化性能:减少了AOF文件的体积后,Redis在进行AOF重写时,新生成的AOF文件的体积通常比原始AOF文件小得多,这有助于提高写入性能和恢复速度。

AOF 文件重写的执行方式

执行 AOF 文件重写的主要命令是 BGREWRITEAOF。当执行这个命令时,Redis会进行以下操作:

  • 启动AOF重写进程:Redis会启动一个子进程来执行AOF文件的重写操作。
  • 重写过程:子进程会遍历当前内存中的数据库状态,并按照顺序重写所有的写命令。在这个过程中,它会根据每个键的最终状态来重写操作,去除多余的写操作,只保留最终状态。
  • 替换原始AOF文件:当AOF文件重写完成后,Redis会用新生成的AOF文件替换掉原始的AOF文件。

配置AOF自动重写的阈值

Redis也支持自动触发AOF文件重写,可以通过以下配置参数在redis.conf中设置:

  • auto-aof-rewrite-percentage:指定AOF文件比上次重写后的文件增长百分比。当AOF文件的大小增长超过这个百分比时,Redis会自动触发AOF文件重写。
  • auto-aof-rewrite-min-size:指定触发AOF文件重写的最小体积。只有当AOF文件的当前大小超过这个配置的大小时,才会考虑进行自动重写。
# AOF文件比上次文件 增长超过多少百分比则触发重写
auto-aof-rewrite-percentage 100
# AOF文件体积最小多大以上才触发重写 
auto-aof-rewrite-min-size 64mb 

这些配置参数使得Redis能够在需要时自动优化AOF文件的体积,以确保其保持在一个合理且可管理的大小范围内。

通过AOF文件重写,Redis能够有效地管理和优化持久化数据,提高系统的性能和可靠性。

RDB与AOF对比

RDB和AOF各有自己的优缺点

  • RDB 适合用于备份和全量恢复,可以通过定期保存快照来减少持久化对性能的影响。
  • AOF 适合用于提高数据完整性和灾难恢复,尤其是在需要保证每一条写入操作都不丢失的场景下。

通常情况下,Redis 的最佳实践是同时开启 RDB 和 AOF 持久化,以便兼顾性能和数据完整性的需求。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

正在奋斗的程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值