1 个不稳定版本
0.1.0 | 2023年7月26日 |
---|
#8 in #ha
40KB
910 行代码
RiteRaft - 为普通人提供的 raft 框架
这是在 tikv/raft-rs 的基础上创建一个易于使用和实现的层的尝试。这不是最具功能性的 raft,而是一个方便的接口,可以快速开始,并很快拥有一个可工作的 raft。
该接口强烈受到 canonical/raft 的启发。
入门
为了“raft”存储,我们需要为它实现 Storage
trait。以下是一个使用 HashStore
的示例,它是 HashMap
的线程安全包装器。
/// convienient data structure to pass Message in the raft
#[derive(Serialize, Deserialize)]
pub enum Message {
Insert { key: u64, value: String },
}
#[derive(Clone)]
struct HashStore(Arc<RwLock<HashMap<u64, String>>>);
impl Store for HashStore {
type Error = RaftError;
fn apply(&mut self, message: &[u8]) -> Result<Vec<u8>, Self::Error> {
let message: Message = deserialize(message).unwrap();
let message: Vec<u8> = match message {
Message::Insert { key, value } => {
let mut db = self.0.write().unwrap();
db.insert(key, value.clone());
serialize(&value).unwrap()
}
};
Ok(message)
}
fn snapshot(&self) -> Vec<u8> {
serialize(&self.0.read().unwrap().clone()).unwrap()
}
fn restore(&mut self, snapshot: &[u8]) -> Result<(), Self::Error> {
let new: HashMap<u64, String> = deserialize(snapshot).unwrap();
let mut db = self.0.write().unwrap();
let _ = std::mem::replace(&mut *db, new);
Ok(())
}
}
Store 只需要实现 3 个方法
Store::apply
:将已提交的条目应用到存储中。Store::snapshot
:返回存储的快照数据。Store::restore
:应用作为参数传递的快照。
运行 raft
#[tokio::main]
fn main() {
let store = HashStore::new();
let raft = Raft::new(options.raft_addr, store.clone());
let mailbox = Arc::new(raft.mailbox());
let (raft_handle, mailbox) = match options.peer_addr {
Some(addr) => {
info!("running in follower mode");
let handle = tokio::spawn(raft.join(addr));
(handle, mailbox)
}
None => {
info!("running in leader mode");
let handle = tokio::spawn(raft.lead());
(handle, mailbox)
}
};
tokio::join!(raft);
}
mailbox
为您提供与 raft 交互的方式,例如发送消息或将集群从集群中移除。
致谢
这项工作基于 raft-frp,但对代码进行了更多调整和改进。
许可证
本库根据您的选择许可为以下之一
- MIT 许可证 LICENSE-MIT 或 http://opensource.org/licenses/MIT
- Apache License 2.0 LICENSE-APACHE 或 https://opensource.org/licenses/Apache-2.0
。
依赖
~8–18MB
~219K SLoC