1、官网介绍

Redis提供了不同范围的持久性选项:

  • RDB(Redis Database):RDB 持久性按指定的时间间隔执行数据集的时间点快照。
  • AOF(Append Only File):AOF 持久性记录服务器接收的每个写入操作,这些操作将在服务器启动时再次播放,以重建原始数据集。使用与 Redis 协议本身相同的格式记录命令,并且采用仅追加方式。当日志太大时,Redis 可以在后台重写日志。
  • 无持久性:如果希望,只要服务器正在运行,数据就一直存在,则可以完全禁用持久性。
  • RDB + AOF:可以在同一实例中同时合并AOF和RDB。请注意,在这种情况下,当 Redis 重新启动时,AOF 文件将用于重建原始数据集,因为它可以保证是最完整的。

要理解的最重要的事情是 RDB 与 AOF 持久性之间的不同权衡。让我们从 RDB 开始:

1、RDB的优势

  • RDB 是您的 Redis 数据的非常紧凑的单文件时间点表示。RDB 文件非常适合备份。例如,您可能希望在最近的24小时内每小时存档一次 RDB 文件,并在30天之内每天保存一次RDB快照。这样,在发生灾难时,您可以轻松地还原不同版本的数据集。
  • RDB 对于灾难恢复非常有用,它是一个紧凑的文件,可以传输到远程数据中心或 Amazon S3(可能已加密)上。
  • RDB 最大限度地提高了 Redis 的性能,因为 Redis 父进程为了持久化而需要做的唯一工作就是分叉一个孩子,其余所有工作都要做。父实例将永远不会执行磁盘I / O或类似操作。
  • 与 AOF 相比,RDB 允许使用大型数据集更快地重新启动。
  • 在副本上,RDB 支持重新启动和故障转移后的部分重新同步

    2、RDB的缺点

  • 如果您需要最大程度地减少数据丢失的可能性(如果 Redis 停止工作,例如在断电之后),则 RDB 不好。您可以在生成 RDB 的位置配置不同的保存点(例如,在至少五分钟之后,对数据集进行100次写入,但是您可以有多个保存点)。但是,通常会每隔五分钟或更长时间创建一次 RDB 快照,因此如果Redis 出于任何原因在没有正确关闭的情况下停止工作,则应该准备丢失最新的数据。

  • RDB 需要经常使用fork()才能使用子进程将其持久化在磁盘上。如果数据集很大,Fork()可能很耗时,并且如果数据集很大且CPU性能不佳,则可能导致 Redis 停止为客户端服务几毫秒甚至一秒钟。AOF 还需要fork(),但是您可以调整要重写日志的频率,而无需在持久性上进行权衡。

    2、到底是什么

    在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的 Snapshot 快照,它恢复时是将快照文件直接读到内存里

    3、备份

    Redis 会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何 IO 操作的,这就确保了极高的性能如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那 RDB 方式要比 AOF 方式更加的高效。RDB 的缺点是最后一次持久化后的数据可能丢失

    4、Fork

  • Fork 的作用是复制一个与当前进程一样的进程。新进程的所有数据(变量、环境变量、程序计数器等)数值都和原进程一致,但是是一个全新的进程,并作为原进程的子进程

  • 在 Linux 程序中,fork() 会产生一个和父进程完全相同的子进程,但子进程在此后多会 exec 系统调用,出于效率考虑,Linux 中引入了“写时复制技术(CopyOnWrite)
  • 一般情况父进程和子进程会共用同一段物理内存,只有进程空间的各段的内容要发生变化时,才会将父进程的内容复制一份给子进程。

    5、RDB持久化流程

    11.Redis持久化之RDB - 图1
    1)执行 bgsave 命令,Redis 父进程判断当前是否存在正在执行的子进程,如 RDB/AOF 子进程,如果存在bgsave 命令直接返回。
    2)父进程执行fork操作创建子进程,fork 操作过程中父进程会阻塞,通过 info stats 命令查看 latestfork_usec 选项,可以获取最近一个 fork 操作的耗时,单位为微秒。
    3)父进程 fork 完成后,bgsave 命令返回“Background saving started”信息并不再阻塞父进程,可以继续响应其他命令。
    4)子进程创建 RDB 文件,根据父进程内存生成临时快照文件,完成后对原有文件进行原子替换。执行 lastsave 命令可以获取最后一次生成RDB的时间,对应 info 统计的 rdb_last_save_time 选项。
    5)进程发送信号给父进程表示完成,父进程更新统计信息,具体见 info Persistence 下的 rdb
    * 相关选项。

    6、配置文件

    1、dump.rdb

    在redis.conf中配置文件名称,默认为dump.rdb
    1. 默认文件名
    2. # The filename where to dump the DB
    3. dbfilename dump.rdb

    2、配置位置

    在哪儿启动 redis,就在相应的目录下创建 dump.rdb 文件
    文件产生目录
    # The working directory.
    #
    # The DB will be written inside this directory, with the filename specified
    # above using the 'dbfilename' configuration directive.
    #
    # The Append Only File will also be created inside this directory.
    #
    # Note that you must specify a directory here, not a file name.
    dir ./
    

    7、如何触发RDB快照;保持策略

    1、快照配置

    默认保存快照规则
    # Unless specified otherwise, by default Redis will save the DB:
    #   * After 3600 seconds (an hour) if at least 1 key changed
    #   * After 300 seconds (5 minutes) if at least 100 keys changed
    #   * After 60 seconds if at least 10000 keys changed
    #
    # You can set these explicitly by uncommenting the three following lines.
    #
    # save 3600 1
    # save 300 100
    # save 60 10000
    
    改变达到指定数目和时间以后就重新开始计算(改变了102个值,300秒后追加到dump.rdb文件中,剩下的2个值再重新计算时间)

    2、命令save VS bgsave

    save :save时只管保存,其它不管,全部阻塞。手动保存。不建议。
    bgsave:Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求。
    可以通过lastsave 命令获取最后一次成功执行快照的时间

    3、flushall命令

    执行flushall命令,也会产生dump.rdb文件,但里面是空的,无意义

    4、Save

    格式:save 秒钟 写操作次数RDB是整个内存的压缩过的Snapshot,RDB的数据结构,可以配置复合的快照触发条件,默认是1分钟内改了1万次,或5分钟内改了10次,或15分钟内改了1次。
    禁用
    不设置save指令,或者给save传入空字符串

    5、stop-writes-on-bgsave-error

    # By default Redis will stop accepting writes if RDB snapshots are enabled
    # (at least one save point) and the latest background save failed.
    # This will make the user aware (in a hard way) that data is not persisting
    # on disk properly, otherwise chances are that no one will notice and some
    # disaster will happen.
    #
    # If the background saving process will start working again Redis will
    # automatically allow writes again.
    #
    # However if you have setup your proper monitoring of the Redis server
    # and persistence, you may want to disable this feature so that Redis will
    # continue to work as usual even if there are problems with disk,
    # permissions, and so forth.
    stop-writes-on-bgsave-error yes
    
    当Redis无法写入磁盘(磁盘满)的话,直接关掉Redis的写操作。推荐 yes.

    6、rdbcompression 压缩文件

    # Compress string objects using LZF when dump .rdb databases?
    # By default compression is enabled as it's almost always a win.
    # If you want to save some CPU in the saving child set it to 'no' but
    # the dataset will likely be bigger if you have compressible values or keys.
    rdbcompression yes
    
    对于存储到磁盘中的快照,可以设置是否进行压缩存储。如果是的话,redis会采用LZF算法进行压缩。
    如果你不想消耗CPU来进行压缩的话,可以设置为关闭此功能。推荐 yes.

7、rdbchecksum 检查完整性

# Since version 5 of RDB a CRC64 checksum is placed at the end of the file.
# This makes the format more resistant to corruption but there is a performance
# hit to pay (around 10%) when saving and loading RDB files, so you can disable it
# for maximum performances.
#
# RDB files created with checksum disabled have a checksum of zero that will
# tell the loading code to skip the check.
rdbchecksum yes

在存储快照后,还可以让redis使用CRC64算法来进行数据校验,
但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能
推荐 yes.

8、rdb的备份

先通过config get dir查询rdb文件的目录
将*.rdb的文件拷贝到别的地方
rdb的恢复

  • 关闭Redis
  • 先把备份的文件拷贝到工作目录下 cp dump2.rdb dump.rdb
  • 启动Redis, 备份数据会直接加载

    8、优劣

    优势:

  • 适合大规模的数据恢复

  • 对数据完整性和一致性要求不高的话更适合使用
  • 节省磁盘空间
  • 恢复速度快

image.png
劣势:

  • Fork的时候,内存中的数据被克隆了一份,大致2倍的膨胀性需要考虑
  • 虽然Redis在fork时使用了写时拷贝技术,但是如果数据庞大时还是比较消耗性能。
  • 在备份周期在一定间隔时间做一次备份,所以如果Redis意外down掉的话,就会丢失最后一次快照后的所有修改。

总结:

  • RDB 是一个非常紧凑的文件
  • RDB 在保存 RDB 文件时父进程唯一需要做的就是 fork 出一个子进程,接下来的工作全部由子进程来做,父进程不需要再做其他 IO 操作,所以 RDB 持久化方式可以最大化 redis 的性能
  • 与AOF 相比,在恢复大的数据集的时候,RDB 方式会更快一些
  • 数据丢失风险大
  • RDB 需要进程 fork 子进程来保存数据集到硬盘上,当数据集比较大的时候,fork 的过程是非常耗时的,可能会导致 Redis 在一些毫秒级不能响应客户端请求

    9、停止

    动态停止RDB:redis-cli config set save ""save后给空值,表示禁用保存策略