浅谈:redis的主从复制 + 哨兵模式

时间:2022-06-01 19:03:46

浅谈:redis的主从复制 + 哨兵模式

主从模式

​ 在谈论redis的主从复制之前,我们先回想下mysql的主从搭建过程,第一步呢首先要在主库服务器中修改my.cnf,开启一下bin_log功能,设置下server-id=1,重启服务后开启一个主从的授权,然后就可以show master status查看主库的状态记录下主库的master_log_file和master_log_pos;第二步呢就是修改从库的server-id为2(有其余从库依次3,4····),开启relay_log,重启从库后,设置与master主库连接的命令,开启slave使从库生效。。这个mysql主从搭建的过程还是相对比较复杂的,而且要想实时灾备和主从切换,还得需要配置一些其他的,比如借用MHA架构。但是呢,redis的主从搭建就十分简单了。

redis主从搭建过程:

  • 主redis服务器什么也不需要修改,摆那启动就好。
  • 从机服务器在redis.conf文件里加上:replicaof 主机ip:port端口号,启动就好了。

redis主从实现的原理:

  • slave从机在配置完启动后,会根据配置的主机的ip:port去ping主机,看能不能ping通,建立一个socket通道。期间也会不断的进行心跳检测,保证二者实时感应到的。
  • socket通道建立后,slave经历过一系列的鉴权检验没问题后,它会在master那里获得一个RDB快照文件,由于它是二进制文件,所以体积小,传输过程也比较快。slave会解析这个RDB文件,将那个快照版本的数据复制到自己的服务器上,这是一个全量复制的过程。
  • 接下来如果master再接收到来自于客户端的其他命令,它会直接将命令传播给slave,而slave会一直的去接收并执行主服务器master传递过来的命令,这是一个增量复制的过程。

下面我画一张示意图来描述这个过程:

浅谈:redis的主从复制 + 哨兵模式

至于redis为什么要做主从搭建,这也源于主从搭建的两个优点:

  • 数据容灾。从机作为主机的一个数据备份,当主机宕机后,从机能够快速的切换成主机,达到一个高可用的目的。这也是redis主从搭建的常用使用场景。
  • 读写分离。主机负责写数据,从机负责读数据,提高redis的吞吐量,但是会发生数据一致性的问题,毕竟主从同步数据需要时间。

需要注意的是:

  • 当redis搭建主从后,从机就只能读数据,不能去写数据了,写的话会报错。
  • 单纯的搭建redis主从,不能实现主从的切换,也就是主机宕机后,从机还是从机,要想实现主从切换,必须引用redis的哨兵机制。

哨兵模式

​ 哨兵二字可以让我们联想到监察员一类的职务,它的角色在应该是来监控我们的redis主从服务,当发现我们的redis主从服务出现问题了,比如主机下线了一类的,它就要发挥它的作用,将其他的从机扶持成主机,达到系统正常运行的效果。

​ 一般而言,我们会用多个实例来组成sentinel集群(哨兵集群)来监视一组的一主多从或者是多组的一主多从。在这里提一句,哨兵模式也遵循一个选举机制和过半原则,只有当一半以上的sentinel认为某台机器出问题了,这个决议才会被通过进行之后的操作。

哨兵模式的部署示意图:

浅谈:redis的主从复制 + 哨兵模式

关于哨兵模式的搭建过程本文不再缀叙了,百度上很多都写过类似的博客,可以参考:https://www.cnblogs.com/qinxu/p/9633418.html

执行流程

启动并初始化Sentinel

Sentinel是一个特殊的redis服务器,不会去进行持久化,Sentinel实例启动后,每个Sentinel会创建2个连向主服务器的网络连接。

  • 命令连接:用于向主服务器发送命令,并接收响应
  • 订阅连接:用于订阅主服务器的一个sentinel:hello频道

获取主服务器信息

Sentinel默认每10秒一次,向被监控的主服务器发送info命令,获取主服务器和其下属从服务器的信息。

获取从服务器信息

当sentinel发现主服务器有新的从服务器出现时,sentinel还会向从服务器简历命令连接,当命令连接建立之后,sentinel还是会默认10s一次,向从服务器发送info命令,并记录从服务器的信息。

向主服务器和从服务器发送消息(以订阅的方式)

默认情况下,sentinel每2秒一次,向所有被监视的主服务器和从服务器所订阅的sentinel:hello频道上发送消息,消息会携带sentinel自身的信息和主服务器的信息。

接收来自主服务器和从服务器的频道信息

当sentinel与主服务器或者从服务器建立起订阅连接之后,sentinel就会通过订阅连接,向服务器发送以下命令:

subscribe —sentinel—:hello

sentinel彼此之间只创建命令连接,而不创建订阅连接。因为sentinel通过订阅主服务器或者从服务器,就能够感知到新的sentinel的加入,而一旦新的sentinel加入后,相互感知的sentinel通过命令连接来通信就好了。

检测主观下线状态

Sentinel每秒一次向所有与它建立了命令连接的实例(主服务器、从服务器和其他Sentinel)发送PING命



实例在down-after-milliseconds毫秒内返回无效回复(除了+PONG、-LOADING、-MASTERDOWN外)

实例在down-after-milliseconds毫秒内无回复(超时)

Sentinel就会认为该实例主观下线(SDown)

检查客观下线状态

当一个Sentinel将一个主服务器判断为主观下线后,Sentinel会向同时监控这个主服务器的所有其他Sentinel发送查询命令

SENTINEL is-master-down-by-addr <ip> <port> <current_epoch> <runid>

其他Sentinel回复

<down_state>< leader_runid >< leader_epoch >

判断它们是否也认为主服务器下线。如果达到Sentinel配置中的quorum数量的Sentinel实例都判断主服务器为主观下线,则该主服务器就会被判定为客观下线(ODown)。

选举Leader Sentinel

当一个主服务器被判定为客观下线后,监视这个主服务器的所有Sentinel会通过选举算法(raft),选出一个Leader Sentinel去执行failover(故障转移)操作。

故障转移的步骤:

  • 它会将失效 Master 的其中一个 Slave 升级为新的 Master , 并让失效 Master 的其他 Slave 改为复制新的 Master ;
  • 当客户端试图连接失效的 Master 时,集群也会向客户端返回新 Master 的地址,使得集群可以使用现在的 Master 替换失效 Master 。
  • Master 和 Slave 服务器切换后, Master 的 redis.conf 、 Slave 的 redis.conf 和

    sentinel.conf 的配置文件的内容都会发生相应的改变,即, Master 主服务器的redis.conf配置文件中会多一行 replicaof 的配置, sentinel.conf 的监控目标会随之调换。

主服务器master的选择规则

  • 过滤掉主观下线的节点
  • 选择slave-priority最高的节点,如果由则返回没有就继续选择
  • 选择出复制偏移量最大的系节点,因为复制偏移量越大则数据复制的越完整,如果由就返回了,没有就继续
  • 选择run_id最小的节点,因为run_id越小说明重启次数越少