文章目录:1.复制过程2.数据间同步3.全量复制4.部分复制5.心跳6.异步复制Replication原理1.复制过程复制过程的步骤如下:1.从节点执行slaveof命令。2、从节点只保存slaveof命令中主节点的信息,并不会立即发起复制。3、从节点内部的定时任务找到主节点的信息,开始使用。socket连接master节点4.连接成功后,发送ping命令,希望能得到pong命令的响应,否则会重连。6、权限校验通过后,进行数据同步。这是最长的操作。主节点会将所有数据发送给从节点。7.当主节点将当前数据同步到从节点时,复制建立过程完成。接下来主节点会继续向从节点发送写命令,保证主从数据的一致性。2、数据之间的同步在上面提到的复制过程中,其中一个步骤就是“数据集的同步”,也就是我们现在所说的“数据之间的同步”。redis同步有2个命令:sync和psync,前者是redis2.8之前的同步命令,后者是redis2.8新设计的优化sync的命令。我们将重点关注2.8psync命令。psync命令需要3个组件来支持:1.主从节点分别复制偏移量2.主节点复制积压缓冲区3.主节点运行ID主从节点分别复制偏移量:1.参与复制的主从节点将all维护自己的复制偏移量。2、master节点处理完写命令后,会累加记录命令的字节长度,统计信息在inforeplication中的masterreploffset指标中。3、从节点每秒向主节点报告自己的复制偏移量,所以主节点也会保存从节点的复制偏移量。4、从节点收到主节点发送的命令后,也会累加自己的offset,统计信息在inforeplication中。5、通过比较主从节点的复制偏移量,可以判断主从节点的数据是否一致。主节点复制积压缓冲区:1.复制积压缓冲区是一个固定长度的先进先出队列,存储在主节点上。默认大小为1MB。2.这个队列是在slave连接的时候创建的。这时,当主节点响应写入命令时,它不仅会向从节点发送命令,还会将其写入复制缓冲区。3.它的作用是恢复部分复制和复制命令中丢失的数据。通过信息复制可以看到相关信息。主节点运行ID:1.每个redis启动时,都会生成一个40位的运行ID。2、运行ID的主要作用是标识Redis节点。如果采用ip+port的方式,如果master节点重启修改了RDB/AOF数据,slave节点根据offset进行复制是不安全的。因此,当runningid发生变化时,从节点会进行全量复制。也就是说,redis重启后,默认的slave节点会进行全量复制。如果运行ID在重新启动时没有更改怎么办?1、可以通过debugreload命令重新加载RDB,保持runningID不变。从而有效避免了不必要的全量复制。2.它的缺点是debugreload命令会阻塞当前Redis节点的主线程,所以对于数据量较大的master节点或者不能容忍阻塞的节点需要慎用。一般这个问题可以通过failover机制来解决。psync命令使用方法:命令格式为psync{runId}{offset}runId:从节点复制的主节点的运行idoffset:当前从节点复制的数据偏移psync执行过程:过程说明:从节点发送psync命令对于主节点,runId是目标主节点的ID。如果不是,则默认为-1。offset是从节点保存的复制偏移量。如果是第一份,则为-1。主节点根据runid和offset返回结果:1.如果回复+FULLRESYNC{runId}{offset},从节点将触发全量复制过程。2.如果回复+CONTINUE,从节点会触发部分复制。3、如果回复+ERR,说明主节点不支持2.8的psync命令,将使用sync进行全量复制。至此,数据之间的同步就差不多了,长度还是比较长。主要针对psync命令之间的介绍。3、全量复制全量复制是Redis最早支持的复制方式,也是主从第一次建立复制必须经历的阶段。触发全量拷贝的命令有sync和psync。如前所述,这两个命令的分水岭版本是2.8。在redis2.8之前,sync只能用于进行全量程差异。2.8之后,全量同步和部分同步都支持了。流程如下:介绍一下上图中的步骤:1.发送psync命令(spync?-1)2.主节点根据命令返回FULLRESYNC3.从节点记录主节点ID和offset4。主节点bgsaves,将RDB保存到本地5.主节点将RBD文件发送给从节点6.从节点接收到RDB文件并加载到内存中。7、主节点在从节点接收数据的同时将新数据保存到“复制客户端缓冲区”。当从节点加载RDB,并发送过来。(如果从节点时间过长,会造成缓冲区溢出,最终导致全量同步失败。)8.从从节点清除数据后加载RDB文件。如果RDB文件很大,这一步还是比较耗时的。如果客户端此时访问,会导致数据不一致,可以使用配置slave-server-stale-data关闭。9、slave节点加载RBD成功后,如果启用了AOF,会立即执行bgrewriteaof。上面加粗的部分是整个全同步耗时的地方。注意:1、如果RDB文件大于6GB,并且是千兆网卡,Redis默认的超时机制(60秒)会导致全量复制失败。这个问题可以通过增加repl-timeout参数来解决。2、Redis虽然支持无盘复制,即可以通过网络直接发送到从节点,但是功能并不完善,在生产环境中慎用。4.部分复制从节点在复制主节点时,如果出现网络断开或其他异常情况,从节点会请求主节点重新发出丢失的命令数据,主节点只需要将数据发送到复制缓冲区到从节点。可以保证数据的一致性,成本远低于全量拷贝。步骤如下:1、当从节点出现网络中断,超过repl-timeout时间时,主节点会中断复制连接。2.主节点将请求的数据写入“ReplicationBacklogBuffer”,默认为1MB。3.当slave节点恢复并重新连接到master节点时,slave节点会将offset和master节点id发送给master节点4.master节点检查后,如果offset之后的数据在buffer中,则willsendcuntinueresponse——表示可以进行部分复制5.主节点将缓冲区中的数据发送给从节点,以确保主从复制处于正常状态。5、心跳主从节点建立复制后,保持长连接,互相发送心跳命令。心跳的关键机制如下:1.middle和slave都有心跳检测机制,各自模拟对方的client进行通信。使用clientlist命令查看复制相关的客户端信息。主节点的连接状态为flags=M,从节点的连接状态为flags=S。2.主节点默认每10秒向从节点发送一次ping命令,配置repl-ping-可以修改slave-period来控制发送频率。3、从节点每秒在主线程中发送replconfack{offset}命令,向主节点报告自己当前的复制偏移量。4、master节点收到replconf信息后,判断slave节点的超时时间。如果repl-timeout超过60秒,则判断该节点下线。注意:为了减少主从延迟,redis主从节点一般部署在同机房/同城机房,避免网络延迟导致网络分区导致心跳中断。6.异步复制主节点不仅负责读写数据,还负责同步写命令给从节点。写命令的发送过程是异步完成的,也就是说主节点处理完写命令后立即返回给客户端,不等待从节点。节点复制完成。异步复制的步骤很简单,如下:1.主节点接受处理命令2.主节点处理后返回响应结果3.对于修改命令,异步发送给从节点,从节点在主线程中执行复制的命令。小结本文主要分析Redis的复制原理,包括复制过程、数据间同步、全量复制过程、部分复制过程、心跳设计、异步复制过程。其中,可以看出RDB数据之间的同步是非常耗时的。因此Redis在2.8版本退出了类似于增量复制的psync命令。当Redis主从直接遇到网络中断时,不会进行全量复制,而是将数据放在buffer中(默认1MB)。各自维护复制偏移量,判断缓冲区中的数据是否溢出。如果没有溢出,只需要发送缓冲区数据,开销很小。否则,需要完整副本。因此,控制缓冲区大小非常重要。引用《Redis 开发与运维》好了,redis主从复制的原理就介绍到这里,篇幅有限,难免略去。
