本文总结:

1. 主从包括那些机制?包括三个阶段

  • 第一次复制通过全量复制,全量复制完成之后(psync + RDB文件+repl_buffer);
  • 命令传播阶段(通过长连接+repl_buffer保证 命令顺序性+ repl_backlog_buffer 实现数据补发);
  • 恢复断连阶段增量同步(psync +repl_backlog_buffer )。redis 2.8之前和全量同步类似,通过psync代替sync实现增量同步。

2. 命名传播阶段是否会出现:第一指令没有成功,第二个成功了?
通过repl_buffer保证master节点给slave节点命令的顺序性。

1 全量复制和增量复制

1.1 全量复制

slaveof命令执行全量同步流程如下:

  • slave节点向master节点发送“psync ? -1” 命令。
  • master收到psync命令之后返回 FULLRESYNC 告知 slave 将执行全量同步。
  • master执行bgsave命令,Redis会fork出一个子进程在后台生成RDB文件,同时将同步过程中的写命令记录到replication_buffer中。
  • master会把生成的RDB文件发送给slave。
  • slave接收到RDB文件会将其装载入内存。
  • master将记录在缓冲区replication_buffer的所有写命令发送给slave,slave对这些命令进行「重放」,将其数据库的状态更新至和master一致。

1

1.2 断连处理-增量复制

在Redis 2.8之前,如果因网络原因,主从节点复制中断,当再次建立连接时,还是会执行SYNC命令进行全量复制。效率较为低下。从Redis 2.8开始,引入了PSYNC命令代替SYNC命令来执行复制时的同步操作。PSYNC命令相比之前SYNC提供了增量复制。

注意: “PSYNC ? -1 ” 和SYNC作用相同,都是全量复制。

PSYNC通过repl_backlog_buffer实现增量复制,流程如下:

1

1、断连期间

主库将命令记录到repl_backlog_buffer,并更新master_repl_offset

2、断连恢复

STEP1 从库通过PSYNC <replication-id> <offset>,发送salve_repl_offset 到主库。

STEEP2 主库将salve_repl_offset和master_repl_offset之间的数据发送给从库,即断连之间的数据。

  • repl_backlog_buffer是环形缓存区,如果断连时间过长,命令会被覆盖,此时会进行全量同步。

2 基于长连接的命令传播

解释下repl_backlog_buffer和replation_buffer两个缓存的区别?

  • replation_buffer每个长连接独享一个,建立主从连接之后生成的。
    1.  全量复制过程中,解决RDB生成、传输和加载过程中增量写问题。
    2. 命令传播过程中,实现命令按顺序同步到从节点。
  • relation_backlog_buffer所有长连接共享一个,redis服务初始化时候生成的。
    1. 恢复断连过程中实现增量复制。
    2. 命令传播过程中实现数据补发

在命令传播阶段,一个写命令到master之后会更新两个buffer:

  • repl_backlog_buffer追加写命令
  • replation_buffer追加写命令

当主从库完成了全量复制,它们之间就会一直维护一个长连接,主库会通过这个长连接将后续陆续收到的写操作命令(replation_buffer中命令)发送给对应的从库,这个过程也称为基于长连接的命令传播,使用长连接的目的就是避免频繁建立连接导致的开销。

1

 

2.1 命令传播如何保证顺序性

假设,当前主节点的master_repl_offset为1000,如下两个命令顺序达到主库:

  • 命令1 -> 保存到缓存repl_backlog_buffer (200个字节)&&更新master_repl_offset 1200 -》 异步发送命令给从节点offset。
  • 命令2 -> 保存到缓存repl_backlog_buffer(300个字节)&&更新offset 1500 -》 异步发送命令给从节点。

A: 在将命令1和命令2同步到从库过程中是否出出现: 命令1丢失了,命令2正常到从节点?即此时从节点offset为1300,然后从节点执行 REPLCONF ACK 1300,主节点如何处理?

Q: 不会出现这个问题。因为主节点往从节点发送命令是通过replation_buffer进行的。replation_buffer是每个从节点长连接独享一个所以保证了master同步slave命令的有序性,如上面命令传播流程图。

2.2 心跳检测REPLCONF_ACK

在命令传播阶段,从节点间隔1秒向服务器发送一个“REPLCONF ACK{offset}” 命令。命令作用为:

  • slave上报资损复制偏移量,检查是否存命令丢失。主节点判断master_repl_offset和slave_repl_offset是否一致性,不一致性就行数据补发操作。
  • 判断master是否在线,如果超时则认为为master下线
    1. 将传播命令的长连接关闭;
    2. 等下次进行心跳检查,如果连接上,则触发增量同步PSYNC

数据补发和增量复制区别:

  • 增量复制是主从连接断连,在连接恢复之后,从节点发送PSYNC <replication-id> <offset>进行触发的。
  • 数据补发是在主从连接没有断连的情况下执行的。通过REPLCONF ACK{offset}触发。

1

3 拓扑结构- 主-从-从

为了降级master同步的压力,多采用“主-从-从”的复制模式。

1

 

分类&标签