史上最细Redis保姆级教学2-深入了解Redis持久化与分布式部署
Redis的持久化机制
Redis 提供了多种持久化方式,用于将内存中的数据保存到磁盘,以便在 Redis 重启后能够恢复数据。Redis 的持久化机制主要有以下几种:
RDB(Redis Database)快照持久化
RDB(Redis Database)快照是 Redis 提供的一种持久化机制,它通过定期将 Redis 内存中的数据保存到磁盘上的二进制文件 dump.rdb
中,以便在 Redis 重启时能够恢复数据。RDB 快照的生成是基于设定的条件触发的,通常通过配置文件中的 save
参数来控制。
RDB 快照的工作原理
-
触发条件: Redis 可以在特定的时间间隔内(如 N 秒)检测到至少 M 次写操作时,自动生成一次 RDB 快照。通过这种方式,Redis 实现了自动持久化。在配置文件中,可以使用
save
命令来指定这些条件:save 900 1 # 900秒(15分钟)内至少有1个写操作 save 300 10 # 300秒(5分钟)内至少有10个写操作 save 60 10000 # 60秒(1分钟)内至少有10000个写操作
-
生成快照: 当满足某个
save
条件时,Redis 会触发生成 RDB 快照。这个快照是将当前的数据库状态(内存中的所有键值对)保存到一个二进制文件中,通常是dump.rdb
文件。Redis 通过将当前的内存数据通过写入磁盘来保存数据。 -
手动触发: 你可以通过命令手动触发 RDB 快照的生成:
SAVE
:会阻塞 Redis 主线程,直到生成快照为止。执行时会导致 Redis 暂停处理其他客户端请求,直到快照写入磁盘完成。BGSAVE
:会在后台生成快照,使用的是写时复制技术(Copy-On-Write,COW),这样可以在生成快照的同时,继续处理其他客户端请求,非阻塞操作。
自动生成 RDB 快照时,默认 Redis 会在后台使用 BGSAVE
方式生成快照。这意味着,Redis 会定期检查是否满足触发条件,如果满足条件,Redis 会异步地生成 RDB 快照,而不会阻塞主线程的正常操作。
BGSAVE
和 SAVE
的对比
特性 | SAVE |
BGSAVE |
---|---|---|
阻塞行为 | 阻塞 Redis,直到完成快照写入磁盘 | 不阻塞 Redis,生成子进程进行快照操作 |
性能影响 | 执行期间 Redis 无法响应其他请求 | 子进程生成快照,不影响主线程执行,但可能有短暂的阻塞 |
适用场景 | 希望同步保存快照并且可以容忍阻塞操作 | 希望异步保存快照并继续响应其他请求 |
复杂度 | O(n) | O(n) |
使用方式 | 通常用于测试或备份场景,避免影响性能 | 在生产环境中更常用,后台异步生成快照 |
写时复制(Copy-On-Write,COW)
BGSAVE
使用了写时复制技术(COW),这意味着当 Redis 在主线程和 BGSAVE
子进程中同时操作数据时,操作系统会在数据发生写入时,为主线程的修改创建数据的副本。具体来说:
- 当主线程修改数据时,操作系统会复制被修改的内存页,不会影响正在执行的
BGSAVE
子进程。 BGSAVE
子进程会将这些被修改的数据写入 RDB 文件,而主线程依然可以继续进行修改操作。
因此,BGSAVE
在生成快照时不会阻塞主线程的操作,可以继续响应客户端请求,确保 Redis 的高可用性。
RDB 恢复流程的详细步骤
- 启动 Redis 服务器:
- Redis 启动时,首先会打开
dump.rdb
文件。这个文件通常位于 Redis 的工作目录下。
- Redis 启动时,首先会打开
- 解析文件头:
- RDB 文件的开头包含一个魔术值,用来标识文件是否是有效的 RDB 文件。Redis 会验证这个魔术值来确保文件格式正确。
- 逐个数据库恢复:
- Redis 支持多个逻辑数据库(默认为 16 个),并且每个数据库的数据都会单独存储在 RDB 文件中。
- Redis 会遍历 RDB 文件中的每个数据库,并依次恢复其中的数据。
- 恢复数据类型:
- RDB 文件存储了 Redis 中不同类型的数据(如字符串、哈希、列表、集合、有序集合等)。Redis 会根据 RDB 文件中的数据格式,恢复这些数据到内存中。
- 恢复过期时间:
- 如果数据项有过期时间(如
SET
命令设置了过期时间),RDB 文件中会记录这个过期时间。在恢复时,Redis 会将过期时间加载到内存中。
- 如果数据项有过期时间(如
- 恢复完成,进入正常工作状态:
- 数据恢复完成后,Redis 会完成启动过程并开始处理客户端的请求。此时,Redis 内存中的数据已经与
dump.rdb
文件中的数据一致。
- 数据恢复完成后,Redis 会完成启动过程并开始处理客户端的请求。此时,Redis 内存中的数据已经与
RDB 恢复的性能特点
- 恢复速度较快:RDB 数据恢复的速度较快,因为 Redis 会一次性加载整个快照,不需要逐条执行命令(如 AOF)。这使得 Redis 启动时可以迅速恢复数据。
- 内存占用:在恢复过程中,Redis 会将数据加载到内存中,因此对内存的需求较大。如果 RDB 文件非常大,恢复过程可能会占用较多的内存。
- 阻塞问题:由于 RDB 恢复是一个阻塞操作,在恢复过程中,Redis 可能会暂停处理客户端请求。恢复完成后,Redis 会恢复正常的服务。
使用 RDB 恢复时的注意事项
- 数据一致性:
- 如果 Redis 在生成 RDB 快照时正好在处理一些写操作,生成的快照可能并不完全一致。例如,可能某些数据在 RDB 快照中已经保存,而另一些数据尚未保存。虽然这种情况不常见,但它是 RDB 持久化的一个潜在问题。AOF 持久化机制能提供更高的数据一致性。
- 丢失的数据:
- 如果 Redis 在生成 RDB 快照和恢复数据之间崩溃,可能会丢失 RDB 快照生成后但尚未保存的数据。因此,RDB 机制的恢复是基于最后一个快照的,可能会丢失最近的修改数据。
- 结合 AOF 使用:
- 为了弥补 RDB 可能丢失最近数据的缺点,Redis 可以同时启用 AOF 持久化(
appendonly
),这样在每次写操作时,数据会被追加到 AOF 文件中。这样,Redis 可以结合 RDB 和 AOF 实现更高的持久性保障。
- 为了弥补 RDB 可能丢失最近数据的缺点,Redis 可以同时启用 AOF 持久化(
RDB快照总结
RDB 快照
是 Redis 提供的一种高效持久化机制,通过定期将数据快照保存到磁盘来保证数据不丢失。它具有较快的恢复速度和较小的文件大小,适合对性能要求高且数据丢失可接受的场景。对于对数据安全性有更高要求的应用,可以考虑结合使用 AOF
持久化。在RDB
生成的两种常用方式中, BGSAVE
和 SAVE
提供了不同的快照生成方式,前者更适合生产环境,后者适合同步备份操作。
AOF(Append-Only File)追加文件持久化
AOF(Append-Only File)
是 Redis 提供的一种持久化机制,它通过将每一个修改 Redis 数据集的命令(如 SET
、HSET
等)记录到一个日志文件(appendonly.aof
)中,来确保数据的持久性。与 RDB 快照机制不同,AOF
是基于日志的持久化方式,即每次写操作都会记录在日志文件中,通过这些命令可以恢复 Redis 数据集。在 Redis 重启时可以通过重新执行这些命令来恢复数据。这种方式的优点是数据持久化程度较高,在选择合适的同步策略的情况下,几乎没有数据丢失的风险,但相对来说,性能开销较大。
AOF 的工作原理
-
写命令记录: 每当 Redis 执行一个写命令时(例如
SET
、HSET
、DEL
等),该命令会被以 RESP 协议 格式记录到 AOF 文件中。例如,当执行SET feray 666
时,AOF 文件将记录如下内容:1 *3 2 $3 3 set 4 $5 5 feray 6 $3 7 666 #如果命令包含过期时间(例如 `SET` 命令带有 `EX` 或 `PX` 参数),AOF 会记录过期时间的时间戳,而不是记录原始命令。例如,执行 `SET feray 888 EX #1000` 时,AOF 文件记录的内容会包括设置过期时间的命令 `PEXPIREAT`,如下所示: 1 *3 2 $3 3 set 4 $5 5 feray 6 $3 7 888 8 *3 9 $9 10 PEXPIREAT 11 $5 12 feray 13 $13 14 1604249786301 #其中,`1604249786301` 是设置的过期时间戳。
这里的
1 *3
表示命令有 3 个参数,接下来的行表示每个参数的具体内容,$3
表示这个参数有 3 个字符,set
、feray
和666
分别是命令的内容。 -
AOF 重写: AOF 文件随着时间的推移会变得非常大,Redis 会定期对 AOF 文件进行重写(AOF rewrite),从而减少 AOF 文件的大小。AOF 重写是一个后台操作,不会阻塞主线程。
#这是重写前的AOF文件demo *3 $3 SET $4 name $5 Alice *3 $3 SET $3 age $2 25 *2 $4 INCR $3 age *2 $3 DEL $4 name #触发aof重写后的aof记录 *3 $3 SET $4 name $5 Alice *3 $3 SET $3 age $2 26
在重写后的 AOF 文件中,只保留了能够重建当前数据状态的命令,即仅保留了
SET name "Alice"
和SET age 26
,INCR
和DEL
命令被省略了。
AOF 持久化的配置选项
在 Redis 中启用 AOF 持久化功能可以通过修改配置文件 redis.conf
中的 appendonly
和 appendfsync
参数。
-
启用 AOF 持久化: 要启用 AOF 持久化,只需在 Redis 配置文件中将
appendonly
设置为yes
:appendonly yes
一旦启用 AOF,每次修改数据集的命令都会被追加到 AOF 文件末尾。
-
配置
fsync
策略:appendfsync
配置项控制着何时将 AOF 文件中的数据同步到磁盘。它有三种设置:appendfsync always
:每次有新命令追加到 AOF 文件时,都会执行一次fsync
,即每次命令都会同步到磁盘。这种方式非常安全,但性能较差,适用于对数据安全性要求非常高的场景。appendfsync everysec
:每秒执行一次fsync
,即每秒将 AOF 文件内容同步到磁盘。这个选项提供了较好的性能和安全性之间的平衡,适用于大多数场景,是 Redis 的默认设置。appendfsync no
:从不执行fsync
,将数据交给操作系统来处理。这样会提高性能,但在发生故障时可能会丢失一些数据。
默认的推荐设置是:
appendfsync everysec
-
AOF 重写:
auto-aof-rewrite-percentage
:当 AOF 文件增长到上次重写时的指定百分比时,触发重写操作。默认是 100%,即 AOF 文件大小是上次重写时的两倍时会触发重写。auto-aof-rewrite-min-size
:指定 AOF 文件最小的大小,只有当 AOF 文件达到这个大小时,才会触发重写操作。默认是 64MB。
AOF 只恢复的过程
当 Redis 启动时,如果只启用了 AOF 持久化机制,Redis 会按以下步骤进行数据恢复:
- 检查 AOF 文件:
- Redis 启动时,会首先检查是否存在 AOF 文件(
appendonly.aof
),并验证它的完整性。如果 AOF 文件存在且是有效的,Redis 将尝试通过执行 AOF 文件中的命令来恢复数据。
- Redis 启动时,会首先检查是否存在 AOF 文件(
- 读取 AOF 文件:
- Redis 会逐条读取 AOF 文件中的命令(例如,
SET
、INCR
、DEL
等命令)。这些命令会被按顺序执行,以恢复数据集到 AOF 文件最后一次保存时的状态。 - AOF 文件的内容是以 Redis 命令的形式存储的,因此 Redis 通过执行这些命令来恢复数据。
- Redis 会逐条读取 AOF 文件中的命令(例如,
- AOF 重写(如果启用):
- 如果启用了 AOF 重写(AOF Rewrite),Redis 会在恢复完数据之后,触发 AOF 重写过程,生成一个新的 AOF 文件。AOF 重写的目的是删除冗余的命令,使 A