曾轼麟
2021-09-08
先回答老师的问题:serverCron函数中,查找到 rdbSaveBackground 函数一共会被调用执行几次? 答:包含直接或者间接,一共调用了4次(不知道还有没有漏的) 1、【直接调用】:server.c(1296行) 如果达到了更改量阈值,等待秒数阈值,延时失败重试达到时间,会进行一次调用。 2、【直接调用】:server.c(1369行) bgsave因为AOF重写的原有被迫推迟,所以在最后需要重新调用。 3、【间接调用】:replicationCron(1340行) -> startBgsaveForReplication -> rdbSaveBackground 主从复制定时任务,通过startBgsaveForReplication,触发的RDB文件保存。 4、【间接调用】:backgroundSaveDoneHandler(1261行) -> backgroundSaveDoneHandlerDisk/backgroundSaveDoneHandlerSocket -> updateSlavesWaitingBgsave -> startBgsaveForReplication -> rdbSaveBackground 如果当前的进程角度是rdb_child_pid子进程,在结束bgsave后可能有机器在等待RDB文件,那么会调用 updateSlavesWaitingBgsave,从而间接的可能调用startBgsaveForReplication函数 补充总结: 本期老师主要介绍了Redis的持久化做法和RDB文件的编码方式,包括文件头部的编码方式,文件的键值对写入的编码方式,还有写入的触发时机等等,也方便我们日后自行解析RDB文件。 此外在本次源码中多次出现了RIO的标识,这里解释一下,RIO其实是unix下的一款IO包,起本质是封装了操作系统I/O,能通过缓冲区的方式调用操作系统I/O去对文件进行读写,此外Redis在保存RDB文件也使用了一些技巧,例如在rdbSave函数中,文件是先写入tmpfile(临时文件)的,最后通过rename的方式修改文件名字来替换掉整个文件,这是安全的文件写入方式,如果在写入期间掉电也并不会导致旧RDB文件损坏,但是也证明在磁盘预留上是需要双倍空间的。
展开
18
Kaito
2021-09-07
1、RDB 文件是 Redis 的数据快照,以「二进制」格式存储,相比 AOF 文件更小,写盘和加载时间更短 2、RDB 在执行 SAVE / BGSAVE 命令、定时 BGSAVE、主从复制时产生 3、RDB 文件包含文件头、数据部分、文件尾 4、文件头主要包括 Redis 的魔数、RDB 版本、Redis 版本、RDB 创建时间、键值对占用的内存大小等信息 5、文件数据部分包括整个 Redis 数据库中存储的所有键值对信息 - 数据库信息:db 编号、db 中 key 的数量、过期 key 的数量、键值数据 - 键值数据:过期标识、时间戳(绝对时间)、键值对类型、key 长度、key、value 长度、value 6、文件尾保存了 RDB 的结束标记、文件校验值 7、RDB 存储的数据,为了压缩体积,还做了很多优化: - 变长编码存储键值对数据 - 用操作码标识不同的内容 - 可整数编码的内容使用整数类型紧凑编码 课后题:在 serverCron 函数中,rdbSaveBackground 函数一共会被调用执行几次?这又分别对应了什么场景? 在 serverCron 函数中 rdbSaveBackground 会被调用 2 次。 一次是满足配置的定时 RDB 条件后(save <seconds> <changes),触发子进程生成 RDB。 另一次是客户端执行了 BGSAVE 命令,Redis 会先设置 server.rdb_bgsave_scheduled = 1,之后 serverCron 函数判断这个变量为 1,也会触发子进程生成 RDB。
展开
共 1 条评论
9
Geek_6580e3
2022-02-10
老师好,能咨询个问题,redis321版本是有unknown RDB format version:7 #3353的bug吗,使用中遇到这个问题,但不知道什么情况下会触发,谢谢