持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第10天,点击查看活动详情
【Redis】记一次数据RDB持久化的历程
对于Redis的持久化方式相信大家都是比较熟悉了,其中一种是RDB快照,另外一种是AOF;可是大家伙了解过的它们之间的细节吗?
今天咱们就一起来聊一聊RDB持久化这种方式的细节点。
话不多说,咱们马上开始!
RDB
RDB持久化相当于为当前时点下Redis的数据做了一个快照(生成 dump.rdb 文件),记录下当前时刻Redis的数据。
dump.rdb 文件是Redis在内存中所存储的所有数据的二进制表示,存储非常紧凑。
总的来说,RDB持久化就是将Redis内存中的数据以二进制的格式写进 dump.rdb 文件中(文件中记录的是数据,不是命令)
RDB持久化的触发条件
手动触发
- save命令:这个命令是通过主进程写进 dump.rdb 文件,这样的话,在写文件的过程中,Redis无法处理外部请求,也就是说外部请求阻塞。
- bgsave命令:这个命令会通过子进程写 dump.rdb 文件,主进程可以继续处理Redis外部请求。
自动触发
自动触发是通过配置文件设置的,如下:
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系统调用来实现的,这里咱们就拓展一下,来聊一聊创建子进程的思想。
主要有两种想法:
- 第一种:创建子进程,把父进程的数据都复制一份给子进程
- 第二种:创建子进程,只是将父进程的数据引用复制一份,这种情况下,父子进程的数据引用都指向磁盘的同一个物理地址
第一种方案:
数据引用,其实就是相当于指针之类的东西。
这种方案是实实际际需要复制数据的,比如父进程中有 x G 数据,那么就需要复制 x G的数据。
速度慢!
第二种方案:
这种方案下就只需要复制数据引用即可,数据引用的存储大小可比真实数据小很多。
速度快。
这种情况下,只有在需要写的时候才会真正地去复制磁盘的数据。