天天看点

Redis设计与实现知识点总结-主从复制复制

复制

用户可以通过执行SLAVEOF命令或者设置其选项,让一个服务器去复制另一个服务器。这样形成了简易化集群。

在2.8版本以前主从复制的机制是:

从服务器主动请求复制,主服务器执行BGSAVE命令,将生成的RDB文件,发送给从服务器,并在此时使用一个缓冲区缓冲生成RDB文件以后没有写入的命令。

从服务器接受到RDB文件进行数据的更新。 然后接受主服务器传来的缓冲区的命令,执行进行同步处理。

复制断线问题解决方法:

当从服务器在复制中重启会重新向服务器发送一个指令提示主服务器继续复制,而主服务器会重新生成RDB文件等操作,最后将文件发送给从服务器。

从这种方法中我们可以得出,主服务器做了两次生成RDB操作,而且,两次RDB文件里面相差的数据不是很大(假设在正常使用的情况下,而非这一秒添加大量数据,下一秒删除大量数据这种极端情况下),所以这样及其浪费主服务器的性能。

自2.8以后的版本:

为了解决断线重复生成RDB文件造成的低效问题。Redis使用了新的命令来进行提示主服务器我又连上了。

部分重同步机制,当从服务器在断线重连后,主服务器将主从服务器连接断开期间执行的写命令发送给从服务器,而从服务器只需要执行断开期间丢失的命令即可。

部分重同步机制,原理为主从服务器分别维护一个复制偏移量。

每次主服务器向从服务器传播N个字节时,会将自己的复制偏移量加上N。

从服务器每次收到请求后,会将自己的复制偏移量也加上N

这样,如果主从服务器处于一致的状态,则复制偏移量是相同的。

我们考虑这么一个问题,当主节点向从节点发送一个几个字节的数据,而从服务器断线了,这时候别的从服务器能够接受数据并成功返回收到了。当从服务器上线后数据肯定与主服务器不一致性,那么这时候应该执行全部复制同不,还是部分重同步功能那?

在主服务器发送命令到从服务器的时候,自己会将命令发送到一个自己维护的缓冲区中,缓冲区的大小为1MB使用了FIFO队列的结构。所以我们可以了解到,如果从服务在这个缓冲区中查找自己的复制偏移量,如果找的了就使用部分重同步,如果没有找到就实行完全同步。

服务器ID

从服务器和主服务器都保存着一个ID,当从服务器与主服务器一致时,说命从服务器是这个主服务器上的从节点。

在集群中,从服务器默认每秒一次的频率告知主服务器自己的状态以及复制偏移量。