distributed-systemconsensusraft

In Raft distributed consensus, what do I set votedFor to?


I am trying to implement the Raft consensus algorithm. Here is my general understanding around all the times we set the term and votedFor attributes of a server's state:

  1. Upon startup term is 0 and votedFor is null
  2. Upon a server's election timeout, the server becomes a Candidate, increments its term by 1, and sets its votedFor to itself.
  3. When a server receives a RequestVote RPC with a term higher than its own, it should update the term to the number observed, then update votedFor to the sender iff the receiving server has a votedFor of null and its log is not more up-to-date than the sender's log.
  4. When a Candidate receives an AppendEntries RPC, and the sender's term is higher than or equal to its own, the Candidate should update its term to the sender's term then set its votedFor to the sender and have it's state become Follower, thereby acknowledging the sender as its legitimate leader.
  5. In all other cases when a server receives any RPC request or response containing a term higher than its own, it should set its own term to the received server's term and set votedFor to null.

Together, do these make up the only 5 ways that term and votedFor are set in a correct implementation of Raft, and are these cases correctly summarized? I am confused about this because the paper only mentions that at certain times a node will go through a conversion to a follower which does not specify whether votedFor should be the value of the sender with the higher term or null. I am worried that case 4 is wrong and should be this instead: on AppendEntries if the sender's term is greater, then the receiver should update their term to that of the sender, then set votedFor to the sender, regardless of whether or not the receiver is a Follower, Candidate, or stale Leader.


Solution

  • As you can see in the "Rules for All Servers" of Figure 2 of the original paper:

    If RPC request or response contains term T > currentTerm:

    set currentTerm = T, convert to follower (§5.1)

    in which case you are supposed to reset votedFor to null.

    As a result, in your rule 3, when a server receives a RequestVote RPC with a term higher than its own, it should update the term to the number observed and also reset the votedFor to null (meaning that in this case, it will always vote for the requesting server).