【Redis】记一次数据RDB持久化的历程

113 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第10天,点击查看活动详情

【Redis】记一次数据RDB持久化的历程

对于Redis的持久化方式相信大家都是比较熟悉了,其中一种是RDB快照,另外一种是AOF;可是大家伙了解过的它们之间的细节吗?

今天咱们就一起来聊一聊RDB持久化这种方式的细节点。

话不多说,咱们马上开始!

RDB

RDB持久化相当于为当前时点下Redis的数据做了一个快照(生成 dump.rdb 文件),记录下当前时刻Redis的数据。

dump.rdb 文件是Redis在内存中所存储的所有数据的二进制表示,存储非常紧凑。

总的来说,RDB持久化就是将Redis内存中的数据以二进制的格式写进 dump.rdb 文件中(文件中记录的是数据,不是命令)

RDB持久化的触发条件

手动触发

  1. save命令:这个命令是通过主进程写进 dump.rdb 文件,这样的话,在写文件的过程中,Redis无法处理外部请求,也就是说外部请求阻塞。
  2. bgsave命令:这个命令会通过子进程写 dump.rdb 文件,主进程可以继续处理Redis外部请求。

自动触发

自动触发是通过配置文件设置的,如下:

image.png

save 3600 1

save 300 100

save 60 10000

上述的命令 save 60 10000是指 60 秒内有10000 个key被修改才触发RDB;不然的话,就等到300秒之后,如果有100个key被修改,则触发RDBsave 300 100;不然的话,就等到3600秒之后,如果有1个key被修改,则触发RDBsave 3600 1

可以看到自动触发的条件也是有讲究的,越多修改越容易触发持久化,时间越久,越容易触发持久化;只不过上述的命令是将两者结合起来了。

这里有一点需要十分注意的就是:

自动触发中,虽然配置文件写的是 save但是它触发的是 bgsave

巧妙创建子进程——CopyOnWrite思想体现

在RDB持久化过程中触发创建子进程是通过fork系统调用来实现的,这里咱们就拓展一下,来聊一聊创建子进程的思想。

主要有两种想法:

  1. 第一种:创建子进程,把父进程的数据都复制一份给子进程
  2. 第二种:创建子进程,只是将父进程的数据引用复制一份,这种情况下,父子进程的数据引用都指向磁盘的同一个物理地址

第一种方案:

image.png

数据引用,其实就是相当于指针之类的东西。

这种方案是实实际际需要复制数据的,比如父进程中有 x G 数据,那么就需要复制 x G的数据。

速度慢!

第二种方案:

image.png

这种方案下就只需要复制数据引用即可,数据引用的存储大小可比真实数据小很多。

速度快。

这种情况下,只有在需要写的时候才会真正地去复制磁盘的数据。

image.png