Skip to content

Commit

Permalink
fix docs about joint consensus (#434)
Browse files Browse the repository at this point in the history
Signed-off-by: Jay Lee <[email protected]>
  • Loading branch information
BusyJay authored May 12, 2021
1 parent 0223a26 commit 64b99c7
Showing 1 changed file with 27 additions and 33 deletions.
60 changes: 27 additions & 33 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,6 @@ config.validate().unwrap();
// Finally, create our Raft node!
let storage = MemStorage::new_with_conf_state((vec![1], vec![]));
let mut node = RawNode::new(&config, storage, &logger).unwrap();
// We will coax it into being the lead of a single node cluster for exploration.
node.raft.become_candidate();
node.raft.become_leader();
```
## Ticking the Raft node
Expand Down Expand Up @@ -280,6 +277,9 @@ need to update the applied index and resume `apply` later:
# fn handle_conf_change(e: raft::eraftpb::Entry) {
# }
#
# fn handle_conf_change_v2(e: raft::eraftpb::Entry) {
# }
#
# fn handle_normal(e: raft::eraftpb::Entry) {
# }
#
Expand All @@ -296,8 +296,9 @@ need to update the applied index and resume `apply` later:
match entry.get_entry_type() {
EntryType::EntryNormal => handle_normal(entry),
// It's recommended to always use `EntryType::EntryConfChangeV2.
EntryType::EntryConfChange => handle_conf_change(entry),
EntryType::EntryConfChangeV2 => unimplemented!(),
EntryType::EntryConfChangeV2 => handle_conf_change_v2(entry),
}
}
```
Expand Down Expand Up @@ -413,8 +414,6 @@ For more information, check out an [example](examples/single_mem_node/main.rs#L1
## Arbitrary Membership Changes
> **Note:** This is an experimental feature.
When building a resilient, scalable distributed system there is a strong need to be able to change
the membership of a peer group *dynamically, without downtime.* This Raft crate supports this via
**Joint Consensus**
Expand All @@ -424,42 +423,37 @@ It permits resilient arbitrary dynamic membership changes. A membership change c
the following:
* Add peer (learner or voter) *n* to the group.
* Remove peer *n* from the group.
* Remove a leader (unmanaged, via stepdown)
* Remove a learner *n* from the group.
* Promote a learner to a voter.
* Demote a voter back to learner.
* Replace a node *n* with another node *m*.
It (currently) does not:
* Allow control of the replacement leader during a stepdown.
* Optionally roll back a change during a peer group pause where the new peer group configuration
fails.
* Provide automated promotion of newly added voters from learner to voter when they are caught up.
This must be done as a two stage process for now.
> PRs to enable these are welcome! We'd love to mentor/support you through implementing it.
This means it's possible to do:
```rust
use raft::{Config, storage::MemStorage, raw_node::RawNode, eraftpb::*};
use protobuf::Message as PbMessage;
use slog::{Drain, o};
let mut config = Config { id: 1, ..Default::default() };
let store = MemStorage::new_with_conf_state((vec![1, 2], vec![]));
let logger = slog::Logger::root(slog_stdlog::StdLog.fuse(), o!());
let mut node = RawNode::new(&mut config, store, &logger).unwrap();
node.raft.become_candidate();
node.raft.become_leader();
For example to promote a learner 4 and demote an existing voter 3:
```no_run
# use raft::{Config, storage::MemStorage, raw_node::RawNode, eraftpb::*};
# use protobuf::Message as PbMessage;
# use slog::{Drain, o};
#
# let mut config = Config { id: 1, ..Default::default() };
# let store = MemStorage::new_with_conf_state((vec![1, 2], vec![]));
# let logger = slog::Logger::root(slog_stdlog::StdLog.fuse(), o!());
# let mut node = RawNode::new(&mut config, store, &logger).unwrap();
let steps = vec![
raft_proto::new_conf_change_single(4, ConfChangeType::AddNode),
raft_proto::new_conf_change_single(3, ConfChangeType::RemoveNode),
];
let mut cc = ConfChangeV2::default();
cc.set_changes(steps.into());
node.propose_conf_change(vec![], cc).unwrap();
// After the log is committed and applied
// node.apply_conf_change(&cc).unwrap();
```
This process is a two-phase process, during the midst of it the peer group's leader is managing
**two independent, possibly overlapping peer sets**.
> **Note:** In order to maintain resiliency guarantees (progress while a majority of both peer sets is
active), it is very important to wait until the entire peer group has exited the transition phase
active), it is recommended to wait until the entire peer group has exited the transition phase
before taking old, removed peers offline.
*/
Expand Down

0 comments on commit 64b99c7

Please sign in to comment.