Redis学习笔记(2)———部分重同步

  • SYNC同步的缺点
  • PSYNC
  • 部分重同步
  • 复制偏移量
  • 复制积压缓冲区
  • 运行ID


SYNC同步的缺点

在两种情况下需要进行同步操作,即首次进行SLAVEOF操作和断线重连之后。对于第一种,完整的同步是必要的,但是在断线重连后,如果主服务器只进行了少量的写操作,这时再进行一次完整同步就是一个不聪明的决定。因为一次完整的同步包括以下过程:

  1. 从服务器发送SYNC同步命令。
  2. 主服务器收到SYNC同步命令后执行BGSAVE指令,开始生成一个RDB文件,同时缓冲区存储当前开始的数据库写操作。由于生成的RDB文件包含了完整的数据库,该操作会占用主服务器大量的设备资源,包括CPU、内存和磁盘I/O资源。
  3. 主服务器发送RDB文件给从服务器,发送过程会消耗主从服务器之间大量的带宽、流量等网络资源。
  4. 从服务器在接收RDB文件后进行载入,在载入期间,从服务器会因为阻塞而无法处理命令请求。

PSYNC

从Redis2.8版本开始,PSYNC代替了原先的SYNC。PSYNC包含了完整重同步(full resynchronization)和部分重同步(partial resynchronization)。主要就是为了解决原先断线后进行完整重同步出现的低效情况。在断线重连后,在一定条件下,能使用部分重同步,只需要更新部分操作就可以同步至主服务器一致的状态。

部分重同步

部分重同步的操作主要涉及以下三个部分:

  • 复制偏移量(replication offset)
  • 复制积压缓冲区(replication backlog)
  • 运行ID(run ID)

复制偏移量

复制偏移量可以认为是一个计数器,用于统计主服务器和从服务器的操作步骤数。主服务器和从服务器都会分别维护各自的复制偏移量。

  • 主服务器原复制偏移量为redis 订阅广播断开重连 redis断线重连_偏移量,当主服务器向从服务器传播N个字节的数据后,主服务器的复制偏移量加上redis 订阅广播断开重连 redis断线重连_redis_02得到redis 订阅广播断开重连 redis断线重连_数据库_03
  • 从服务器原复制偏移量为redis 订阅广播断开重连 redis断线重连_偏移量_04,收到了主服务器传播的N个字节的数据后,从服务器的复制偏移量加上redis 订阅广播断开重连 redis断线重连_redis_02得到redis 订阅广播断开重连 redis断线重连_数据库_06

通过比较主从服务器的复制偏移量,可以快速地知道主从服务器是否处于一致的状态,比较一个计数量所消耗的资源要远远小于比较服务器完整的数据量所要消耗的资源。

假设主服务器和从服务器在某一时刻保持了相同的复制偏移量redis 订阅广播断开重连 redis断线重连_偏移量_07,这时从服务器断线,主服务器仍在执行传播命令,主服务器复制偏移量为redis 订阅广播断开重连 redis断线重连_redis_08。而从服务器在断线后自然无法收到主服务器的传播命令,其复制偏移量仍为断线时的redis 订阅广播断开重连 redis断线重连_偏移量_07。在重新建立连接后,比较主从服务器的复制偏移量即可很快知道,主从服务器状态不一致,需要进行后续同步操作。

引入复制偏移量的好处就是通过一个计数器,就能很快通过比较得到主从服务器是否保持一致,而不需要通过完整的数据库比较,节省下了大量的服务器资源。

复制积压缓冲区

当出现主从服务器状态不一致时,这时候同步就需要用到了复制积压缓冲区。复制积压缓冲区是由一个主服务器维护的一个固定长度(fixed-size)先进先出(FIFO)的队列,默认的大小为1MB,可以根据实际的服务器需求配置缓冲区大小。

上一节中提到,主服务器在命令传播后,复制偏移量会相应的增加。而同时,相关的写操作会被存入复制积压缓冲区,从队尾入队,队列满时,先入队的元素从队头出队,即出队的写操作将不会被缓冲区保存

下表是一个复制积压缓冲区的例子。每一个偏移量对应一个写操作,可以根据偏移量找到其对应的操作。

偏移量


8913

8914

8915

8916

8917

8918

8919


字节值


‘h’

‘e’

‘l’

‘l’

‘o’

1

‘\n’


主从服务器正常工作时,缓冲区只做入队出队的操作,而当从服务器断连再重新建立连接后,进行以下操作:

  1. 从服务器会通过PSYNC命令将自己的复制偏移量(offset)redis 订阅广播断开重连 redis断线重连_偏移量_04发送给主服务器。
  2. 主服务器接收到从服务器的复制偏移量redis 订阅广播断开重连 redis断线重连_偏移量_04,并跟主服务器自身的复制偏移量redis 订阅广播断开重连 redis断线重连_偏移量作比较,不相等时需要进行同步。
  3. 主服务器查询redis 订阅广播断开重连 redis断线重连_偏移量_04是否存在复制积压缓冲区中。例如,redis 订阅广播断开重连 redis断线重连_redis_14时,而redis 订阅广播断开重连 redis断线重连_redis_15时,主服务器向从服务器发送+CONTINUE回复,表示数据同步以部分重同步的形式进行。
  4. 然后主服务器将复制积压缓冲区偏移量为8916之后的所有数据操作都发送给从服务器,完成部分重同步。

部分重同步可以在从服务器断连后,以最小的代价完成同步操作。而非每次断连都进行完整同步,消耗大量服务器资源。

运行ID

服务器运行ID是每一台服务器每次运行的身份识别码,一台服务器多次运行可以生成多个运行id。运行id由40位字符组成,是一个随机的十六进制字符,例如:7cfbf53e4901277d7247db9fac7945af44dcc666。运行id被用于在服务器间进行传输,识别身份,如果向两次操作均对同一台服务器进行,必须每次操作携带对应的运行id,用于对方识别。运行id在每台服务器启动时自动生成的,master在首次连接slave时,会将自己的运行ID发送给slave,slave保存此ID,通过info Server命令,可以查看节点的runid,slave node应该根据不同的run id区分,run id不同就做全量复制。