03 RDB 持久化
RDB 持久化是指在客户端输入 save、bgsave
或者达到配置文件自动保存快照条件时,将 Redis 在内存中的数据生成快照保存在名字为 dump.rdb
(文件名可修改)的二进制文件中。
3.1 save 命令
save 命令会阻塞 Redis 服务器进程,直到 RDB 文件创建完毕为止,在 Redis 服务器阻塞期间,服务器不能处理任何命令请求。在客户端输入 save
127.0.0.1:6379> save OK
快照生成完毕,会弹出 DB saved ondisk 的提示。
1349:M 25 Apr 13:16:48.935 * DB saved on disk
3.2 bgsave 命令
bgsave 执行时,主线程会创建一个子进程,专门用于写入 RDB 文件,避免了主线程的阻塞,这也是 Redis RDB 文件生成的默认配置。
127.0.0.1:6379> bgsave Background saving started
PS:bgsave 命令执行期间 SAVE 命令会被拒绝;不能同时执行两个 BGSAVE 命令;不能同时执行 BGREWRITEAOF 和 BGSAVE 命令。
3.3 bgsave 时写数据
bgsave 执行时,Redis 主线程能正常读写数据。读操作时,主线程和 bgsave 子线程互不影响;写操作时,Redis 会利用写时复制技术(Copy-On-Write, COW),生成被修改数据的副本。然后 bgsave 子线程把副本数据写入 RDB。
比如,bgsave 期间,主线程修改键值对 C,过程如下:
但是在这过程中发生宕机了咋办?比如,T0 时刻做了一次快照,T0+t 时刻又做了一次。但是 t 时间内主线程修改完数据 5 和 9,然后 Redis 宕机了,RDB 没记录到修改后的数据。
Redis 重启恢复数据,就会出现数据 5 和 9 丢失的情况,没办法恢复。
这该咋办?我们需要记住那些数据被修改了。
3.4 混合持久化
如下图所示,记录 t 时刻被修改的数据就需要占用额外的空间,而 Redis 是内存数据库,空间非常宝贵。所以,直接记录到内存这种方式不可取。
内存开销比较小的方法是把 t 时间的增量写操作记录到 AOF 日志中,这样既保留了 RDB 的快速恢复,也没占用额外的空间。
如图,T1 和 T2 时刻的修改,用 AOF 日志记录,等第二次做全量快照时,清空 AOF 日志,因为此时的修改都记录到快照中了,恢复不用 AOF 日志了。
庆幸的是 Redis 4.0 就开始提供了这种 RDB + AOF 的持久化方式,开启的配置项是 aof-use-rdb-preamble yes
,它需要配合 AOF 的重写机制实现。
# 开启混合持久化 redis> config set aof-use-rdb-preamble yes OK # AOF 重写 redis> BGREWRITEAOF Background append only file rewriting started
在没有第二次做全量快照之前,它的格式是这样的:前半部分是 RDB 格式,后半部分是 AOF 增量日志。如果这个时候宕机,直接拿 appendonly.aof 恢复数据。
3.5 RDB 优缺点
优点
- 二进制数据,恢复时比 AOF 快
- RDB 的 bgsave 方式主线程不阻塞
缺点
- Redis 意外宕机 时,会丢失部分数据(混合持久化可解决)
- 当数据量比较大时,fork 的过程是非常耗时的,fork 子进程时是会阻塞的,在这期间 Redis 是不能响应客户端的请求的。
04 如何选择?
- 数据不能丢失时,选择内存快照和 AOF 混合使用;
- 如果允许分钟级别的数据丢失,可以只使用 RDB;
- 如果只用 AOF,优先使用 everysec 的配置选项,因为它在可靠性和性能之间取了一个平衡。
05 数据恢复流程
07 总结
本文主要讲解 Redis AOF 、RDB 持久化的原理和两者的优缺点,对比两者后,我还给你总结了 Redis 混合持久化的流程。最后给了你一些选择持久化方案的建议,希望看完你能有所收获。
全文将近字,张图,希望能帮到你。好啦,以上就是狗哥关于 Redis 持久化的总结。感谢各技术社区大佬们的付出,尤其是极客时间,真的牛逼。如果说我看得更远,那是因为我站在你们的肩膀上。希望这篇文章对你有帮助,我们下篇文章见~