Redis系列-复制

来源:互联网 发布:myeclipse php 编辑:程序博客网 时间:2024/06/10 00:21

Redis系列-复制

一.什么是复制?

Redis复制是不同Redis实例之间的数据同步,其中我们将被复制的Redis实例称之为主服务器,复制数据的Redis实例称之为从服务器。复制的方式通常为主服务器将数据发送到从服务器,从服务器接收到数据,将数据保存在当前实例中,最终的目标是保证主服务器与从服务器间的数据一致及同步。

 

二.复制的实现


1.同步


1.1 SYNC

从服务器通过向主服务器发送SYNC命令,来实现同步。SYNC命令的执行步骤:

(1)      从服务器向主服务器发送SYNC命令

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

(3)      当主服务器的BGSAVE命令执行完毕时,主服务器会将BGSAVE命令生成的RDB文件发送给从服务器。从服务器接收并加载这个RDB文件,将从服务器的数据库状态更新至主服务器执行BGSAVE命令时相同的数据库状态

(4)    主服务器将缓冲区中记录的写命令传播给从服务器,从服务器执行这些命令,将从服务器数据库的状态更新至主服务器当前的状态。


1.2 PSYNC

Redis2.8版本之后使用PSYNC命令替代SYNC命令来执行复制时的同步操作。PSYNC支持完整重同步和部分重同步两种模式。

1.2.1 完整重同步

完整重同步主要用于初次复制的情况。完整重同步的执行步骤同SYNC的执行步骤很像,他们都是通过让主服务器创建RDB文件并发送给从服务器,以及向从服务器传送缓冲区的写命令来进行同步。

1.2.2 部分重同步

1.2.2.1部分重同步的作用

部分重同步用于处理断线后重复制的情况:当从服务器在断线后重新连接到主服务器时,如果条件允许,主服务器可以将断线后这一段时间执行的血命令发送给从服务器,从服务器只接收并执行这些写命令,就可以将从服务器数据库的状态更新至主服务器当前的状态。


1.2.2.2 部分重同步实现构成
1.2.2.2.1 复制偏移量

1.主服务器和从服务器分别维护一个复制偏移量

2.主服务器每次向从服务器传播N个字节数据时,就将自己的复制偏移量的值加上N

3.从服务器每次接收到主服务器传来的N个字节的数据时,就将自己的复制偏移量加上N

4.通过对比主从服务器的复制偏移量可以很容易的知道主从服务器是否处于一致状态

1.2.2.2.2 复制积压缓冲区

复制积压缓冲区是由主服务器负责维护的一个固定长度先进先出的队列,默认大小为1MB。当主服务器进行命令传播时,它不仅会将写命令发送给所有从服务器,还会将写命令写入到命令积压缓冲区里面。复制积压缓冲区会为队列中的每个字节记录相应的复制偏移量。

   当从服务器重新连接到主服务器时,从服务器通过PSYNC命令将自己的复制偏移量OFFSET发送个主服务器,主服务器根据此偏移量来觉得此从服务器执行何种同步操作:

1.      当offset偏移量之后的数据仍然存在于复制积压缓冲区中,那么主服务器将对从服务器执行部分重同步操作。

2.      相反,当offset偏移量之后的数据不存在于复制积压缓冲区中,那么主服务器将对从服务器执行完整重同步操作。

复制积压缓冲器的大小确定:2*second(服务器短线后重新连上主服务器所花费的时间)*write_size_per_second(主服务器每秒产生的写命令数量)

1.2.2.2.1 服务器运行ID

Runid是服务器运行id,每个Redis服务器都有自己的运行ID,在服务器启动时生成,由40个随机的十六进制字节组成。当从服务器对主服务器进行初次复制时,主服务器会将自己的Runid发送给从服务器,从服务器会将这个运行id保存起来。当从服务器断线并重新连接到一台主服务器时,从服务器将向当前的主服务器发送之前保存的运行ID。

1.      如果从服务器保存的运行ID和主服务器的运行ID相同,那么说明从服务器在断线之前连的就是当前这台主服务器,主服务器可以继续执行部分重同步操作。

2.      相反,如果从服务器保存的运行ID和主服务器的运行ID不同,那么说明从服务器在断线之前连的不是当前这台主服务器,主服务器可以继续执行完整重同步操作。

 

2.命令传播

2.1 什么是命令传播

在同步操作完成后,主服务器与从服务器之间的数据状态达到一致。这种一致并不是一成不变的。每当主服器执行客户端的写命令后,主服务器的数据就有可能被修改,从而造成主从数据库的数据不一致的情况。

为了让主服务器与从服务器再次回到数据一致状态,主服务器需要对从服务器执行命令传播操作:主服务器将造成主从服务器数据不一致的命令传播给从服务器执行,从而使主从服务器数据状态再次达成一致状态。

2.2    心跳监测

在命令传播阶段,从服务器默认会以每秒一次的频率,向主服务器发送命令:

REPLCONF ACK  <replication_offset>

其中replication_offset是从服务器的复制偏移量。

发送replication_offset命令对于主服务器有三个作用:

1.  监测主服务器的网络连接状态

当主服务器1秒没有收到从服务器发来的replication_offset命令,那么主服务器就知道主从服务器之间的连接出现问题了。

2.  辅助实现min-slaves选项

Redis通过min-slaves-to-write和min-slaves-max-lag两个属性防止主服务器在不安全的情况下执行写命令。

例如:min-slaves-to-write 3   min-slaves-to-write5 代表从服务器的数量少于3个,或者三个从服务器的延迟值都大于或等于5秒时,主服务器拒绝执行写命令。

 

3.  检测命令丢失

当从服务器向主服务器发送REPLCONF ACK命令时,主服务器如果发觉从服务器的复制偏移量小于自己的复制偏移量,主服务器就会根据从服务器的提交的复制偏移量,在复制积压缓冲区里面找到从服务器缺少的数据,并将这些数据重新发送给从服务器。



原创粉丝点击