zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

Redis 部分复制详解

Redis 详解 复制 部分
2023-09-14 09:01:47 时间

redis部分复制


部分复制主要是Redis针对全量复制的过高开销做出的一种优化措施,使用psync{runId}{offset}命令实现。 当从节点(slave) 正在复制主节点(master) 时, 如果出现网络闪断或者命令丢失等异常情况时, 从节点会向主节点要求补发丢失的命令数据, 如果主节点的复制积压缓冲区内存在这部分数据则直接发送给从节点, 这样就可以保持主从节点复制的一致性。 补发的这部分数据一般远远小于全量数据, 所以开销很小。 部分复制的流程如图:
 

流程说明:
1) 当主从节点之间网络出现中断时, 如果超过repl-timeout时间, 主节点会认为从节点故障并中断复制连接, 打印如下日志:

M # Disconnecting timedout slave: 127.0.0.1:6380
M # Connection with slave 127.0.0.1:6380 lost.

如果此时从节点没有宕机, 也会打印与主节点连接丢失日志:

S # Connection with master lost.
S * Caching the disconnected master state.

 3) 当主从节点网络恢复后, 从节点会再次连上主节点, 打印如下日志:

S * Connecting to MASTER 127.0.0.1:6379
S * MASTER <-> SLAVE sync started
S * Non blocking connect for SYNC fired the event.
S * Master replied to PING, replication can continue...

4) 当主从连接恢复后, 由于从节点之前保存了自身已复制的偏移量和主节点的运行ID。 因此会把它们当作psync参数发送给主节点, 要求进行部分复制操作。 该行为对应从节点日志如下:

S * Trying a partial resynchronization (request 2b2ec5f49f752f35c2b2da4d05775b5
b3aaa57ca:49768480).

5) 主节点接到psync命令后首先核对参数runId是否与自身一致, 如果致, 说明之前复制的是当前主节点; 之后根据参数offset在自身复制积压冲区查找, 如果偏移量之后的数据存在缓冲区中, 则对从节点发送+CONTINUE响应, 表示可以进行部分复制。 从节点接到回复后打印如下日志:

S * Successful partial resynchronization with master.
S * MASTER <-> SLAVE sync: Master accepted a Partial Resynchronization.

6) 主节点根据偏移量把复制积压缓冲区里的数据发送给从节点, 保证主从复制进入正常状态。 发送的数据量可以在主节点的日志获取, 如下所示:

M * Slave 127.0.0.1:6380 asks for synchronization
M * Partial resynchronization request from 127.0.0.1:6380 accepted. Sending 78
bytes of backlog starting from offset 49769216.



#自己测试
21609:S 05 Apr 2020 02:54:38.558 * Master replied to PING, replication can continue...
 
21609:S 05 Apr 2020 02:54:38.559 * Trying a partial resynchronization (request 999f89051b48418f2b1f498996d9a6f77a4feb5f:939).
 
21609:S 05 Apr 2020 02:54:38.559 * Successful partial resynchronization with master.
 
21609:S 05 Apr 2020 02:54:38.559 * MASTER <-> REPLICA sync: Master accepted a Partial Resynchronization.

从日志中可以发现这次部分复制只同步了78字节, 传递的数据远远小于全量数据。