:::tipredis
SLAVEOF host:port 命令能够将当前服务器去复制目标服务器,进行复制中的主从服务器的数据库将保存相同的数据,概念上称为数据库状态一致数据库
:::服务器
当从服务器发送SLAVEOF
命令要求复制主服务器时,从服务器首先执行同步
操做,即将从服务器的数据库状态更新至主服务器当前所处的数据库状态,具体步骤以下网络
SYNC
命令BGSAVE
命令,在后台生成RDB文件,并使用缓冲区记录从如今执行BGSAVE
以后执行的全部写命令BGSAVE
以后,主服务器会将RDB文件发送给从服务器,从服务器接收并载入这个RDB文件同步操做完成后,主从服务器目前的数据库状态达到一致,但这种状态不是一成不变的,每当主服务器执行客户端发送的写命令时,主从服务器的数据库就再也不一致设计
因此为了保持主从服务器的数据一致,主服务器须要对从服务器执行命令传播:将写命令发送给从服务器,当从服务也执行完后,主从服务器将再次回到一致状态3d
旧版复制功能的缺陷主要体如今从服务器断线重连的处理code
如上图的状况,从服务器在某一刻断线,再此期间主服务器增长了k3,k4两个键,按目前的实现逻辑,从服务器在以后重连后,依旧是再次发送SYNC
命令进行同步(主服务器生成和发送RDB文件给从服务器载入)cdn
但其实从服务器主须要断线期间的k3,k4键便可,RDB文件中的其余键信息对从服务器来讲都是没必要要的blog
:::tip队列
SYNC是一个很是耗资源的操做
:::
为了解决断线重连后的重同步问题,Redis2.8之后使用了PSYNC
代替SYNC
进行同步操做,有如下两种模式:
PSYNC ? -1
PSYNC runid offset
如下是执行部分重同步时的通讯过程
部分重同步主要由三个部分组成
每个服务器都会分别维护一个复制偏移量:
那么经过对比主从服务器的复制偏移量就能够知道
经过复制偏移量能够知道主从服务器之间缺失了多少数据,那么缺失的数据是什么?要去哪里找回来呢?
这里就用上了复制积压缓冲区了
当主服务器进行命令传播
时,它不只将写命令发送给全部从服务器,还会将写命令放进一个固定长度的先进先出的队列
里,这个队列就是复制积压缓冲区(默认大小是1MB)
当从服务器重连后,从服务器经过PSYNC
命令将本身的复制偏移量发送给主服务器
复制偏移量
以后的数据还在复制积压缓冲区
中,那么进行部分重同步
的操做复制偏移量
以后的数据不在复制积压缓冲区
中,那么进行完整重同步
的操做:::tip
如何调整复制积压缓冲区的大小
经过redis.conf中的repl-backlog-size进行调整
通常调整为 2 * 断线重连所需的平均秒数 * 主服务器每秒产生的写命令数量
:::
:::tip
每一个Redis服务器都拥有本身的运行ID
运行ID由服务器启动时生成,由40个随机的十六进制字符组成
:::
初次复制时,从服务器会保存主服务器的运行ID
当从服务器断线重连时,从服务器将这个运行ID发送给主服务器:
相同
,则说明断线前复制的就是当前链接的主服务器,主服务器能够根据条件尝试进行部分重同步
不一样
,则说明断线前复制的不是当前链接的主服务器,主服务器将对从服务器进行完整重同步
:::tip
在命令传播阶段,从服务器默认一秒一次的速率,向主服务器发送指令
REPLCONF ACK <replication_offset>
其中replication_offset时从服务器当前的复制偏移量
:::
发送REPLCONF ACK命令主要由三个做用: