GithubHelp home page GithubHelp logo

Comments (8)

xnnyygn avatar xnnyygn commented on August 18, 2024

The votedFor is not saved because the node hasn't voted for anyone in that term.

In the scenario you said, when Node 2 and 3 become followers, they will save the first log, a NoOp log with only term in it. So Node 4 won't have a chance to become a leader without that log.

The NoOp log is the tricky part in the Raft algorithm. I cannot remember the exact chapter where it is discussed. Maybe the edge cases in the last several chapters.

from xraft.

Icysandwich avatar Icysandwich commented on August 18, 2024

But the log is written after the node becomes follower from candidate.
Thus, in a concurrent scenario, Node 4 can request Node 2 and Node 3 right after they become follower and before writing the log.

from xraft.

xnnyygn avatar xnnyygn commented on August 18, 2024

Sorry, my explanation might not be clear. The NoOp log is inserted by the new leader and replicated to followers.

  1. Node 1 receives enough votes and becomes a leader. Node 1 inserts a NoOp log and starts to replicate its log immediately.
  2. Node 2 and 3 receive AppendEntriesRpc from the leader, set the leader to Node 1, merge the logs from AppendEntriesRpc.

So, Node 4 won't get enough votes before step 2 or after step 2.

Hope this answers your question.

from xraft.

Icysandwich avatar Icysandwich commented on August 18, 2024

Okay, I see. Thanks for your further explanation.

You mean the leader writes NoOp in this task, right?

changeToRole(new LeaderNodeRole(role.getTerm(), scheduleLogReplicationTask()));

And in this task the leader will send AppendEntriesRpc requests to other nodes.

But the 2nd step in your comment is not atomic, i.e., the operation set leader and merge logs are executed in two lines:

becomeFollower(rpc.getTerm(), null, rpc.getLeaderId(), true);
return new AppendEntriesResult(rpc.getMessageId(), rpc.getTerm(), appendEntries(rpc));

So here's the concurrency scenario: before appendEntries(rpc) is executed (before writing NoOp log), Node 4 can launch the new leader election process and get votes from Node 2 and 3.

from xraft.

xnnyygn avatar xnnyygn commented on August 18, 2024

I guess you have misunderstood the thread model of XRaft. It's a single thread application except the connection handlers.

For the node receiving AppendEntriesRpc, while it is processing

public void onReceiveAppendEntriesRpc(AppendEntriesRpcMessage rpcMessage) {
context.taskExecutor().submit(() ->
context.connector().replyAppendEntries(doProcessAppendEntriesRpc(rpcMessage), rpcMessage),
LOGGING_FUTURE_CALLBACK
);
}

Any new messages will be queued and processed later, not at the same time.

TaskContext comes from here.

context.setTaskExecutor(taskExecutor != null ? taskExecutor : new ListeningTaskExecutor(
Executors.newSingleThreadExecutor(r -> new Thread(r, "node"))

from xraft.

Icysandwich avatar Icysandwich commented on August 18, 2024

Sorry for my misunderstanding. Now I've got the thread model. Thanks again for your explanation.

I seemingly find out a possible buggy scenario, which can occur when using FileLog instead of default MemoryLog.

After Node 1 finishes synchronizing the NoOp log (lastLogTerm = 1) with all nodes (Node 2, 3 and 4), a following generate snapshot command persists the log on disk. Then, Node 4 lanuches an new election process with term = 1 (volatile) and lastLogTerm = 1 (persistent) after a restart, and requests Node 2 and 3 for votes.
Here Node 2 and 3 can vote for Node 4 in case both two conditions hold.

if ((votedFor == null && !context.log().isNewerThan(rpc.getLastLogIndex(), rpc.getLastLogTerm())) ||

We know that votedFor == null holds on Node 2 and 3.

Here in isNewerThan method, Node 2 and 3's logTerm equals 1, while the rpc's lastLogTerm is also 1, and all logIndex equals 0. Thus, the method returns false. Finally, Node 2 and 3 can vote for Node 4.

return lastEntryMeta.getTerm() > lastLogTerm || lastEntryMeta.getIndex() > lastLogIndex;

from xraft.

xnnyygn avatar xnnyygn commented on August 18, 2024

Of course node 2 and 3 should vote for node 4 if node 4 has effectively latest log.

After node 4 receives AppendEntriesRpc from node 1, its term will be the same as node 1, 2, and 3. If node 4 restarts due to some unexpected error, it will continue to be a follower while receiving AppendEntriesRpc or heart beat messages from node 1. Should there be a weird network partition, node 1 could not contact node 4 but they were both able to connect to node 2 and 3, node 4 attempted to become a leader and it was sure to be successful. However, the cluster will be unstable.

from xraft.

Icysandwich avatar Icysandwich commented on August 18, 2024

A network partition is not essential. When AppendEntriesRpc requests are delayed, the situation occurs. And Raft should be tolerant to message delay faults.

from xraft.

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.