【Redis基础】主从复制

时间:2022-06-05 05:18:43

1.定义

  • 通过执行slaveof命令或设置slaveof选项,让一个服务器去复制另一个服务器。

  • 允许多个slave server拥有和mater server相同的数据库副本

2.旧版复制功能

旧版(Redis2.8之前)复制功能包括两个操作:同步和命令传播

(1)同步:将从服务器的数据库状态更新至主服务器的当前状态

实例:

【Redis基础】主从复制

(2)命令传播:当主服务器的状态被修改,让主从服务器的数据库重新回到一致状态。

若主从服务器刚刚完成同步操作,这是客户端向主服务器发送写命令,导致主从服务器的状态不一致,这时服务器会把客户端发来的写命令发送给从服务器,它们就再次回到同一状态了。

(3)旧版复制功能的缺陷

复制分为两种情况:初次复制和断线后重复制

  • 初次复制:从服务器第一次复制主服务器。旧版复制功能可以很好完成任务。

  • 断线后重复制:处于命令传播阶段的主服务器因为网络原因中断了复制,当主从服务器重新连接后,继续复制主服务器。旧版复制功能效率极低。

主从服务器断线后重新复制的实例

【Redis基础】主从复制

分析:断线后没有必要传送RDB文件,因为只是改变了几个键而已。而且sync命令非常消耗资源。

3.新版复制功能

(1)为了解决旧版复制功能的低效问题,Redis从2.8版本开始,使用PSYNC命令代替SYNC命令。

(2)PSYNC命令具有完整重同步和部分重同步

  • 完整重同步:用于初次复制,和SYNC一样,让主服务器创建并发送RDB文件,向从服务器发送保存在缓冲区中的写命令。

  • 部分重同步:用于断线后重复制,重连后,主服务器将断开期间执行的写命令发送给从服务器。

例:使用PSYNC命令来进行断线后的重复制

【Redis基础】主从复制

4.部分重同步

部分重同步功能由主从服务器的复制偏移量、主服务器的积压缓冲区和服务器的运行ID组成

(1)复制偏移量

  • 执行复制的主从服务器都会分别维护一个复制偏移量

    • 主服务器每次向从服务器传播N个字节的数据,就把自己的复制偏移量加N
    • 从服务器每次收到主服务器传播的N字节数据时,将自己的复制偏移量加N
  • 通过对比主从服务器的复制偏移量,就可以知道主从服务器是否处于一致状态。

(2)复制积压缓冲区

  • 复制积压缓冲区是由主服务器维护的一个固定长度的先进先出队列,默认大小为1MB

  • 当从服务器断开重连时,从服务器通过PSYNC命令将自己的复制偏移量offset发送给主服务器,若offset之后的数据在积压缓冲区中,就进行部分重同步的操作,否则进行完整重同步。

(3)服务器运行ID

每个Redis服务器都有自己的运行ID,这个ID在启动时自动生成,由40个随机的十六进制字符生成。

断开重连时,从服务器将自己的运行ID发送给主服务器,若主从服务器的运行ID相同,则进行部分重同步操作,否则进行完整重同步操作。

5.复制的实现

  • PSYNC命令的实现

    • 从服务器第一次复制时,向主服务器发送PSYNC ? -1命令,请求主服务器进行完全重同步
    • 若从服务器之前已经复制过某个主服务器,那从服务器就发送PSYNC < runid> < offset>命令进行部分重同步或完全重同步。
  • 例:让从服务器复制主服务器,执行命令slaveof 127.0.0.1 6379,复制的实现步骤

(1)设置主服务器的地址和端口

将主服务器的IP和端口保存到服务器状态的masterhost和masterport属性中。

(2)建立套接字连接

从服务器根据IP和端口创建连向主服务器的套接字连接。

【Redis基础】主从复制

(3)发送ping命令

  • 从服务器向主服务器发送ping命令,作用如下

    • 检查套接字的读写状态是否正常
    • 检查主服务器能否正常处理命令请求
  • 从服务器发送ping之后可能出现的情况图例:

【Redis基础】主从复制

(4)身份验证

  • 如果从服务器设置了masterauth选项,那么进行身份验证,否则不需要。

  • 从服务器在身份验证可能遇到的情况图例

【Redis基础】主从复制

(5)发送端口信息

从服务器执行命令repliconf listenging-port < port-number>,向主服务器发送从服务器的监听端口号。

(6)同步

  • 从服务器向主服务器发送PSYNC命令,执行同步操作,并将自己的数据库更新到主服务器当前的状态

  • 因为主服务器要向从服务器发送保存在缓冲区(完全重复制)或复制积压缓冲区(部分重同步)的写命令,所以主从服务器都是对方的客户端,图解如下:

【Redis基础】主从复制

(7)命令传播

完成同步之后,主服务器进入到命令传播阶段,主服务器一直将自己执行的写命令发送给从服务器。

6.心跳检测

在命令传播阶段,从服务器会默认以每秒一次的频率向主服务器发送replconf ack < replication_offset>命令,有如下作用:

  • 检测主从服务器的网络连接状态
  • 辅助实现min-slaves选项
  • 检测命令丢失,通过对比主从服务器的复制偏移量知道命令是否丢失。

注:Redis的min-slaves-to-write和min-slaves-max-log选项可以防止主服务器在不安全的情况下执行写命令。

7.主从复制的特点

  • master 可以拥有多个slave

  • 多个slave可以连接到同一个master,还可以连接到其它slave

  • 主从复制不会阻塞master,在同步数据时,master还可以继续处理client请求

  • 提高系统的伸缩性。

8.哨兵模式

(1)定义

sentinel(哨兵)是Redis高可用性的解决方案,由一个或多个sentinel实例组成的哨兵系统可以监视任意多个主服务器。

图例:

【Redis基础】主从复制

(2)启动并初始化Sentinel

  • 启动sentinel,执行命令:redis-sentinel /path/to/your/sentinel.conf
    sentinel.conf的内容:sentinel monitor mymaster 127.0.0.1 6379 1 (1表示主机挂掉后slave投票让谁成为主机,得票数多少成为主机/1表示至少需要一个哨兵节点同意才会执行故障恢复操作)1的值通常设置为N/2 + 1 其中 N为哨兵节点数量。

  • Sentinel启动的步骤

    • 初始化服务器
    • 将普通的Redis服务器使用的代码替换为Sentinel专用代码
    • 初始化Sentinel状态
    • 根据给定的配置文件,初始化Sentinel的监视主服务器列表
    • 创建连向主服务器的网络连接(命令连接、订阅连接)

注:命令连接指专门用于向主服务器发送命令,并接受命令回复,而订阅连接指专门用于订阅主服务器的sentinrl:hello频道

【Redis基础】主从复制

(3)获取服务器信息

  • 和主数据库建立连接后,哨兵会定时执行以下3个操作
    • 每10秒哨兵会向主数据库和从数据库发送info命令
    • 每2秒哨兵会向主数据库和从数据库的sentinel:hello 频道发送自己的信息
    • 每1秒哨兵会向主数据库和从数据库和其他哨兵节点发送ping命令

(4)选举领头Sentinel

  • 如果主数据库断开连接,则会选举领头的哨兵节点对主从系统发起故障恢复。选举过程使用raft 算法。

  • 选举规则:删除下线或中断的服务器,尽量选举从服务器优先级高的、复制偏移量大的、运行ID小的。

例:server成功被选举为主服务器

【Redis基础】主从复制



本人才疏学浅,若有错,请指出,谢谢!
如果你有更好的建议,可以留言我们一起讨论,共同进步!
衷心的感谢您能耐心的读完本篇博文!

参考书籍:《Redis设计与实现(第二版)》—黄健宏