文章目录
  1. 1. 多机数据库的实现——复制
    1. 1.1. 2.8版本之前的复制
      1. 1.1.1. 同步
    2. 1.2. 旧版本复制功能缺陷
    3. 1.3. 新版复制功能
      1. 1.3.1. 部分重同步实现
      2. 1.3.2. Psync命令实现
    4. 1.4. 复制的实现

多机数据库的实现——复制

通过执行slaveof命令或者设置slaveof选项达到replicate复制服务器的作用

redis的复制可以分为同步(sync)和命令传播(command propagate)两个操作

2.8版本之前的复制

  • 同步sync:从服务器发起sync,将从服务器状态更新至主服务器状态。
  • 命令传播:主服务器数据库状态被修改时,让主从状态达到一致。

同步

内部实现步骤

  • 从服务器向主服务器发送sync
  • 主服务器收到sync,进行bgsave操作(逻辑和主动bgsave一样,后台生成RDB文件,并在缓冲区中纪录从开始执行bgsave后接受的写命令)。
  • 主服务器发送rdb文件给从服务器,从服务器执行
  • 主服务器将缓冲区命令发送给从服务器。此时从服务器更新至主服务器一样的状态。流程如下:

sync1

旧版本复制功能缺陷

主要问题断线后无条件执行sync全部重同步,正常在短时间内断线重连后的主服务器只要发送部分命令即可。。。

sync是一个非常耗资源的命令:参考bgsave,并且还需要占用带宽和i/o

新版复制功能

psync代替sync,sync被细分为完整重同步和部分重同步两种模式,部分重同步是处理断线后重复制情况的,会将断线后写命令直接发送给从服务器。

部分重同步实现

  • 组成部分
    • 主服务器写命令偏移量和从服务器写命令偏移量
    • 主服务器的复制积压缓冲区(写命令积压)
    • 服务器运行ID
  • 复制偏移量:主从复制偏移量做减法,看看偏移量差是多少,判断是rdb还是写命令传播(主要是下面介绍的复制积压缓冲区的偏移量)
    psync
  • 复制积压缓冲区:由主服务器维护的一个固定长度先进先出队列,默认1MB大小
    • 服务器在命令传播时,除了将写命令发送给从服务器(命令传播复制),还会将写命令入队到复制积压缓冲区。
    • 上面说的偏移量会记录在复制积压缓冲区中:复制积压缓冲区会为队列中每个字节纪录偏移量,断线服务器的偏移量会跟这里的最小偏移量比较比较。如果小于最小偏移量则进行完整重同步发送rdb文件,如果大于最小偏移量则写命令传播
    • 积压缓冲区大小是可以调整的,但是需要根据实际情况,一般计算公式:2*断线后重连主机的平均时间 * 每秒产生的写命令大小,通过修改redis.conf的repl-backlog-size属性来设置。
  • 服务器运行ID
    • 主要判断从服务器在断线重连后连接的主服务器是否是断线之前的服务器。从服务器会保存连接的主服务器id。如果发现重连后主服务器id和保存的id不同则直接需要RDb完整同步

Psync命令实现

命令格式:psync 从服务器纪录的主服务器id 从服务器偏移量

一张图说明命令执行和相应过程:
psync命令实现过程

复制的实现

  • 复制主服务器的地址和端口
  • 建立套接字链接
    • 从服务器套接字发送成功,从服务器会将套接字关联一个专门处理复制功能的文件事件处理器
    • 主服务器接受从服务器的套接字之后,从服务器同时具备服务器和客户端的角色
  • 发送PING命令——主要是测试通信,但通过ping携带的信息可以做其他作用,比如下图:
    psync ping过程
  • 身份验证
    psync 身份验证
  • 发送端口信息
    • 主服务器接受到这个命令后,会将从服务器的端口保存到主服务器的redisClient中。然而到目前为止,这个属性在主服务器上并没有什么鸟用。。。
  • 同步
    • 同步时因为主服务器要向从服务器发送命令(完整重同步、部分重同步),所以主服务器会成为从服务器的客户端。主服务器变从服务器的客户端是主服务器对从服务器执行命令传播的基础
  • 命令传播
    • 主服务器将自己接受到的命令发送给从服务器以保持一致状态。
  • 心跳检测
    • 命令:replconf ack 从服务器复制偏移量
    • 从服务器以每秒一次的频率向主服务器发送心跳
    • 心跳检测作用:用于 检测命令丢失 后的命令补发。
      命令补发 和 部分重同步的逻辑是一样的都是通过比较偏移量然后从复制积压缓冲区找到命令后重新发送给丛服务器,但是执行的前提不一样:
      两者执行前提区别在是否是断线重连,命令补发主从并没有断线。
    • 如果主服务器超过一秒钟没有收到从服务器发送的replconf ack 命令说明链接出问题
      (这里是:主服务器超过一秒没有接受到丛服务器的replconf ack命令说明主从链接异常。
      而不是:命令发送的从服务器没有接受到主服务器应答,来做判断。
      这里的通信可能是单向的,http的心跳因为http的通信逻辑,发送者是会收到应答。这里可以在接受者和发送者两者中同时做链接检测。)
    • 主服务器可以通过 info replication命令信息的lag一栏来查看心跳响应延迟时间。
    • 加了master-slave后,主服务器必须保证从服务器的最小链接数min-slaves-to-write 和 最小链接数的从服务器最小延迟时间都不超过最大延迟lag时间min-slaves-max-lag。
      如果超过则主服务器将不执行 写命令。
    • 检测命令丢失
      因网络故障而导致的命令丢失,会根据replconf ack 命令携带的偏移量来作出丢失判断,逻辑基本和部分重同步类似。

that is all。

文章目录
  1. 1. 多机数据库的实现——复制
    1. 1.1. 2.8版本之前的复制
      1. 1.1.1. 同步
    2. 1.2. 旧版本复制功能缺陷
    3. 1.3. 新版复制功能
      1. 1.3.1. 部分重同步实现
      2. 1.3.2. Psync命令实现
    4. 1.4. 复制的实现