rdb
持久化成一个二进制的快照文件,可以用于还原redis的数据。
但是在不同版本的redis中不兼容,在之前用unstable版本的redis启动过一次,再用3.2启动会报rdb的version有问题。
save
源代码
同进程创建rdb文件。server端阻塞。
创建一个文件做校验,然后轮训每个数据库对数据进行二进制编码以及落盘。
bgsave
源代码
创建一个子进程来创建rdb文件。server端不阻塞。
|
|
核心代码就是fork了一个子进程。
但是如果是复制代码块内存需要两份,但是不复制代码的话是怎么保证快照呢。
在Linux程序中,fork()会产生一个和父进程完全相同的子进程,但子进程在此后多会exec系统调用,出于效率考虑,linux中引入了“写时复制“技术,也就是只有进程空间的各段的内容要发生变化时,才会将父进程的内容复制一份给子进程。
写时拷贝(copy on write) 增量技术。
关于(fork)[https://www.cnblogs.com/biyeymyhjob/archive/2012/07/20/2601655.html]
AOF(append only file)
通过保存Redis服务器所执行的写命令来记录数据库状态的。
源代码
|
|
server.aof_buf:aof缓冲,由于aof不是实时刷盘,记录只能先记录到内存中的一个sds中
写入需要等eventloops调用时间事件去运行flush方法才真正的写入文件之中
aof重写
aof文件是记录命令,对同一个key的行为会记录多次,会造成空间的浪费,重写有助于减少空间。
源代码
|
|
同步函数会阻塞,逻辑和rdb差不多。
逻辑来说分析和解析当前的aof文件,对每个key的命令做合并是合理的方式,但是可能会有跨度太大等风险
重写是从key中直接读值的方式来完成。
aof background
aof background 也是fork一个进程去完成操作。
但是和rdb不同的是aof有个增量的不一致问题。rdb仅仅是记录快照。
解决方案:
在执行命令的时候在aof缓冲区和rewrite aof 缓冲区都会写一份。(在aof调用的相同的地方。通过判定子进程id)
等待aof重写完成后,全都flush到aof文件中去。