Skip to content

Commit

Permalink
Merge pull request databendlabs#988 from drmingdrmer/35-leader-id
Browse files Browse the repository at this point in the history
Doc: explain LeaderId: partial order or total order
  • Loading branch information
drmingdrmer authored Jan 11, 2024
2 parents ab7f309 + 42c06fb commit 42e809c
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 8 deletions.
33 changes: 30 additions & 3 deletions openraft/src/docs/data/leader_id.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,36 @@
# Leader-id in Advanced mode and Standard mode
## Leader-id in Advanced mode and Standard mode

Openraft provides two `LeaderId` types to switch between these two modes with feature `single-term-leader`:
Openraft provides two `LeaderId` types to switch between these two modes with feature [`single-term-leader`] :

The feature [`single-term-leader`] affects the `PartialOrd` implementation of `LeaderId`, where `LeaderId` is defined as a tuple `(term, node_id)`.

### Definition of `LeaderId`

Within Openraft, and also implicitly in the standard Raft, `LeaderId` is utilized to uniquely identify a leader. The `LeaderId` could either be a confirmed leader, one that has been granted by a `Quorum`, or a potential `Leader`, such as a `Candidate`.

- In standard Raft, the definition of `LeaderId` as `(term, node_id)` implies a **`partial order`**, although it is not explicitly articulated in the original paper.

When comparing two `LeaderId` `A` and `B`, the partial order for `LeaderId` in standard Raft is as follows:

`A.term > B.term ↔ A > B`.
<br/><br/>

- Conversely, in Openraft, with the [`single-term-leader`] feature disabled by default, `LeaderId` follows a `total order` based on lexicographical comparison:

`A.term > B.term || (A.term == B.term && A.node_id > B.node_id) ↔ A > B`.

Activating the `single-term-leader` feature makes `LeaderId` conform to the `partial order` seen in standard Raft.

### Usage of `LeaderId`

When handling `VoteRequest`, both Openraft and standard Raft (though not explicitly detailed) rely on the ordering of `LeaderId` to decide whether to grant a vote:
**a node will grant a vote with a `LeaderId` that is greater than any it has previously granted**.

Consequently, by default in Openraft (with `single-term-leader` disabled), it is possible to elect multiple `Leader`s within the same term, with the last elected `Leader` being recognized as valid. In contrast, under standard Raft protocol, only a single `Leader` is elected per `term`.

### Default: advanced mode

`cargo build` without [`single-term-leader`], is the advanced mode, the default mode:
`cargo build` without [`single-term-leader`][], is the advanced mode, the default mode:
`LeaderId` is defined as the following, and it is a **totally ordered** value(two or more leaders can be granted in the same term):

```ignore
Expand Down Expand Up @@ -99,3 +125,4 @@ So let a committed `Vote` override a incomparable non-committed is safe.
- Cons: election conflicting rate may increase.


[`single-term-leader`]: crate::docs::feature_flags
4 changes: 2 additions & 2 deletions openraft/src/docs/data/vote.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ In a standard Raft, the corresponding concept is `(term, voted_for: Option<NodeI

The validity checking for RPCs in Openraft, such as when handling vote or append-entries requests,
is straightforward. Essentially, **a node will grant a `Vote` only if it is greater than or equal to the last `Vote` it has seen**.
Refer to the `PartialOrd` implementation for [`Vote`]. The pseudo code about vote order checking is as follows:
Refer to the `PartialOrd` implementation for [`Vote`]. The pseudocode about vote order checking is as follows:

```ignore
# pseudo code
Expand Down Expand Up @@ -43,7 +43,7 @@ See: [`leader-id`].

## Vote and Membership define the server state

In the default mode, the `Vote` defines the server state(leader, candidate, follower or learner).
In the default mode, the `Vote` defines the server state (leader, candidate, follower or learner).
A server state has a unique corresponding `vote`, thus `vote` can be used to identify different server
states, i.e, if the `vote` changes, the server state must have changed.

Expand Down
9 changes: 6 additions & 3 deletions openraft/src/docs/feature_flags/feature-flags.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,12 @@ By default openraft enables no features.
<br/><br/>

- `single-term-leader`: allows only one leader to be elected in each `term`.
This is the standard raft policy, which increases election confliction rate
but reduce `LogId`(`(term, node_id, index)` to `(term, index)`) size.
Read more about how it is implemented in [`vote`](./vote.md)
This is the standard raft policy, which increases election conflict rate
but reduce `LogId` size(`(term, node_id, index)` to `(term, index)`).

Read more about how it is implemented in:
[`leader_id`](crate::docs::data::leader_id)
and [`vote`](crate::docs::data::vote).
<br/><br/>

- `compat-07`: provides additional data types to build v0.7 compatible RaftStorage.
Expand Down

0 comments on commit 42e809c

Please sign in to comment.