Skip to content

主从复制原理

Mota edited this page Jan 12, 2018 · 2 revisions

在进行主从复制时,当主redis收到psync请求后,首先主节点redis会先阻塞后续的写操作,然后会与ssd读写进程确认socket缓冲以及用户buffer中所有rocksdb写操作已经做完,当确认写操作做完后,会通知ssd读写进程生成rocksdb快照文件,rocksdb快照生成后会通知redis,redis收到rocksdb快照生成的消息后进行BGSAVE生成RDB文件。开始生成RDB文件时,redis取消写阻塞,写操作继续执行,并且从此时开始所有的写操作会append到redis的slave buffer里。

然后就可以开始向从节点swapdb传输数据了。数据传输的过程分为两个阶段,第一个阶段是传输redis RDB和rocksdb snapshot文件(即主从复制时所有的存量数据),第二个阶段是存量数据传输完成后,将redis的slave buffer的增量写操作发给从节点redis,进入增量同步阶段。

在swapdb中,主从复制时传输RDB和rocksdb快照是通过两个连接分别进行的,RDB文件通过主从Redis之间的连接发送,RDB传完后该连接被继续用于主从同步。主从Rocksdb之间也会新建一个连接用于发送snapshot文件,snapshot文件发送完成后该连接会被断开。

这里需要注意的是,传输存量数据的过程可能会耗时比较久,比如说rocksdb snapshot达到几百G时,而redis的slave buffer大小是有限的,如果写入QPS比较高并且rocksdb snapshot文件较大,可能会导致rocksdb snapshot还没传输完成但redis的slave buffer就溢出了的情况。所以,swapdb对这种情况也进行了优化:swapdb不需要等到redis RDB和rocksdb snapshot都传输完成才开始将主redis的slave buffer的增量写操作发给从节点redis,只要RDB文件传输完成,主redis就可以开始发送增量操作给从redis了,在rocksdb snapshot传完之前,从redis会将接收到的增量操作记录在内存中,等到rocksdb snapshot传完后再进行命令的重放,这样就大大减小了主redis上的slave buffer数据量。