Redis 7.x 系列【15】持久化机制之 RDB

有道无术,术尚可求,有术无道,止于术。

本系列Redis 版本 7.2.5

源码地址:https://gitee.com/pearl-organization/study-redis-demo

1. 概述

Redis 的数据都在内存中,一旦服务器宕机或者重启,所有的数据都将丢失。Redis 提供了持久化机制,将内存数据进行磁盘持久化保存,以便重启时重新加载数据到内存中。

目前提供了两种持久化机制:

  • RDBRedis Database):默认方式,在指定的时间间隔内,通过创建快照保存数据,重启时,加载快照数据
  • AOFAppend Only File):将每一个写命令都追加到 AOF 文件的末尾,重启时,执行文件中的所有命令来恢复数据

RDB优点:

  • RDB 文件是一个紧凑的二进制文件,可以很方便地进行备份、传输和恢复。
  • 保存的是数据集的完整快照,所以恢复起来也很快。
  • 在恢复大的数据集时,比AOF更快。

RDB缺点:

  • RDB 是定期保存,所以在两次保存之间如果发生宕机,那么最近一次保存之后的数据将会丢失。
  • Redis Save 命令可能会阻塞客户端的请求。
  • 依赖于主进程的fork,在更大的数据集中,这可能会导致服务请求的瞬间延迟。

2 执行原理

执行流程如下所示:
在这里插入图片描述
RDB默认开启,但是快照生成不是连续的,而是在满足特定条件时触发。在以下情况时,会触发生成RDB

  • 手动触发:
    • 手动save/bgsave命令
    • 执行shutdown且没有设置开启AOF持久化
    • 执行flushall/flushdb命令也会产生dump.rdb文件,但里面是空的,无意义
  • 自动触发:
    • 达到save配置项的条件
    • 主从复制时,主节点自动触发

当触发后,Redis 会创建一个子进程,与主进程共享相同的地址空间,责遍历内存中的键值对,并将它们编码后写入一个临时RDB文件中。

子进程完成写入后,用新的RDB文件替换旧的RDB文件,并更新生成时间戳,默认的文件名为dump.rdb
在这里插入图片描述
Redis 重启时,会加载RDB文件中的数据并读回到内存中。

3. 配置项

redis.confRDB 相关的配置如下:

################################ SNAPSHOTTING  ################################

# Save the DB to disk.
#
# save <seconds> <changes> [<seconds> <changes> ...]
#
# Redis will save the DB if the given number of seconds elapsed and it
# surpassed the given number of write operations against the DB.
#
# Snapshotting can be completely disabled with a single empty string argument
# as in following example:
#
# save ""
#
# Unless specified otherwise, by default Redis will save the DB:
#   * After 3600 seconds (an hour) if at least 1 change was performed
#   * After 300 seconds (5 minutes) if at least 100 changes were performed
#   * After 60 seconds if at least 10000 changes were performed
#
# You can set these explicitly by uncommenting the following line.
#
# save 3600 1 300 100 60 10000

# 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

# 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

# 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

# Enables or disables full sanitization checks for ziplist and listpack etc when
# loading an RDB or RESTORE payload. This reduces the chances of a assertion or
# crash later on while processing commands.
# Options:
#   no         - Never perform full sanitization
#   yes        - Always perform full sanitization
#   clients    - Perform full sanitization only for user connections.
#                Excludes: RDB files, RESTORE commands received from the master
#                connection, and client connections which have the
#                skip-sanitize-payload ACL flag.
# The default should be 'clients' but since it currently affects cluster
# resharding via MIGRATE, it is temporarily set to 'no' by default.
#
# sanitize-dump-payload no

# The filename where to dump the DB
dbfilename dump.rdb

# Remove RDB files used by replication in instances without persistence
# enabled. By default this option is disabled, however there are environments
# where for regulations or other security concerns, RDB files persisted on
# disk by masters in order to feed replicas, or stored on disk by replicas
# in order to load them for the initial synchronization, should be deleted
# ASAP. Note that this option ONLY WORKS in instances that have both AOF
# and RDB persistence disabled, otherwise is completely ignored.
#
# An alternative (and sometimes better) way to obtain the same effect is
# to use diskless replication on both master and replicas instances. However
# in the case of replicas, diskless is not always an option.
rdb-del-sync-files no

# 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 ./

3.1 save

stop-writes-on-bgsave-error配置 Redis 如何触发 RDB持久化。

# 禁用 RDB
# save ""
# 多少秒内,如果数据集至少发生了多少次写操作,执行一次快照保存(下面为默认值)
# save 3600 1 300 100 60 10000 

save "" 将配置设置为一个空字符串,表示禁用 RDB ,但通常不建议这样做,除非你使用了 AOF 持久化或其他备份策略。

save <seconds> <changes> 配置指定了在多少秒(seconds)内,如果数据集至少发生了多少次写(changes)操作(例如SETLPUSH等),则执行一次 RDB 快照保存。

save 3600 1 300 100 60 10000 表示:

  • 3600秒内(1小时),如果至少进行了1次写操作,则保存
  • 300秒内(5分钟),如果至少进行了100次写操作,则保存
  • 60秒内,如果至少进行了10000次写操作,则保存

可以自定义配置,比如 :

# 每隔600秒(10分钟)检查一次,如果在这段时间内至少发生了10次写操作,则执行一次RDB快照保存
save 600 10

在执行RDB快照保存时,Redis可能会阻塞客户端的请求,特别是当使用SAVE命令而不是BGSAVE(在后台保存)时。因此,在生产环境中,通常建议使用BGSAVE来避免阻塞。BGSAVE通过创建一个子进程来执行快照保存,而主进程则继续处理客户端的请求。

3.2 stop-writes-on-bgsave-error

stop-writes-on-bgsave-error配置 RedisRDB持久化过程中遇到错误时,是否应该停止接受新的写操作,默认为 yes

stop-writes-on-bgsave-error yes

如果设置为yes(默认值),那么在执行BGSAVE命令时如果遇到错误(例如磁盘空间不足、权限问题等),Redis会停止接受新的写操作,直到BGSAVE命令成功执行。这样做的目的是为了让用户意识到数据没有正确地持久化到磁盘上,从而可以采取适当的措施。

如果设置为no,即使BGSAVE命令失败,Redis也会继续接受新的写操作。这意味着数据可能会丢失,因为错误没有导致Redis停止写入。然而,如果你已经设置了适当的Redis服务器监控和持久化策略,并且希望Redis在发生磁盘、权限等问题时仍然能够继续工作,那么可以选择将这个选项设置为no

在大多数情况下,将stop-writes-on-bgsave-error设置为yes是一个比较安全的选择,因为它可以确保在发生错误时用户会注意到,并有机会采取措施。然而,如果对Redis的监控和持久化策略非常自信,并且希望即使在发生错误时也能继续工作,那么可以将其设置为no

3.3 rdbcompression

rdbcompression 配置 Redis 在创建RDB快照文件时是否使用LZF算法来压缩字符串对象的。

rdbcompression yes

如果设置为 yes(默认值),Redis会使用LZF压缩算法来压缩RDB文件中的字符串对象。LZF是一个快速且有效的压缩算法,可以在创建RDB文件时减少文件的大小,从而节省磁盘空间。然而,压缩过程会消耗一些额外的CPU资源。

如果设置为noRedis将不会使用LZF压缩算法来压缩,这样做可以节省CPU资源,但RDB文件可能会变得更大,尤其是当数据库中包含大量可压缩的字符串值或键时。

在大多数情况下,启用压缩是一个好的选择,因为它可以显著减少RDB文件的大小,节省磁盘空间,并且通常压缩和解压缩的开销对于Redis的性能影响是微乎其微的。然而,如果Redis实例运行在CPU资源非常受限的环境中,并且你更关心节省CPU资源而不是磁盘空间,那么你可以考虑禁用压缩。但请注意,这可能会导致RDB文件变得更大。

3.4 rdbchecksum

rdbchecksum 配置Redis在生成RDB持久化文件时是否应该包含CRC64校验和,并将这个校验和保存在文件的末尾。

rdbchecksum yes

如果设置为yes(默认值),Redis会在RDB文件的末尾添加一个CRC64校验和。这个校验和用于在加载RDB文件时验证文件的完整性,确保文件在写入磁盘后没有被损坏。虽然这会增加在保存和加载文件时的CPU消耗(大约10%的性能开销),但它提高了RDB文件的抗损坏能力。

如果设置为noRedis将不会在文件的末尾添加校验和。这样可以减少保存和加载RDB文件时的CPU消耗,但会增加RDB文件损坏的风险,因为在加载文件时无法验证其完整性。如果加载了一个损坏的RDB文件,Redis可能无法正确启动或导致数据丢失。

在大多数情况下,推荐启用CRC64校验和,因为它提供了对RDB文件完整性的验证,有助于确保数据的可靠性。除非你非常关注性能,并且确信RDB文件在保存和加载过程中不会受到损坏,否则建议不要禁用这个选项。

3.5 sanitize-dump-payload

sanitize-dump-payload配置Redis在加载RDB文件或RESTORE命令的payload时是否执行全面的数据校验。全面的数据校验可以减少在后续处理命令时遇到断言失败或崩溃的风险。

sanitize-dump-payload no

可配置选项:

  • no:从不进行全面的数据校验。
  • yes:始终进行全面的数据校验。
  • clients:仅对用户连接执行全面的数据校验。排除从主连接收到的RDB文件和RESTORE命令,以及具有skip-sanitize-payload ACL标志的客户端连接。

默认值是no,由于它目前会影响集群迁移(resharding via MIGRATE),所以默认设置为no。但在某些情况下,尤其是当安全性更重要时,可以设置为yesclients

3.6 dbfilename

dbfilename 用于指定Redis在生成RDB持久化文件时使用的文件名,默认文件名是dump.rdb

dbfilename dump.rdb

可以根据需要更改这个文件名,但请确保Redis进程有权写入指定的目录和文件。如果更改了dbfilename的值,那么当你需要恢复Redis数据时,也需要使用新的文件名来指定RDB文件。

3.7 rdb-del-sync-files

rdb-del-sync-files 控制Redis是否在没有启用持久化(即既没有启用RDB也没有启用AOF)的实例中删除用于复制的RDB文件。

rdb-del-sync-files no

如果设置为yesRedis会在完成初始同步或复制操作后删除这些RDB文件。在某些环境中,由于法规或其他安全考虑,可能需要尽快删除这些文件。但请注意,这个选项仅在实例同时禁用了RDBAOF持久化时才生效。如果启用了任何一种持久化方式,这个选项将被忽略。

如果设置为no(默认值),Redis将保留这些RDB文件。在某些情况下,这可能是有用的,例如,如果你希望稍后能够重新使用这些文件来恢复数据或重新配置复制。

此外,还有另外一种替代方法(在某些情况下可能是更好的方法),即在主节点和从节点上都使用无盘复制(diskless replication)。然而,在从节点上,无盘复制并不总是可行的选项。

3.8 dir

dir 用于指定RDB文件和AOF文件的存储目录。

dir ./

./ 表示当前目录。修改时请确保Redis进程对该目录有写入权限。如果在配置文件中没有指定dir配置项,会使用默认的工作目录,即服务器启动时的当前目录,或者是在编译时指定的目录。

4. save/bgsave 命令

Redis save 命令执行一个同步保存操作,将当前 Redis 实例的所有数据快照以 RDB 文件的形式保存到硬盘。

执行命令后会阻塞服务端进程,直到RDB文件创建完毕为止,在整个RDB文件生成过程中服务器不能处理任何命令请求,所以一般情况下我们不会使用该命令触发持久化。

127.0.0.1:6379> save
OK

Redis bgsave 命令执行时,Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短。基本上 Redis 内部所有的RDB操作都是采用 bgsave 命令。

执行后会立即返回 OK 状态码, Redis 父进程继续提供服务以供客户端调用,子进程将DB数据保存到磁盘然后退出。如果操作成功,可以通过客户端命令LASTSAVE来检查操作结果。

127.0.0.1:6379> bgsave
Background saving started
127.0.0.1:6379> lastsave
(integer) 1620784097

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-09 17:42:10       50 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-09 17:42:10       54 阅读
  3. 在Django里面运行非项目文件

    2024-07-09 17:42:10       43 阅读
  4. Python语言-面向对象

    2024-07-09 17:42:10       54 阅读

热门阅读

  1. 设计模式——工厂模式

    2024-07-09 17:42:10       44 阅读
  2. c语言中printf函数参数个数可变实现原理

    2024-07-09 17:42:10       22 阅读
  3. FFmpeg——视频拼接总结

    2024-07-09 17:42:10       24 阅读
  4. php框架详解-symfony框架

    2024-07-09 17:42:10       22 阅读
  5. 红黑树,B+树,B树的结构原理及对比

    2024-07-09 17:42:10       23 阅读
  6. 代码随想录算法训练营:21/60

    2024-07-09 17:42:10       31 阅读
  7. Vue3 对于内嵌Iframe组件进行缓存

    2024-07-09 17:42:10       24 阅读
  8. Kafka 面试题指南

    2024-07-09 17:42:10       30 阅读