Redis的主从同步
Redis主从同步
什么是Redis的主从模式
主从模式中,一个高可用的Redis服务由一个主节点和若干个从节点组成。
Redis中采用读写分离来保证主节点和从节点之间的数据一致性,
- 主节点支持数据写入和数据读取,从节点只支持数据读取
- 主节点会与从节点之间执行主从数据同步,以保证主节点数据和从节点数据的一致性
主从数据同步
主从数据同步主要分为以下几种情况:
- 从节点与主节点刚建立连接时进行全量同步
- 主节点与从节点正常运行时的数据同步
- 主节点与从节点连接断开后又重连时会进行增量同步或者全量同步
全量同步
触发条件
- 从节点第一次连接主节点
- 从节点保存的复制id和主节点不匹配
- 从节点的复制偏移量不在主节点的复制积压缓冲区中
执行步骤
从节点向主节点发送PSYNC命令
从节点通过配置文件中的replicaof {masterip} {port} 获得主节点ip和port,然后向主节点发送psync {repID} {offset} 指令,
其中repID表示主节点唯一标识,offset为复制偏移量,因为当前从节点与主节点尚未连接,且尚未开始复制,所以repID为 ?,offset为 -1;
发送的数据为:psync ? -1主节点判断从节点需要全量同步,并向从节点响应fullresync {repID} {offset} 指令,从节点会将主节点的repID和offset保存下来
主节点会执行bgsave异步的生成RDB文件,然后主节点将RDB文件发送给从节点;从节点接收到RDB文件后,会清空内存数据,然后加载RDB文件的数据到内存中。
由于主节点生成RDB文件时是一部生成的,此时主节点是非阻塞的,可以继续处理业务。
所以在生成RDB文件、发送RDB文件和从节点加载RDB文件期间,主节点执行的写指令均会存放到缓冲区(replication_buffer)中,所以当从节点加载完RDB文件后,
主节点会将replication_buffer中的内容发送给从节点,从节点会执行replication_buffer中的指令,从而达到和主节点一致的状态。
注意:
在全量同步期间,主节点是非阻塞的,同时从节点很大程度上也是非阻塞的,从节点的非阻塞表现可以通过配置让从节点在全量同步期间使用就内存数据来处理查询指令
但是从节点在删除旧内存数据和加载RDB文件到内存中的这段时间里,从节点是阻塞的。
replication_buffer的配置:
# 主节点配置 |
如果replication_buffer的大小超过了限制,主节点会断开从节点的同步连接,此时replication_buffer的数据会被清空,然后会重新开始全量同步,所以
replication_buffer的大小需要设置一个合理值。
正常同步
触发条件
- 主从节点连接稳定,数据状态基本一致
- 主节点收到写命令(SET、DEL等)
执行过程
- 主节点执行写命令:现在本机执行
- 异步传播到从节点:通过复制流将命令发送给所有从节点
- 从节点执行相同命令:保持数据最终一致
配置
# 主节点配置 |
增量同步
触发条件
- 从节点和主节点断开连接后重连
执行过程
- 正常运行期间的写命令,主节点会向从节点发送写指令流来同步数据。
此时主节点自己维护了一份maser_repl_offset,从节点也会自己维护一份slave_repl_offset,他们都是不断自增保证数据更新的。 - 主从断连后,断连期间写在主节点的指令会放在repl_backlog_buffer(复制积压缓冲区)中,等待从节点重新连接。
- 从节点重连,向主节点发送 psync{repID}{slave_repl_offset}命令。
- 主节点判断repID是自己的,就会发送continue命令,表示增量同步
- 主节点还要计算从节点的偏移量和自己现在的偏移量差距多大,然后把这段时间的写指令写入replication_buffer中,再传给从节点。
- 从节点接收指令并自增偏移量直到与主节点同步。
