目录
全量复制
关于replid和runid
部分复制
补充问题
实时复制
psync可以从主节点获取全量数据,也可以获取一部分数据。主要就是看offset的进度,如果offset写作-1,就是获取全量数据。offset写具体的正整数,则是从当前偏移量位置来进行获取。获取所有数据,是最稳妥的,但是会比较低效。如果从节点之前已经从主节点这里复制过一部分数据了,就只需要把新的之前没复制过的数据搞过来即可。
不是从节点索要那部分,主节点就一定给那部分。主节点会自行判定,看当前是否方便给部分数据,不方便就只能给全量了。
主节点根据 psync 参数和⾃⾝数据情况决定响应结果:
fullresync:全量数据的同步。
continue:增量数据的同步。
err:比较老版本的redis服务器,不支持psync。
一般来说首次和主节点进行数据同步或主节点不方便进行部分复制的时候,会进行全量复制。
从节点之前已经从主节点上复制过数据了,因为网络抖动或从节点重启了。从节点需要重新从主节点这边同步数据,此时会进行部分复制。
全量复制
全量复制流程:
1)从节点发送 psync 命令给主节点进⾏数据同步,由于是第⼀次进⾏复制,从节点没有主节点的运⾏ ID 和复制偏移量,所以发送 psync ? -1。
2)主节点根据命令,解析出要进⾏全量复制,回复 +FULLRESYNC 响应。
3)从节点接收主节点的运⾏信息进⾏保存。
4)主节点执⾏ bgsave 进⾏ RDB ⽂件的持久化。rdb文件是二进制的格式,比较节省空间。
5)主节点发送 RDB ⽂件给从节点,从节点保存 RDB 数据到本地硬盘。
6)主节点将从⽣成 RDB 到接收完成期间执⾏的写命令,写⼊缓冲区中,等从节点保存完 RDB ⽂件后,主节点再将缓冲区内的数据补发给从节点,补发的数据仍然按照 rdb 的⼆进制格式追加写⼊到收到的 rdb ⽂件中. 保持主从⼀致性。
7)从节点清空⾃⾝原有旧数据。
8)从节点加载 RDB ⽂件得到与主节点⼀致的数据。
9)如果从节点加载 RDB 完成之后,并且开启了 AOF 持久化功能,它会进⾏ bgrewrite 操作,得到最近的 AOF ⽂件。
主节点进行全量复制的时候,也支持“无硬盘模式”(diskless)。即主节点生成的rdb的二进制数据,不是直接保存到文件中,而是直接进行网络传输了(省下了一系列读硬盘和写硬盘的操作)。从节点之前也是先把收到的rdb数据,写入到硬盘中,然后再加载,现在也可以省略这个过程,直接把收到的数据进行加载了。
关于replid和runid
replid使用info replication查看,runid 使用info server命令查看。
runid是每个节点都不相同的。replid则是具有主从关系的节点,是相同的。
runid主要是用在支持实现redis哨兵这个功能。replid主要用在主从复制中。
部分复制
有些时候,从节点本身就已经有了主节点的绝大部分数据,这个时候,就不太需要进行全量复制了。比如出现网络抖动,主节点这边最近修改的数据可能就无法同步了,网络恢复后,此时就可以让从节点和主节点重新建立联系,当从节点和主节点重新建立连接之后,就需要进行数据的同步。
1)当主从节点之间出现⽹络中断时,如果超过 repl-timeout 时间,主节点会认为从节点故障并终端复制连接。
2)主从连接中断期间主节点依然响应命令,但这些复制命令都因⽹络中断⽆法及时发送给从节点,所以暂时将这些命令滞留在复制积压缓冲区中。
3)当主从节点⽹络恢复后,从节点再次连上主节点。
4)从节点将之前保存的 replicationId 和 复制偏移量作为 psync 的参数发送给主节点,请求进⾏部分复制。如果replicationId不一样,就需要全量复制。offset表示之前同步数据的进度,主节点就看这个进度是否在当前的积压缓冲区之内,如果确实是在积压缓冲区之内,此时就可以直接进行部分复制,就只把最近这段时间的数据复制过去即可。
5)主节点接到 psync 请求后,进⾏必要的验证。随后根据 offset 去复制积压缓冲区查找合适的数据,并响应 +CONTINUE 给从节点。
6)主节点将需要从节点同步的数据发送给从节点,最终完成⼀致性。
补充问题
实时复制
从节点已经和主节点同步好数据了,但是之后,主节点这边会源源不断的收到修改数据的请求。主节点上的数据就会随之改变。这些数据也需要同步给从节点。
也就是从节点和主节点之间会建立TCP的长连接。然后主节点把自己收到的修改数据的请求,通过上述连接,发给从节点,从节点再根据这些修改请求,修改内存中的数据。
在进行实时复制的时候,需要保证连接处于可用状态。就需要心跳包机制:
主节点:默认,每隔10s给从节点发送一个ping命令,从节点收到就返回pong。
从节点:默认每隔1s就给主节点发送一个特定的请求,就会上报当前从节点复制数据的进度(offset)
从节点何时晋升成主节点:
从节点和主节点断开连接,有两种情况:
1、从节点主动和主节点断开连接(slaveof no one)。 这个时候,从节点就能够晋升成主节点。
2、主机点挂了,这个时候,从节点不会晋升成主节点。需要通过人工干预的方式,恢复主节点。
关于redis主节点无法重启:
解决方案:把redis服务器生成的文件的工作目录区分开(修改配置文件中的dir选项)。
1、停止之前的redis服务器。 2、删除之前工作目录下已经生成的aof文件(或者也可以通过chown命令修改aof文件所属的用户)。 3、给从节点创建新的目录,用来作为从节点的工作目录。并且修改从节点的配置文件,设定成新的工作目录。4、启动redis服务器。
以上,关于主从复制,希望对你有所帮助。