etcd中raft协议的消息(二) —— 选举相关的消息(MsgHup、MsgPreVote/MsgPreVoteResp、MsgVote/MsgVoteResp)

一、MsgHup消息

   在raft协议中我们看到,Leader节点推动心跳计时器,而Follower节点会推动选举计时器。源码主要在etcd的github.com/etcd-io/etcd/tree/master/raft/node.go和raft.go中,raft结构体中有一个electionElapsed字段,该字段是选举计时器的指针,逻辑时钟每推进一次,该字段的值递增1,逻辑时钟是有上层模块来推进的。当electionElapsed选举计时器超时时,则该Follower节点会发送MsgHup消息。

    1.选举计时器逻辑时钟的推动

       选举计时器及超时时间在raft结构体中为以下两个字段:

electionElapsed int     //选举计时器的指针,其单位是逻辑时钟的刻度,逻辑时钟每推进一次,该字段值就会增加1	
randomizedElectionTimeout int     //随机生成的选举计时器超时时间

选举计时器是tickElection()函数来推动的,Node节点每收到一次逻辑时钟推进,就会调用一次该函数来推动逻辑时钟,并判断逻辑时钟是否超时,如果超时则发送MsgHup类型的消息。

    //推动选举计时器,如果超时则发送MsgHub消息
    func (r *raft) tickElection() {
	r.electionElapsed++

	if r.promotable() && r.pastElectionTimeout() {
		r.electionElapsed = 0
		r.Step(pb.Message{From: r.id, Type: pb.MsgHup})
        }
    }

      从以上方法我们看到,当选举计时器超时,节点会调用Step方法发送MsgHup消息。

     2.MsgHup消息流程

      

      从tickElection方法中可以看到,当选举计时器超时时,会将raft节点的electionElapsed心跳计时器置零,并且调用Step方法发送该MsgHup消息。Step方法处理各种消息类型的消息,我们这里只看对MsgHup消息的处理。

  

   如果当前节点是Leader,则忽略MsgHup类型的消息

   如果当前节点不是Leader,

   获取raftLog中已提交但未应用的Entry记录

   检测是否有未应用的EntryConfChange记录,如果有就放弃发起选举的机会

   检测当前集群是否开启了PreVote模式,如果开启了则发起PreElection预选举,没有开启则发起Election选举   

   调用campaign()发起选举

func (r *raft) Step(m pb.Message) error {

   // ......  其他类型消息处理略
   switch m.Type {	//根据Message的Type进行分类处理
	case pb.MsgHup:	//这里针对MsgHup类型进行处理(Flower转成PreCandidate发送的消息)
		if r.state != StateLeader {	//只有非Leader状态的节点才会处理MsgHup消息
			//获取raftLog中已提交但未应用的Entry记录
			ents, err := r.raftLog.slice(r.raftLog.applied+1, r.raftLog.committed+1, noLimit)
			if err != nil {
				r.logger.Panicf("unexpected error getting unapplied entries (%v)", err)
			}
			//检测是否有未应用的EntryConfChange记录,如果有就放弃发起选举的机会
		
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值