Redis持久化之RDB

持久化(Persistence)是指将数据写到比如固态硬盘等持久化的存储中。Redis支持以下几种持久化方式:

  • RDB:即Redis Database,是指通过在不同的时间点,将数据库的快照(snapshot)以二进制格式保存到文件中,这样Redis重启后直接加载数据。
  • AOF:即Append Only File,是指在Redis运行期间,不断将Redis执行的写命令(修改数据的命令)写到文件中,Redis重启后,只要将这些写命令重复执行一遍就可以恢复数据。
  • RDB+AOF:同时使用RDB和AOF两种持久化方式。

RDB常用配置

RDB持久化相关的配置如下:

  • save 60 1000:如果在60秒内有不少于1000个键发生了变更,那么就生成一个RDB文件。SAVE条件可以配置多个,Redis启动后会把该配置项保存在server.saveparams中。
  • dbfilename dump.rdb:RDB文件名,默认为dump.rdb
  • dir ./:RDB文件和AOF文件的保存路径,默认为./
  • rdbchecksum yes:加载RDB文件后校验CRC64校验码,默认为yes,从Redis 5起开始支持。
  • rdbcompression yes:数据保存到RDB文件前先进行压缩,默认为yes。

RDB持久化的优势

RDB持久化主要有以下几点优势:

  • RDB文件是在某个具体时刻对Redis数据库做的一个快照,因此非常适合用来对Redis数据库做备份。比如你可以对过去24小时内每个小时生成的RDB文件进行归档,并且在过去30天内每天都做一次RDB文件备份。这样在Redis数据库因为灾难被损坏时,就可以利用备份将数据恢复到不同时间点的版本。
  • 作为一个很容易在不同数据中心之间进行传输的压缩文件,RDB非常适用于灾备恢复。
  • RDB持久化是由Redis父进程fork出来的子进程完成的,能够最小化对Redis性能的影响。
  • 在数据量比较大时,使用RDB持久化时Redis重启后恢复的速度比AOF更快。
  • RDB支持从节点在重启和故障转移后的部分同步

RDB持久化的缺点

RDB持久化主要有以下劣势:

  • 在Redis因为故障或者断电而停止工作时,RDB不能最小化数据丢失量。你可以将RDB配置成在60秒内有不少于1000个键发生了变化就进行一次持久化,然后在发生故障时你还是有可能丢失一分钟左右的数据。
  • RDB子进程在进行持久化时需要经常调用fork函数。如果数据量很大,fork函数可能会比较耗时;如果数据集很大并且CPU性能一般,可能会导致Redis在若干毫秒甚至一秒内停止对客户端提供服务。相对而言,AOF调用fork函数的频率更低,并且你也可以人为调整重写AOF日志的频率。

RDB还是AOF?

如果想要达到与PostgreSQL相当的数据安全级别,应该同时使用RDB和AOF两种持久化方法。

如果能够容忍分钟级别的数据量丢失,就可以单独使用RDB持久化。

官方不建议单独使用AOF持久化,因为RDB快照在数据备份快速重启方面有很大的优势,也能在AOF引擎故障时提供额外的数据安全保障。

快照与写时复制

RDB默认将数据库快照保存在磁盘中的二进制文件dump.rdb中。可以通过在配置文件中设置save N M来控制RDB在N秒内有不少于M个键发生变化时生成快照,也可以手动执行SAVEBGSAVE命令来生成快照文件。

生成快照的流程如下:

  • Redis调用fork函数创建一个RDB子进程;
  • RDB子进程将数据集写入到临时的RDB文件中;
  • 临时的RDB文件写完后,会替换掉旧的RDB文件。

在持久化的过程中,RDB子进程和父进程是共享同一片内存数据的,因为在创建RDB子进程时会复制父进程的页表,但是页表指向的物理内存是相同的。这样能够减少创建子进程时的性能损耗,从而加快创建子进程的速度。由于共享父进程的所有内存数据,RDB子进程可以直接读取主进程的内存数据,并将数据写入到RDB文件。

如果在RDB子进程生成RDB快照的过程中,Redis主进程修改了内存中的某个键,就会发生写时复制Copy-On-Write, COW),那么这个键对应的物理内存就会被复制一份,主进程在复制出来的内存里进行修改,而RDB子进程就可以继续把未修改的内存数据保存到RDB快照中。也就是说,在生成RDB快照期间被修改的内存数据无法被保存到该RDB快照文件中

RDB转AOF

如果现在有一个Redis实例使用RDB进行持久化,该怎么切换到AOF持久化?在Redis 2.2及其以后的版本中,这是一个比较简单的操作,并且不需要任何重启动作。

Redis 2.2及其以后的版本

  • 备份最新的dump.rdb文件;
  • 将备份转移到安全的地方;
  • 执行下面两个命令:
> redis-cli config set appendonly yes
> redis-cli config set save ""
  • 确认数据库包含与切换前相同数量的键;
  • 确认写命令以正确的方式添加到了AOF文件中。

其中,redis-cli中的第一个CONFIG命令用于开启AOF持久化,第二个CONFIG命令用于关闭RDB持久化(如果你想同时使用两种持久化方式,可以不执行第二个命令)。

🐍 切记一定要修改redis.conf配置文件中的对应配置,否则Redis重启后在redis-cli中开启的AOF持久化配置会失效。

Redis 2.2之前的版本

  • 备份最新的dump.rdb文件;
  • 将备份转移到安全的地方;
  • 停止所有对数据库的写操作
  • 在redis-cli中执行一次BGREWRITEAOF命令。该命令会创建AOF文件;
  • 在AOF dump文件生成以后,停止Redis服务;
  • 修改redis.conf文件来开启AOF持久化;
  • 重新启动Redis服务;
  • 确认数据库包含与切换前相同数量的键;
  • 确认写命令以正确的方式添加到了AOF文件中。

RDB与AOF的关联

Redis 2.4及其以后的版本中,会确保在生成RDB快照的过程中不会触发AOF重写,同时在AOF重写的过程中不会允许执行BGSAVE命令。这么做是为了避免生成RDB快照和重写AOF的两个后台进程同时进行大量的磁盘I/O。

在正在创建RDB快照时,如果用户通过执行BGREWRITEAOF命令显示地要求进行AOF重写时,Redis服务将回复一个OK状态代码,告知用户重写操作已安排,并且一旦快照完成,AOF重写就会开始。

在RDB和AOF同时启用的情况下,Redis发生重启后,AOF将优先被用来重建原有的数据集,因为AOF中包含的数据更加完整。

Redis数据备份

Redis对数据备份非常友好,你可以在数据库运行时复制RDB文件。RDB文件一旦生成就不会被修改。Redis在创建RDB文件时会使用一个临时的文件名,只有在快照文件创建完毕后才会被重命名为默认的RDB文件名。

官方的建议如下:

  • 创建一个定时任务,将按小时生成的RDB文件保存到一个单独的路径下,并将按天生成的快照文件保存到另一个不同的路径下。
  • 每次运行定时任务时,使用find命令来确保过旧的快照文件已被删除。确保在快照文件名称中包含快照生成时的日期和时间信息。
  • 确保至少每天一次把RDB快照文件传输到其他数据中心、或者其他物理机上。

REFERENCES
【1】https://redis.io/docs/management/persistence/
【2】https://raw.githubusercontent.com/redis/redis/6.0/redis.conf

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值