mon选举流程总结

来源:互联网 发布:java后端游戏引擎 编辑:程序博客网 时间:2024/05/16 14:17

选举的触发条件

mon 的选举会在3中情况下触发:

1.     mon启动,bootstrap阶段。

2.     收到其它mon发送的选举请求,Elector::handle_propose时,如果自身满足一定条件会发起选举。

3.     ceph命令触发quorum变动时。

 

选举的关键环节

bootstrap阶段的选举大致可以分为两个阶段:准备阶段和选举阶段。

准备阶段

在选举前要准备monmap和quorum或outside_quorum(主要是outside_quorum的准备,quorum是在一次成功的选举之后才通过acked_me赋值的,不是从配置文件中读取的,非bootstrap第一次选举的情形用quorum.).这些是通过向monmap中和extra_probe_peers中的mon发送OP_PROBE消息,其它mon回复的OP_REPLY消息中获取的。extra_probe_peers是指给mon发送个OP_PROBE消息且fsid相同但不在monmap中的mon.

选举阶段

当monmap,quorum等必要条件满足以后,则会发起选举,可能多个mon同时发起选举。当集群第一次启动时,是通过outside_quorum中的选举成员完成选举的,此时quorum为空。如果想要发起选举,mon必须满足以下条件:

1、 自己必须处于STATE_PROBING或STATE_ELECTING状态。

2、 其它mon通过OP_REPLY消息自身没有参加过任何选举 或 mon参加过选举且自己的election_epoch比其它mon返回的epoch高。

3、 paxos版本足够高,不必从其它mon同步数据。

4、 quorum或outside_quorum中成员的数量达到monmap中成员数量的一半以上。

 

由于接收消息的时间差等,满足要求的mon可能不止一个,多个mon会同时发起请求,从这方面说mon的选主并不是一次典型的basic paxos过程。多个mon同时发起选主请求时,决定最终能否获胜的关键因素是rank值的大小,rank值最小的才能获得最终的胜利。

多个mon发起选主,向quorum(ouside_quorum)中的成员发送OP_PROPOSE消息,是否否会收到回复呢?不是。只有满足下面两个条件才会收到其它mon的回复:

1、 epoch要比其它mon的epoch大。

2、 接受方没有回复过其它mon或自己的rank值小于接收到回复过的mon的rank值。

 

前面多次提到过epoch,那么epoch是如何生成的呢?epoch有两种方式生成,一是启动时从leveldb中读取,然后+1变为奇数,奇数代表选举阶段,偶数时稳态,如果leveldb中没有,赋值为1。二是准备阶段根据其它mon返回的消息中epoch的值设置。

 

上面的限制能否覆盖一下异常情况呢。我们来考虑以下两种情况,看能不能保证rank值最小的mon在最终的选举胜出。

有mon0,mon1,mon2,对应的rank值分别为0,1,2.

情形1:由于消息传递时间的原因,mon1已经在选举中胜出,mon0再发送选举请求,mon0还能胜出吗?能。因为此时mon1,mon2收到消息后都会进行处理,如果满足mon0的epoch版本更高且mon0的rank值更小,就会回复消息。Elector.cc中void Elector::handle_propose()处理。

情形2:系统中新加入了一个mon,且这个mon的rank值最小,以mon0为例,由于mon0是新安装的,所以epoch版本肯定小于当前集群中稳态的epoch的值,那么mon0还能在选举中获胜吗?能。mon1,mon2在收到消息后会重新调用start_election,mon0在收到mon1或mon2发来的消息后,由于自己的epoch<m-epoch,会调用bump_epoch来更新自己的版本信息,然后mon0重新调用start_elction发起选举,也是在void Elector::handle_propose()处理的。

rank值来自于哪里呢?从monmap中获取,monmap也是有版本号的,会用其它mon的高版本的monmap更新自己的monmap.

 

选主基本代码流程分析参考:

http://blog.csdn.net/scaleqiao/article/details/52315468

 

原创粉丝点击