Redis ⑩-持久化 || RDB
持久化
Redis 的数据是存储在内存里的,所以只要断电后,这些数据就都会丢失了。如果这些数据都比较重要,那么就会造成比较大的损失。
依此,Redis 提供了持久化功能,可以将内存中的数据保存到磁盘里,防止数据丢失。
在存储数据时,Redis 即会写入数据到内存,也会把数据写入到硬盘。但读取数据还只是从内存中读取,硬盘中的数据只是为了将数据恢复到内存。
RDB 持久化
RDB(Redis DataBase,快照方式),是一种定期将内存中的数据写入到磁盘的持久化方式。在达到某个时限和特定条件后,Redis 会触发 RDB 持久化操作,将内存中的数据写入到磁盘里。
写入到磁盘里的文件是 Redis 规定的一种二进制文件,其后缀为 .rdb
。
该二进制通常被称为快照文件,其保存了 Redis 在某个时间点上的整个数据集。如果 Redis 正常或异常关闭,那么在下次启动时,Redis 会自动加载该快照文件,将数据集恢复到内存中。
触发方式
RDB 持久化可以手动触发,也可以通过配置自动触发。
手动触发
手动触发可以通过 save
或 bgsave
命令来触发。
save
命令会阻塞 Redis,直到 RDB 文件写入完成。阻塞期间,Redis 不能处理任何其他命令。
如果数据量比较大,不建议使用,其效果类似 keys *
bgsave
命令则会在不影响 Redis 服务的前提下,同时保存 RDB 文件到磁盘。
Redis 不是单线程模型吗?这又是如何做到的?
Redis 采用的确实是单线程模型,但它是通过额外创建一个子进程来执行 RDB 持久化操作的。也就是通过 “多进程” 的方式执行。
通过上述流程我们可以看出:
- 在执行
bgsave
后,父进程(Redis 主进程)就会先检测是否有其他子进程正在工作的子进程,如果有,则直接返回。 - 如果没有,则会
fork
一个子进程来处理 RDB 持久化操作。 - 子进程处理完毕后,将生成的 .rdb 文件写入到磁盘中,然后通知到父进程,随机该子进程被销毁。
自动触发
自动触发的时机和条件可以通过配置文件来设置。
打开配置文件后,找到 save
选项,可以看到默认的配置:
save 900 1
save 300 10
save 60 10000# save ""
save
选项的三个参数分别表示:
save 900 1
表示在 900 秒(15 分钟)之后,如果至少有 1 个键发生变化,则执行一次 RDB 持久化操作。save 300 10
表示在 300 秒(5 分钟)之后,如果至少有 10 个键发生变化,则执行一次 RDB 持久化操作。save 60 10000
表示在 60 秒(1 分钟)之后,如果至少有 10000 个键发生变化,则执行一次 RDB 持久化操作。save ""
表示关闭 RDB 持久化功能。
可以根据自己的需要修改这些参数。
其他方式的触发
通过 service redis-server <restart | stop>
命令重启或关闭 Redis 时也可以触发 RDB 持久化操作。这是因为 Redis 会在关闭时自动执行 RDB 持久化操作。
但如果是异常关闭,比如突然断电或者通过 kill
命令强制关闭,那么 Redis 则不会自动执行 RDB 持久化操作。
通过 shutdown
命令(Redis 提供的一个命令)关闭 Redis 服务器时,也会自动执行 RDB 持久化操作。
Redis 进行主从复制时,主节点会自动生成 RDB 文件,并通过网络发送给从节点进行同步。
执行 flushall
命令时,不仅仅会情况所有键值对,RDB 文件里的数据也会被清空。
.rdb 文件
RDB 文件是一个二进制文件,其内容是 Redis 在某个时间点上的整个数据集。
Redis 生成的 .rdb 文件是存放在 Redis 的工作目录下的,默认路径为 /var/lib/redis
。
其工作目录可以在配置文件中进行修改,找到 dir /var/lib/redis
选项,修改其值即可。
.rdb 文件的文件名由 Redis 的配置参数 dbfilename
来决定,默认文件名为 dump.rdb
。
.rdb 文件的处理:
- 保存:RDB 文件保存在
dir
配置指定的目录(默认为/var/lib/redis
)下,文件名通过dbfilename
配置指定的名称(默认为dump.rdb
)。 - 压缩:Redis 默认采用 LZF 算法对生成的 RDB 文件做压缩处理,压缩后的文件远远小于内存大小,默认开启,可以通过配置
rdbcompression
选项进行开关。(压缩文件尽管会消耗 CPU,但可以大幅降低文件的体积,方便保存到磁盘以及通过网络进行传输到其他节点,因此建议开启) - 校验:如果 Redis 启动时加载到损坏的 RDB 文件会拒绝启动。这时可以通过使用Redis 自带的
redis-check-rdb
工具来检查 RDB 文件的正确性。
RDB 是会把数据写入到新的文件中,然后使用新的文件替换旧的文件,即使数据没有发生任何改变,也会生成新的文件然后替换。
可以通过 stat 文件名
命令查看 RDB 的 inode
编号,可以看到,每执行一次 RDB 持久化操作,inode
编号都会发生变化。
优缺点
- RDB 是一个紧凑压缩的二进制文件,代表 Redis 在某个时间点上的数据快照。非常适用于备份,全量复制等场景。比如 6 小时执行 bgsave 备份,并发 RDB 文件复制到远程机器或者文件系统中(如 hdfs)用于灾难恢复。
- Redis 加载 RDB 恢复数据远远快于 AOF 方式。
- RDB 方式数据没办法做到实时持久化 / 秒级持久化。因为 bgsave 每次运行都要执行 fork 创建子进程,属于重量级操作,频繁执行成本过高,会对 Redis 性能造成影响。
DB 方式数据没办法做到实时持久化 / 秒级持久化**。因为 bgsave 每次运行都要执行 fork 创建子进程,属于重量级操作,频繁执行成本过高,会对 Redis 性能造成影响。 - RDB 文件使用特定二进制格式保存,Redis 版本演进过程中有多个版本的 RDB 格式,不同版本之间的数据兼容性较差。