master宕机

如果主从模式下的master宕机,一般处理流程:

  1. 将宕机的master下线
  2. 找一个slave作为master
  3. 通知所有的slave连接新的master
  4. 启动新的master与slave
  5. 全量复制*N + 部分复制*N

出现的问题:

  • 谁来确认master宕机了
  • 选新的master如何选?
  • 修改配置后,原来的master恢复了怎么办?

哨兵

哨兵(sentinel)是一个分布式系统,用于对主从结构中的每台服务器进行监控,当出现故障时通过投票机制选择新的master并将所有slave连接到新的master。

作用:

  • 监控

    不断的检查master和slave是否正常运行。

master存活检测、master与slave运行情况检测

  • 通知(提醒)

    当被监控的服务器出现问题时,向其他(哨兵间,客户端)发送通知

  • 自动故障转移

    断开master与slave连接,选取一个slave作为master,将其他slave连接到新的master,并告知客户端新的服务器地址。

哨兵也是一台redis服务器,只是不提供数据服务。

通常哨兵配置数量为单数。

哨兵搭建示例

配置哨兵(参考 sentinel.conf 配置文件)

编写配置文件sentinel-端口号.conf:

  1. port 26379
  2. daemonize no
  3. pidfile /var/run/redis-sentinel.pid
  4. logfile ""
  5. dir /tmp
  6. # sentinel monitor [自定义的名称] 监控的master的ip和端口 判断master宕机的哨兵数量
  7. # 如果有2台哨兵认为master宕机了,master就下线
  8. sentinel monitor mymaster 127.0.0.1 6379 2
  9. # master判定宕机的未响应时长(单位毫秒)
  10. sentinel down-after-milliseconds mymaster 30000
  11. # 新的master上来之后,进行数据同步时,一次多少个数据开始同步
  12. sentinel parallel-syncs mymaster 1
  13. # 多久未同步完成算作超时(单位毫秒)
  14. sentinel failover-timeout mymaster 180000
  15. sentinel deny-scripts-reconfig yes

启动哨兵:

  1. redis-sentinel sentinel-端口号.conf

使用客户端连接时,依然是redis-cli启动客户端,但是不允许使用setget等指令。

哨兵启动之后,刚刚编写的配置文件会被自动重写一部分,例如变为:

  1. port 26379
  2. daemonize yes
  3. pidfile "/var/run/redis-sentinel.pid"
  4. logfile "26379.log"
  5. dir "/home/redis/data"
  6. sentinel myid d957acd3913031c3bec970b13f9a2cc446230d25
  7. sentinel deny-scripts-reconfig yes
  8. sentinel monitor mymaster 127.0.0.1 6379 2
  9. sentinel config-epoch mymaster 0
  10. sentinel leader-epoch mymaster 0
  11. # Generated by CONFIG REWRITE
  12. protected-mode no
  13. maxclients 4064
  14. user default on nopass ~* +@all
  15. sentinel known-replica mymaster 127.0.0.1 6381
  16. sentinel known-replica mymaster 127.0.0.1 6380
  17. sentinel known-sentinel mymaster 127.0.0.1 26380 5b8d465eba4e61f72f245cc12d32d4c45b812ae5
  18. sentinel known-sentinel mymaster 127.0.0.1 26381 8812ba72638e42fbbc1a9af8a8a2e1716e223011
  19. sentinel current-epoch 0

工作原理

三个阶段:

  • 监控

    同步信息

  • 通知

    保持连通

  • 故障转移

    发现问题

选择竞选负责人

优选新的master

新master上任,其他slave切换master,原master改为slave

监控阶段

同步各个节点的状态信息

  • 通过ping指令获取各个sentinel的状态(是否在线)
  • 通过info指令获取master的状态

    • master的属性:runid、role:master
    • 各个slave的详细信息
  • 通过info获取所有slave的状态(根据master中的slave信息)

    • slave的属性:runid、role:slave、master_host、master_port、offset…..
sentinel[1]->master: 发送指令:info \n 获取master状态 sentinel[1]->master: 建立cmd连接 note right of master: master记录的信息:\n master信息\nslaves信息\n当前master连接的sentinels note left of sentinel[1]: sentinel[1]记录的信息:\nmaster信息\nslaves信息\n当前master连接的sentinels note left of sentinel[1]: sentinel[1]向slaves发送info指令,\n获取slaves状态 # 此时又增加了一台哨兵 sentinel[2] sentinel[2]->master: 发送指令:info sentinel[2]->master: 建立cmd连接 note right of master: master更新记录的信息:\n当前master连接的sentinels note right of sentinel[2]: sentinel[2]记录的信息:\nmaster信息\nslaves信息\n当前master连接的sentinels note right of sentinel[2]: sentinel[2]向slaves发送info指令,\n获取slaves状态 sentinel[2]->sentinel[1]: 建立通道:publish / subscribe \n用于哨兵间数据同步 sentinel[1]->sentinel[2]: 发送指令:ping \n获取各个sentinel状态

通知阶段

sentinel[1]->master/slaves: publish sentnel: hello master/slaves->sentinel[1]: 返回状态信息 note left of sentinel[1]: 在哨兵间的publish/subscribe网络中\n发布master/slaves的状态信息

故障转移阶段

确认master下线流程:

sentinel[1]->master: 发送hello指令无响应 sentinel[1]->master: 连续发送hello指令 note left of sentinel[1]: sentinel[1]将master标记为:SRI_S_DOWN \n S_DOWN:主观下线 sentinel[1]->sentinel[2]: 通过哨兵间的发布/订阅通道\n向其他哨兵传播master下线信息\n SENTINEL is-master-down-by-addr\n服务器host,port,发起方,状态.... sentinel[2]->master: 向master连续发送hello指令 sentinel[2]->sentinel[1]: sentinel[2]通过哨兵间发布/订阅通道\n确认master下线信息 note right of sentinel[2]: 超过一定数量的哨兵认为master下线\n(数量在哨兵配置文件配置)\nmaster被标记为:SRI_O_DOWN\nO_DOWN:客观下线

投票选择哨兵间的leader:

每个哨兵向哨兵间发布/订阅通道内发送信息:

SENTINEL is-master-down-by-addr ….

  • 下线的master的ip
  • 下线的master的端口号
  • 哨兵自己参与哨兵leader竞选的次数
  • 哨兵自己的runid

每一个哨兵作为参选者,同时也是投票者,每个哨兵有一票。哨兵根据自己接收到其他哨兵发送信息的先后顺序,把自己的票投给对应的哨兵。最终汇总得票结果,选出哨兵leader。如果第一轮没有选出来leader,再进行一轮投票,直至得出哨兵leader。每增加一轮,哨兵的参与竞选次数会增加1。

哨兵leader 从slave服务器里列表中挑选备用master转正,选择的原则:

  1. 备选的slave需要是在线的
  2. 给slave不停发送hello消息,淘汰掉响应慢的
  3. 淘汰与原master断开时间久的
  4. 优先原则

    • 比较优先级
    • 比较数据同步的offset
    • 选择runid比较小的

哨兵leader发送指令告知新的master:

  • 向新的master发送slaveof no one 指令
  • 向其他slave发送slaveof 新master的ip 端口号