Redis主从原理

498 阅读5分钟

Redis的主从复制过程大体上分3个阶段:建立连接数据同步命令传

一、建立连接

1)在slaveof命令执行之后,从服务器根据设置的master的ip地址和端口,创建连向主服务器的socket套接字连接,连接成功后,从服务器会为这个套接字关联一个专门的处理器,用于处理后续的复制工作

2)建立连接之后,从服务器会向主服务器发送ping命令,确认主服务器是否可用,以及当前是否可用接受处理命令。如果收到主服务器的pong回复说明是可用的,否则有可能是网络超时或主服务器阻塞,从服务器会断开连接发起重连

3)身份验证。如果主服务器设置了requirepass选项,那么从服务器必须配置masterauth选项,且保证密码一致才能通过验证

4)身份验证完成之后,从服务器会发送自己的监听端口,主服务器会保存下来

5)Redis 使用异步复制。 从 Redis 2.8 开始, 从服务器会以每秒一次的频率向主服务器报告复制流

  • 数据同步

  • Redis的主从同步分为:完整重同步(full resynchronization)*
  • 和*
  • 部分重同步(partial resynchronization) 为了应对这种情况,Redis在2.8版本提供了PSYNC命令来带代替SYNC命令,为Redis主从复制提供了部分复制的能力。PSYNC命令格式是:
  • PSYNC <runid> <offset> runid:主服务器ID offset:从服务器最后接收命令的偏移量
  • runid
  •   每个Redis服务器都会有一个表明自己身份的ID。在PSYNC中发送的这个ID是指之前连接的Master的ID,如果没保存这个ID,PSYNC的命令会使用”PSYNC ? -1” 这种形式发送给Master,表示需要全量复制
  • offset(复制偏移量)
  •   在主从复制的Master和Slave双方都会各自维持一个offset。Master成功发送N个字节的命令后会将Master的offset加上N,Slave在接收到N个字节命令后同样会将Slave的offset增加N。Master和Slave如果状态是一致的那么它的的offset也应该是一致的。

二、完整重同步

  1. 从服务器连接主服务器,发送SYNC命令
  2. 主服务器接收到SYNC命名后,开始执行bgsave命令生成RDB文件并使用缓冲区记录此后执行的所有写命令
  3. 主服务器basave执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令
  4. 从服务器收到快照文件后丢弃所有旧数据,载入收到的快照
  5. 主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令
  6. 从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令

三、部分重同步

  1. 部分重同步是用于处理断线后重复制的情况,先介绍几个用于部分重同步的部分
  1. runid(replication ID),主服务器运行id,Redis实例在启动时,随机生成一个长度40的唯一字符串来标识当前节点

  2. offset,复制偏移量。主服务器和从服务器各自维护一个复制偏移量,记录传输的字节数。当主节点向从节点发送N个字节数据时,主节点的offset增加N,从节点收到主节点传来的N个字节数据时,从节点的offset增加N

  3. replication backlog buffer,复制积压缓冲区。是一个固定长度的FIFO队列,大小由配置参数repl-backlog-size指定,默认大小1MB。需要注意的是该缓冲区由master维护并且有且只有一个,所有slave共享此缓冲区,其作用在于备份最近主库发送给从库的数据(原因可能是从服务器重启丢失的数据)

四、命令传播

当完成数据同步之后,主从服务器的数据暂时达到一致状态,当主服务器执行了客户端的写命令之后,主从的数据便不再一致。为了能够使主从服务器的数据保持一致性,主服务器会对从服务器执行命令传播操作,即每执行一个写命令就会向从服务器发送同样的写命令

每隔一段时间(默认10秒,通过repl-ping-slave-period参数指定)主节点向从节点发送PING命令判断从节点是否在线

在命令传播阶段,从服务器会默认以每秒一次的频率向主服务器发送心跳检测

进行命令传播时,主服务器不仅会将写命令发送给所有从服务器,同时将写命令放入积压缓冲区(队列)中。

在积压缓冲区中,会为队列的每个字节记录相应的复制偏移量。时间较早的写命令会被挤出缓冲区

在从服务器断线重新连接上后,从服务器通过PSYNC命令将自己的偏移量发给主服务器,主服务器根据这两个量来判断执行何种同步操作:

- 如果偏移量后的数据存在复制积压缓冲区中,那么主服务器对从服务器执行部分操作; - 如果偏移量后的数据不存在复制积压缓冲区中,那么主服务器对从服务器执行完整同步操作;

REPLCONF ACK <replication_offset>

其中replication_offset是当前从服务器的复制偏移量,该命令的作用有三个

  • 检测主从服务器的网络连接状态

  • 辅助实现min-slaves选项

  • 检测命令丢失