OpenRaft 0.10 评估:为分布式存储量身定制的 Raft 变体,但 API 尚未稳定
锈筏经过改进。路线图 [x] 2022-10-31 扩大联合成员资格 [x] 2023-02-14 尽量减少选举时的冲突率;参见:OpenRaft 投票设计;或者使用标准 Raft Leader-ID 模式。
秒懂
- 它是什么?
- OpenRaft 是 Databend 团队维护的 Rust Raft 实现,主打扩展联合成员变更和低冲突选举。本文基于仓库文档与发布记录,分析其机制、适用场景与当前限制。
- 适合谁用?
- OpenRaft 适合需要自定义存储层、追求高吞吐且能接受 API 变动的 Rust 分布式系统团队。它不适合希望开箱即用、不愿处理存储与网络抽象层的项目。
- 能商用吗?
- 可以。Apache-2.0 是宽松许可证:你可以使用、修改并销售基于它的软件,只需保留版权和许可证声明。
- 还在维护吗?
- 在维护。仓库最近一次提交在 1 天前。
- 用什么语言写的?
- 主要是 Rust(依据 GitHub 的语言统计)。
以上回答依据项目的 GitHub 数据(最近同步于 2026年9月15日)和我们的分析,不构成法律意见。
开源项目深度解析
它解决什么问题:标准 Raft 的成员变更与选举冲突
标准 Raft 一次只能变更一个集群成员,导致大规模扩缩容需要多次往返。OpenRaft 的扩展联合成员变更允许在单次操作中替换任意数量的节点。另一个痛点是选举冲突:在节点数多或网络抖动时,标准 Raft 的任期递增机制容易引发反复分裂投票。OpenRaft 重新设计了 Vote 结构,让分裂投票不强制进入新任期。这两个改进直接服务于分布式数据存储系统,例如 Databend 的 meta-service 集群。目标用户是那些需要高吞吐、低延迟且愿意自己实现存储和网络层的 Rust 开发者。
核心机制:Vote 设计与预投票选项
OpenRaft 的 Vote 设计是减少选举冲突的关键。传统 Raft 中,候选人递增任期并广播投票请求,若多个候选人同时出现,可能无人获得多数票,导致任期不断递增。OpenRaft 的 Vote 包含 leader_id 和任期信息,允许节点在相同任期内记录已投票给谁,从而避免不必要的任期递增。文档还提到标准 Raft leader-ID 模式可作为备选。预投票功能在 0.10 中实现,通过 Config::enable_pre_vote 启用,节点在递增任期前先询问对等方是否可能授予投票。这避免了网络分区中的节点频繁打断主集群。这些机制在文档中有专门的设计讨论链接,说明作者重视协议层面的严谨性。
如何运行:从 Cargo 依赖到示例应用
OpenRaft 以 crate 形式发布,版本分 0.9 稳定线和 0.10 alpha 线。0.10 示例位于 release-0.10 分支,需要依赖 openraft 0.10.0-alpha.34。在 Cargo.toml 中添加 openraft = "0.10.0-alpha.34" 即可开始。文档建议从 OpenRaft guide 入手,它位于 docs.rs 的 getting_started 页面。你需要实现存储和网络抽象,因为 OpenRaft 只提供共识逻辑。示例应用展示了最小化的 store 和 network 实现。0.9 版本在 crates.io 上有 v0.9.25,但只接受 bug 修复,新功能都在 0.10。升级有专门指南,例如 0.9 到 0.10 的迁移文档。
性能数据:框架吞吐与真实场景的差距
README 给出了基准数据:单客户端写入 33,000 次/秒,4096 个并发客户端时 3,548,000 次/秒,批量写入(每批 4 条)达到 5,615,000 次/秒。但文档明确标注这是最小化存储和网络环境下的框架基准,不是真实应用基准。这些数字能说明框架本身的开销很低,但不能直接推算生产系统的吞吐。真实系统还要考虑日志持久化、网络延迟和状态机执行。如果你看到这些数字就认为 OpenRaft 一定快,那是误读。基准代码在 benchmarks/minimal 目录,你可以自行运行验证。
测试与可靠性:确定性模拟与 Jepsen 套件
OpenRaft 声称单元测试覆盖率达 92%,并且每个 CI 构建都会运行一个确定性模拟模糊器(tests-turmoil)。此外,Jepsen 套件在每次推送到 main 时运行 8 种故障场景:网络分区、进程暂停、进程杀死、慢包、丢包、时钟偏移、成员变更以及这些组合。这部分展示了项目对一致性的重视。但覆盖率数字本身不能证明正确性,Jepsen 测试的存在是更实质的信号。对于共识协议,模糊测试和故障注入比单元测试更有价值。如果你关注协议实现的正确性,可以查看 tests-turmoil 目录了解模拟器的具体场景。
版本策略与维护成本:alpha 阶段的现实
0.10 线仍处于 alpha,API 可能在最终 0.10.0 前变化。README 明确说 OpenRaft API 在 1.0.0 之前不稳定。commit 消息使用 data-change、change、feat、fix 前缀标记修改类型,其中 data-change 意味着磁盘数据格式变化,可能需要手动升级。这意味着一旦采用,你需要跟踪 change-log 并准备迁移脚本。0.9 分支已冻结新功能,只修 bug,适合不想跟随 alpha 的团队。但 0.9 缺少预投票等新特性。维护成本取决于你是否愿意锁定版本并自行处理升级。许可证是 Apache-2.0,允许商用和修改,但需保留版权声明。
替代方案对比:标准 Raft 与 async-raft
OpenRaft 源自 async-raft,修复了若干 bug,因此 async-raft 本身是一个直接替代,但功能更少,且可能没有 OpenRaft 的扩展成员变更和 Vote 设计。另一个选择是标准 Raft 的实现如 raft-rs,它遵循原始论文,成员变更一次一个节点,选举冲突处理方式传统。如果你的集群规模小,成员变更不频繁,标准实现更简单且稳定。OpenRaft 的优势在于大规模集群和频繁成员变更场景,比如自动扩缩容。它还为偶数节点集群引入了 read-quorum 和 write-quorum 的考虑,但这是 roadmap 中未完成的项目。选择时需权衡:你需要扩展成员变更吗?你能接受 alpha API 吗?
编辑结论
OpenRaft 适合需要自定义存储层、追求高吞吐且能接受 API 变动的 Rust 分布式系统团队。它不适合希望开箱即用、不愿处理存储与网络抽象层的项目。在采用前,先确认你愿意跟随 0.10 alpha 的 API 变化,并检查 change-log 中的 data-change 标记,因为磁盘数据格式可能不兼容。若你的集群规模小且成员变更不频繁,标准 Raft 实现如 raft-rs 可能更省心。最终判断:OpenRaft 的扩展联合成员变更和预投票机制是实打实的改进,但 0.10 未到 1.0,生产使用需锁定版本并预留迁移成本。
社区笔记