2024-05-02  阅读(2)
版权声明:本文为博主付费文章,严禁任何形式的转载和摘抄,维权必究。 本文链接:https://www.skjava.com/mianshi/baodian/detail/1366392401

回答

单机版的 Redis 存在单点故障问题,Redis 的主从架构是 Redis 高可用和数据备份机制的核心。Redis 主从复制允许一个或多个从节点复制主节点的数据状态,其过程分为三个阶段:

1、建立连接阶段

这个阶段的主要作用是主从节点建立连接,为数据同步做准备。

  • 保存主节点信息:当从节点执行 slaveof masterIp masterPort 命令后,就会将主节点的 IP、port 信息保存下来。
  • 主从建立连接:从节点发现新的主节点后会尝试与主节点建立 Socket 连接。
  • 发送 ping 命令:当主从建立连接后,从节点会向主节点发送 ping 命令,主要有两个目的:
    • 检查 Socket 连接是否可用
    • 检查主节点是否可以处理请求
  • 身份认证:如果主节点要求密码验证,从节点必须正确的密码才能通过验证。

2、数据同步阶段

当从节点发送 ping 命令收到 pong 回复后,主从节点就建立了连接,这时他们便可以进行数据同步了,具体的执行方式是:从节点向主节点发送 psync 命令,主节点根据当前状态的不同进行不同的复制流程。流程分为:全量复制和部分复制,下篇文章会专门介绍这两种复制方式,这里不再详述。

这里需要注意的两点:

  1. 主从首次建立连接时是进行全量复制,当主从断开连接,从节点重新连接时,则需要根据偏移量来判断是进行全量复制还是部分复制。
  2. 在数据同步前,从节点是主节点的客户端,主节点不是从节点的客户端,但是到了这个阶段以后,主从节点互为客户端,这是因为在这个阶段后,主节点会主动向从节点发送命令。

3、命令传播阶段

数据同步完成后,主节点会持续将新的写命令实时发送给从节点。这样就保证了主节点和从节点之间数据的实时一致性。

如果因网络等原因导致主从连接暂时中断,当重新建立连接时,通过 Redis 2.8 及以上版本引入的部分重新同步(PSYNC)机制,从节点可以只请求丢失的数据,而不需要重新进行全量同步。

扩展

Redis 的主节点会根据当前状态的不同执行不同复制操作,包括全量复制和部分复制:

  • 全量复制:用于首次复制或者其他不能进行部分复制的情况。全量复制是一个非常重的操作,一般我们都要规避它。
  • 部分复制:用于从节点短暂中断的情况(网络中断、短暂的服务宕机)。部分复制是一个非常轻量级的操作,因为它只需要将中断期间的命令同步给从节点即可,相比于全量复制,它显得更加高效。

在 Redis 2.8 以前,从节点向主节点发送 sync 命令请求同步数据,此种方式是全量复制。在 Redis 2.8 以后,Redis 支持部分复制,发送的命令是 psync

全量复制

全量复制是指主节点将自身的整个数据集都发送给从节点的过程。因此它传输的数据量比较大,有一定的性能开销,所以我们需要尽可能地规避它。

  • 如果从节点是第一次请求主节点数据,从节点是不会知道主节点的运行id(runid)的 ,所以从节点发送 psync ? -1
  • 主节点接收从节点的命令后,判定是进行全量复制,所以回复 +FULLRESYNC ,同时也会将自身的 runid 和 偏移量 (offset) 发送给从节点,响应为 +FULLRESYNC {runid} {offset}
  • 从节点接受主节点的响应后,保存主节点的 runidoffset
  • 主节点响应从节点请求后,执行 bgsave,将生成的 RDB 文件保存在本地。
  • RDB 文件生成后,主节点会将它传输到从节点。从节点在接收到文件后,会加载这个 RDB 到自己的数据库中,这个过程从节点会替换掉从节点上现有的所有数据。
  • 从节点加载 RDB 完成后,如果当前节点开启了 AOF,会立刻做 bgrewriteaof 操作,为了保证全量同步后 AOF 文件立即可用。
  • 还有一点,从节点开始接收 RDB 文件到接收完成这段时间,主节点依然可以执行写请求,这个时候主节点是将这些请求写入到客户端缓冲区(repl_back_buffer)。当从节点加载 RDB 完成后,主节点会把缓冲区中的数据再发给从节点。

如下: