哨兵系统会监控主从服务器,当检测到下线时长超过用户设定时长上限时,会进行故障转移操作:

  • 选择一个从服务器作为主服务器
  • 然后对其他所有从服务器发送新的复制指令,让它们成为新的主服务器的从服务器,当所有从服务器都开始复制新的主服务器时,故障转移操作完毕
  • 另外,哨兵还会继续监视已下线的服务器,并在它重新上线时,将它设置为新的主服务器的从服务器。

关键过程

  1. 启动并初始化sentinel
  2. 获取主服务器信息
  3. 获取从服务器信息
  4. 向主服务器和从服务器发送信息
  5. 接收来自主服务器和从服务器的频道信息
  6. 检测主观下线状态
  7. 检测客观下线状态
  8. 选举头领 sentinel
  9. 故障转移

检测客观下线

当sentinel将一个主服务器判断为主观下线后,为了确认这个主服务器是否真的下线了,它会向监视这一主服务器的其他sentinel进行询问,看它们是否也认为主服务器进入了下线状态(主观或客观)。当sentinel从其他sentinel接收到足够数量的已下线判断后,sentinel就会将主服务器判定为客观下线,并对主服务器进行故障转移。

选举头领

判断主服务器是否为客观下线时,监视这个主服务器的sentinel会进行协商,选举出一个领头sentinel,并由领头sentinel进行故障转移。选举头领是对raft算法的领头选举方法的实现。

  • 所有在线的sentinel都有可能被选中
  • 选举后无论成功与否,每个sentinel的配置纪元(configuration epoch)都会加1,实际就是计数器
  • 在配置纪元里每个sentinel都有一次将某个sentinel设为局部头领的机会,局部头领一旦设置就不能更改
  • 每个发现主服务器客观下线的sentinel都要求其他sentinel将自己设为局部头领
  • 如何要求其他sentinel?通过向其他sentinel发送命令sentinel is-master-down-by-addr命令,并且参数中的runid不是 * 而是源sentinel的运行id,表示要求其他sentinel将自己设为局部头领
  • 设置局部头领的规则是先到先得,目标sentinel会将第一个接收到的sentinel设置为局部头领,之后的都会被拒绝。
  • 目标sentinel收到sentinel is-master-down-by-addr后,会返回一条回复,其中leader_runid和leader_epoch参数记录局部头领的运行id和配置纪元。
  • 源sentinel收到后会与自己的对比,如果都相同则表示目标sentinel将源sentinel设为局部头领
  • 如果某个sentinel被半数以上的sentinel设为局部头领,那么这个sentinel成为头领sentinel。

故障转移

选举出头领sentinel后,头领将对主服务器进行转移操作:

  1. 在已下线的主服务器的从服务器里面挑选一个作为主服务器
  2. 其他从服务器重新复制新的主服务器
  3. 将已下线的主服务器作为新主服务器的从服务器,等它上线。

如何挑选新主服务器?
头领会将所有从服务器放在一个列表里进行过滤

  1. 删除所有状态不正常的从服务器,保证剩余的从服务器是正常的
  2. 删除所有5秒内没有回复过头领sentinel INFO 命令的从服务器,保证最近都是通信过的
  3. 删除所有与已下线主服务器连接断开超过主服务器下线所需时间的10倍的从服务器,保证剩余的从服务器没有过早的断开连接
    换句话说,这些操作的目的是为了保证要选的从服务器的数据都是最新的。

之后还会根据从服务器的优先级排序,选择其中优先级最高的。
如果优先级最高的有多个,则按照复制偏移量排序,选择复制偏移量最大的,因为越大说明数据越近;
如果复制偏移量也有重复的,则按照运行id排序,选择最小的从服务器。这样主服务器就选出来了。
头领sentinel向被选中的从服务器发送slaveof no one命令,发送slaveof no one 命令后会以每秒1次的频率(平时是10秒一次)向被选中的服务器发送INFO命令,并观察回复中的角色(role)信息,当角色信息变为master时,表示被选中的从服务器已经升级为主服务器了。

选出主服务器之后,如何让其他服务器复制新的主服务器呢?
通过发送slaveof 命令,并且附带新的主服务器的ip加端口

最后如何让下线的主服务器变为从服务器?
头领一直监视着已下线的主服务器,一旦检测到它重新上线后,通过向其发送slaveof命令,让它成为新的主服务器的从服务器。

标签: none

添加新评论