7 个版本
0.2.0 | 2022 年 1 月 8 日 |
---|---|
0.1.6 | 2021 年 12 月 1 日 |
0.1.4 | 2021 年 11 月 20 日 |
0.1.3 | 2021 年 8 月 21 日 |
#564 in 并发
每月 22 次下载
50KB
875 行
Little Raft
最轻量级的分布式共识库。运行您自己的复制状态机!❤️
安装
只需导入 crate。在您的 Cargo.toml
中添加
[dependencies]
little_raft = "0.1"
使用
要启动 Little Raft,您只需做三件事。
- 实现您集群想要维护的 StateMachine。Little Raft 将负责在集群中复制此机器并就其状态达成共识。
/// StateMachine describes a user-defined state machine that is replicated
/// across the cluster. Raft can Replica whatever distributed state machine can
/// implement this trait.
pub trait StateMachine<T>
where
T: StateMachineTransition,
{
/// This is a hook that the local Replica will call each time the state of a
/// particular transition changes. It is up to the user what to do with that
/// information.
fn register_transition_state(&mut self, transition_id: T::TransitionID, state: TransitionState);
/// When a particular transition is ready to be applied, the Replica will
/// call apply_transition to apply said transition to the local state
/// machine.
fn apply_transition(&mut self, transition: T);
/// This function is used to receive transitions from the user that need to
/// be applied to the replicated state machine. Note that while all Replicas
/// poll get_pending_transitions periodically, only the Leader Replica
/// actually processes them. All other Replicas discard pending transitions.
/// get_pending_transitions must not return the same transition twice.
fn get_pending_transitions(&mut self) -> Vec<T>;
}
- 实现 Cluster 抽象,以便本地副本可以与其他节点通信。
/// Cluster is used for the local Raft Replica to communicate with the rest of
/// the Raft cluster. It is up to the user how to abstract that communication.
/// The Cluster trait also contains hooks which the Replica will use to inform
/// the crate user of state changes.
pub trait Cluster<T>
where
T: StateMachineTransition,
{
/// This function is used to deliver messages to target Replicas. The
/// Replica will provide the to_id of the other Replica it's trying to send
/// its message to and provide the message itself. The send_message
/// implementation must not block but is allowed silently fail -- Raft
/// exists to achieve consensus in spite of failures, after all.
fn send_message(&mut self, to_id: usize, message: Message<T>);
/// This function is used by the Replica to receive pending messages from
/// the cluster. The receive_messages implementation must not block and must
/// not return the same message more than once.
fn receive_messages(&mut self) -> Vec<Message<T>>;
/// By returning true from halt you can signal to the Replica that it should
/// stop running.
fn halt(&self) -> bool;
/// This function is a hook that the Replica uses to inform the user of the
/// Leader change. The leader_id is an Option<usize> because the Leader
/// might be unknown for a period of time. Remember that only Leaders can
/// process transitions submitted by the Raft users, so the leader_id can be
/// used to redirect the requests from non-Leader nodes to the Leader node.
fn register_leader(&mut self, leader_id: Option<ReplicaID>);
}
- 启动您的副本!
/// Create a new Replica.
///
/// id is the ID of this Replica within the cluster.
///
/// peer_ids is a vector of IDs of all other Replicas in the cluster.
///
/// cluster represents the abstraction the Replica uses to talk with other
/// Replicas.
///
/// state_machine is the state machine that Raft maintains.
///
/// noop_transition is a transition that can be applied to the state machine
/// multiple times with no effect.
///
/// heartbeat_timeout defines how often the Leader Replica sends out
/// heartbeat messages.
///
/// election_timeout_range defines the election timeout interval. If the
/// Replica gets no messages from the Leader before the timeout, it
/// initiates an election.
///
/// In practice, pick election_timeout_range to be 2-3x the value of
/// heartbeat_timeout, depending on your particular use-case network latency
/// and responsiveness needs. An election_timeout_range / heartbeat_timeout
/// ratio that's too low might cause unwarranted re-elections in the
/// cluster.
pub fn new(
id: ReplicaID,
peer_ids: Vec<ReplicaID>,
cluster: Arc<Mutex<C>>,
state_machine: Arc<Mutex<S>>,
noop_transition: T,
heartbeat_timeout: Duration,
election_timeout_range: (Duration, Duration),
) -> Replica<S, T, C>;
/// This function starts the Replica and blocks forever.
///
/// recv_msg is a channel on which the user must notify the Replica whenever
/// new messages from the Cluster are available. The Replica will not poll
/// for messages from the Cluster unless notified through recv_msg.
///
/// recv_transition is a channel on which the user must notify the Replica
/// whenever new transitions to be processed for the StateMachine are
/// available. The Replica will not poll for pending transitions for the
/// StateMachine unless notified through recv_transition.
pub fn start(&mut self, recv_msg: Receiver<()>, recv_transition: Receiver<()>);
这样,您就可以开始了。我们正在编写示例,但到目前为止,您可以查看 little_raft/tests
目录和 https://docs.rs/little_raft/0.1.3/little_raft/ 中的文档。我们正在添加更多测试。
测试
运行 cargo test
。
贡献
欢迎贡献!请记住,这个库的一个目标是要尽可能小和简单。让我们保持 little_raft/src
中的代码在 1000 行以下。违反此规则的 PR 将被拒绝。
> cloc little_raft/src
6 text files.
6 unique files.
0 files ignored.
github.com/AlDanial/cloc v 1.90 T=0.02 s (369.2 files/s, 56185.0 lines/s)
-------------------------------------------------------------------------------
Language files blank comment code
-------------------------------------------------------------------------------
Rust 6 82 199 632
-------------------------------------------------------------------------------
SUM: 6 82 199 632
-------------------------------------------------------------------------------
您随时可以挑选并处理这个项目中的任何开放问题。或者,如果您在使用此库的过程中遇到任何问题,可以提交新问题。
依赖项
~3.5MB
~54K SLoC