有道无术,术尚可求,有术无道,止于术。
本系列Redis 版本 7.2.5
源码地址:https://gitee.com/pearl-organization/study-redis-demo
文章目录
1. 概述
Redis
的数据都在内存中,一旦服务器宕机或者重启,所有的数据都将丢失。Redis
提供了持久化机制,将内存数据进行磁盘持久化保存,以便重启时重新加载数据到内存中。
目前提供了两种持久化机制:
RDB
(Redis Database
):默认方式,在指定的时间间隔内,通过创建快照保存数据,重启时,加载快照数据AOF
(Append 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.conf
中 RDB
相关的配置如下:
################################ 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
)操作(例如SET
、LPUSH
等),则执行一次 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
配置 Redis
在 RDB
持久化过程中遇到错误时,是否应该停止接受新的写操作,默认为 yes
。
stop-writes-on-bgsave-error yes
如果设置为yes
(默认值),那么在执行BGSAV
E命令时如果遇到错误(例如磁盘空间不足、权限问题等),Redis
会停止接受新的写操作,直到BGSAVE
命令成功执行。这样做的目的是为了让用户意识到数据没有正确地持久化到磁盘上,从而可以采取适当的措施。
如果设置为no
,即使BGSAVE
命令失败,Redis
也会继续接受新的写操作。这意味着数据可能会丢失,因为错误没有导致Redis
停止写入。然而,如果你已经设置了适当的Redi
s服务器监控和持久化策略,并且希望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
资源。
如果设置为no
,Redis
将不会使用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
文件的抗损坏能力。
如果设置为no
,Redis
将不会在文件的末尾添加校验和。这样可以减少保存和加载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
。但在某些情况下,尤其是当安全性更重要时,可以设置为yes
或clients
。
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
如果设置为yes
,Redis
会在完成初始同步或复制操作后删除这些RDB
文件。在某些环境中,由于法规或其他安全考虑,可能需要尽快删除这些文件。但请注意,这个选项仅在实例同时禁用了RDB
和AOF
持久化时才生效。如果启用了任何一种持久化方式,这个选项将被忽略。
如果设置为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