Giter Site home page Giter Site logo

Comments (5)

OneSizeFitsQuorum avatar OneSizeFitsQuorum commented on May 22, 2024

该方法是作为leader才会调用,“❓”处我觉得会使得这个leader自己election timeout,确切地说作为leader没有什么办法可以reset这个ticker中的election timeout。

electionTimer 和 heartbeatTimer 是两个 timer 呀?为什么要在心跳函数里面 reset election 的 timer 呢?

from mit6.824-2021.

Vector6662 avatar Vector6662 commented on May 22, 2024

该方法是作为leader才会调用,“❓”处我觉得会使得这个leader自己election timeout,确切地说作为leader没有什么办法可以reset这个ticker中的election timeout。

electionTimer 和 heartbeatTimer 是两个 timer 呀?为什么要在心跳函数里面 reset election 的 timer 呢?

抱歉我没有表述清楚。我的意思是作为leader,它的electiontimeout也是会到期的
您的ticker()代码中:

case <-rf.electionTimer.C:
    rf.mu.Lock()
    rf.ChangeState(StateCandidate)
    rf.currentTerm += 1
    rf.StartElection()
    rf.electionTimer.Reset(RandomizedElectionTimeout())
    rf.mu.Unlock()

当作为leader的时候electionTimer到期了,也会进行选举,那么2A的test中会有这样的输出:warning: term changed even though there were no failuresTestInitialElection2A中44行)

我想了一段时间做了一点修改,只有在非leader的时候才会调用startElection(),参考了raft论文中的Figure 4:

case <-rf.electionTimer.C: // 选举时间超时,则开始选举,这个过程参考Figure 2的"Rules for Servers"
  rf.mu.Lock()
  if Leader != rf.state {
      rf.currentTerm++
      rf.changeState(Candidate)
      rf.startElection()
      //todo 重要修正: https://github.com/OneSizeFitsQuorum/MIT6.824-2021/issues/15
      rf.electionTimer.Reset(ElectionTimeOut())
  }
  rf.mu.Unlock()

原因是作为leader进行BroadcastHeartbeat时是排除了自己的

if peer == rf.me {
	continue
}

于是leader自己也会election timeout,然后成为candidate。但是Figure 4中并没有Leader直接转换为Candidate的箭头。

还改了一个地方,是您的startElection()中的:

if response.VoteGranted {
    grantedVotes += 1
    if grantedVotes > len(rf.peers)/2 {
	    DPrintf("{Node %v} receives majority votes in term %v", rf.me, rf.currentTerm)
	    rf.ChangeState(StateLeader)
	    rf.BroadcastHeartbeat(true)
            rf.heartbeatTimer.Reset(HeartbeatTimeOut()) //❗这是我多加的代码
    }
}

多添加的原因是,选举成为Leader之前,ticker中的heartbeat timeout会耗尽,且不会reset,这是因为成为leader之前不是leader,于是不会执行if rf.state == StateLeader:

case <-rf.heartbeatTimer.C:
    rf.mu.Lock()
    if rf.state == StateLeader {
    rf.BroadcastHeartbeat(true)
    rf.heartbeatTimer.Reset(StableHeartbeatTimeout())
    }
    rf.mu.Unlock()

于是,在Make()中初始化时设置的那个heartbeat timeout之后,就再也不会重channel中收到heartbeat timeout了,即使选举成为leader,也只会执行一次rf.BroadcastHeartbeat(true),即选举成功时执行的那次。这也是我添加那行的原因:重新“激活”heartbeat timeout。

from mit6.824-2021.

OneSizeFitsQuorum avatar OneSizeFitsQuorum commented on May 22, 2024

在成为 leader 之后我会将 electionTimer 停掉的。你是不是只看了我文档中的部分代码。。。

func (rf *Raft) ChangeState(state NodeState) {
	if rf.state == state {
		return
	}
	DPrintf("{Node %d} changes state from %s to %s in term %d", rf.me, rf.state, state, rf.currentTerm)
	rf.state = state
	switch state {
	case StateFollower:
		rf.heartbeatTimer.Stop()
		rf.electionTimer.Reset(RandomizedElectionTimeout())
	case StateCandidate:
	case StateLeader:
		lastLog := rf.getLastLog()
		for i := 0; i < len(rf.peers); i++ {
			rf.matchIndex[i], rf.nextIndex[i] = 0, lastLog.Index+1
		}
		rf.electionTimer.Stop()
		rf.heartbeatTimer.Reset(StableHeartbeatTimeout())
	}
}

from mit6.824-2021.

Vector6662 avatar Vector6662 commented on May 22, 2024

在成为 leader 之后我会将 electionTimer 停掉的。你是不是只看了我文档中的部分代码。。。

明白了,谢谢大佬解答😄!确实没有注意到有ChangeState的实现🤣

from mit6.824-2021.

Alan-hunter avatar Alan-hunter commented on May 22, 2024

在成为 leader 之后我会将 electionTimer 停掉的。你是不是只看了我文档中的部分代码。。。

func (rf *Raft) ChangeState(state NodeState) {
	if rf.state == state {
		return
	}
	DPrintf("{Node %d} changes state from %s to %s in term %d", rf.me, rf.state, state, rf.currentTerm)
	rf.state = state
	switch state {
	case StateFollower:
		rf.heartbeatTimer.Stop()
		rf.electionTimer.Reset(RandomizedElectionTimeout())
	case StateCandidate:
	case StateLeader:
		lastLog := rf.getLastLog()
		for i := 0; i < len(rf.peers); i++ {
			rf.matchIndex[i], rf.nextIndex[i] = 0, lastLog.Index+1
		}
		rf.electionTimer.Stop()
		rf.heartbeatTimer.Reset(StableHeartbeatTimeout())
	}
}

大佬,在成为了 leader 后 调用relectionTImer.Stop,但是在 ticker 中不是又继续执行了 reset 吗?

from mit6.824-2021.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.