部分重同步的实现
部分重同步功能由以下三个部分构成:
- 主服务器的复制偏移量和从服务器的复制偏移量
- 主服务器的复制积压缓冲区
- 服务器的运行ID
复制偏移量
执行复制的主从服务器都会保存一个复制偏移量:
- 主服务器每次向服务器传播N个字节的数据的时候,就将自己的复制偏移量+N
- 从服务器每次接收到主服务器传过来的N个字节的数据时,就将自己的复制偏移量的值加上N
开始状态
假设传输了14个字节后的状态
通过对比主从服务器的复制偏移量可以判断主从服务器是否处于一致性状态,相同则处于,不同则不处于。
复制挤压缓冲区
复制挤压缓冲区是由服务器维护的一个固定长度的队列,默认大小为1MB(固定长度的队列的长度是固定的,只有当入队元素的数量大于队列长度时,最先入队的元素才会被弹出,新元素才会入队)。
主服务器的复制挤压缓冲区会保存着一部分最近传播的写命令,并且复制挤压缓冲区会为队列中的每个字节记录相应的偏移量
偏移量 | 。。。。 | 10087 | 10088 | 10089 | 10090 | 10091 | 10092 | 10093 |
字节值 | 。。。。 | '*' | 3 | '\r' | '\n' | 's' | 4 | 'T' |
当从服务器重新连上主服务器时,从服务器会通过PSYNC命令将自己的复制偏移量offset发送给主服务器,主服务器会根据这个复制偏移量来决定对从服务器执行何种同步复制
- 如果offset偏移量之后的数据(也就是offset+1的数据)仍然存在于复制挤压缓冲区里面,那么主服务器就会进行部分同步操作
- 如果不存在复制挤压缓冲区里面,那么主服务器进去完整同步操作
服务器运行ID
每个Reids服务器都有自己的运行ID,运行ID在服务器启动时自动生成,由40个随机的十六进制字符组成。
当从服务器对主服务器进行初次复制时,主服务器会将自己的运行ID发送给从服务器,而从服务器则会将这个运行ID保存起来,当从服务器断线并重新连上一个主服务器时,从服务器将向当前的主服务器发送之前保存的运行ID:
- 如果从服务器保存的运行ID和当前连接的主服务器的运行ID相同,那么说明从服务器断线之前复制的就是当前连接的这个主服务器,主服务器可以尝试执行部分重同步操作
- 如果从服务器保存的运行ID和当前连接的主服务器的运行ID并不相同,那么说明从服务器断线之前复制的主服务器并不是当前连接的这个主服务器,主服务器将对从服务器进行完全同步操作。