从零单排学Redis【铂金一】 (2)

PSYNC命令具有完整重同步和部分重同步两种模式(其实就跟上面所说的初次复制和断线后复制差不多个意思)。

2.1.2完整重同步

下面先来看看完整重同步是怎么实现的:

从服务器向主服务器发送PSYNC命令

收到PSYNC命令的主服务器执行BGSAVE命令,在后台生成一个RDB文件。并用一个缓冲区来记录从现在开始执行的所有写命令

当主服务器的BGSAVE命令执行完后,将生成的RDB文件发送给从服务器,从服务器接收和载入RBD文件。将自己的数据库状态更新至与主服务器执行BGSAVE命令时的状态。

主服务器将所有缓冲区的写命令发送给从服务器,从服务器执行这些写命令,达到数据最终一致性。

完整重同步

2.1.2部分重同步

接下来我们来看看部分重同步,部分重同步可以让我们断线后重连只需要同步缺失的数据(而不是Redis2.8之前的同步全部数据),这是符合逻辑的!

部分重同步功能由以下部分组成:

主从服务器的复制偏移量

主服务器的复制积压缓冲区

服务器运行的ID(run ID)

首先我们来解释一下上面的名词:

复制偏移量:执行复制的双方都会分别维护一个复制偏移量

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

从服务器每次收到主服务器的N个字节,就将自己的复制偏移量加上N

通过对比主从复制的偏移量,就很容易知道主从服务器的数据是否处于一致性的状态!

复制偏移量

那断线重连以后,从服务器向主服务器发送PSYNC命令,报告现在的偏移量是36,那么主服务器该对从服务器执行完整重同步还是部分重同步呢??这就交由复制积压缓冲区来决定。

当主服务器进行命令传播时,不仅仅会将写命令发送给所有的从服务器,还会将写命令入队到复制积压缓冲区里面(这个大小可以调的)。如果复制积压缓冲区存在丢失的偏移量的数据,那就执行部分重同步,否则执行完整重同步。

服务器运行的ID(run ID)实际上就是用来比对ID是否相同。如果不相同,则说明从服务器断线之前复制的主服务器和当前连接的主服务器是两台服务器,这就会进行完整重同步。

所以流程大概如此:

同步的流程

2.1.3命令传播

当完成了同步之后,主从服务器就会进入命令传播阶段。这时主服务器只要将自己的写命令发送给从服务器,而从服务器接收并执行主服务器发送过来的写命令,就可以保证主从服务器一直保持数据一致了!

在命令传播阶段,从服务器默认会以每秒一次的频率,向服务器发送命令REPLCONF ACK <replication_offset> 其中replication_offset是从服务器当前的复制偏移量

发送这个命令主要有三个作用:

检测主从服务器的网络状态

辅助实现min-slaves选项

检测命令丢失

五、最后

画了好久好久的图,终于写完啦。

抛个问题:如果从服务器挂了,没关系,我们一般会有多个从服务器,其他的请求可以交由没有挂的从服务器继续处理。如果主服务器挂了,怎么办?因为我们的写请求由主服务器处理,只有一台主服务器,那就无法处理写请求了?

问题留到下篇解决~~

参考资料:

《Redis设计与实现》

《Redis实战》

如果你觉得我写得还不错,了解一下:

坚持原创的技术公众号:Java3y。回复 1 加入Java交流群

文章的目录导航(精美脑图+海量视频资源):https://github.com/ZhongFuCheng3y/3y

帅的人都关注了

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwjgss.html