EPaxos如何实现1轮网络往返提交?PreAccept快速路径源码级全解析
【免费下载链接】epaxos项目地址: https://gitcode.com/gh_mirrors/ep/epaxos
EPaxos(Egalitarian Paxos)是一款无领导者的分布式共识协议,通过 PreAccept 快速路径机制,让命令只需1 轮网络往返即可提交,比经典 Multi-Paxos 的 2 轮延迟显著更低。本文将从源码视角拆解这条快速路径的工作原理:为什么多数派无冲突时能跳过 Accept 阶段直接提交?4 个触发条件缺一不可,任何一个失败就自动降级到 2 轮慢路径兜底。
核心算法位于 src/epaxos/,协议消息定义在 src/epaxosproto/,完整形式化规范见 tla+/EgalitarianPaxos.tla。
传统 Paxos 为什么多一轮?🐢
经典 Multi-Paxos 领导者必须走完Prepare → Accept两个阶段:先发 Prepare 收集多数派状态,确认无冲突后再发 Accept。这意味着至少2 轮网络往返(Prepare 往返 + Accept 往返),加上 Commit 通知,客户端感知延迟通常为 2~3 轮。
EPaxos 的洞察是:PreAccept 阶段已经把命令内容和排序属性(seq / deps)完整携带给所有副本。如果多数派副本对这些属性无异议、依赖也已提交,那 Accept 阶段就是多余的——可以直接提交,省掉整整一轮。
PreAccept 快速路径:1 轮提交的 4 个关键步骤 🚀
① 客户端提案 → 5ms 攒批
客户端将命令发给任意副本(无需固定领导者)。该副本在 src/epaxos/epaxos.go#L801 的handlePropose中收到提案后,会等约 5ms 把到达的其他命令一起攒入同一个Instance(实例),提升批量吞吐。
② PreAccept 广播:一次携带完整信息
startPhase1(epaxos.go#L828)为 Instance 计算seq(全局序列号)和deps(最多 5 个副本的依赖实例号),然后调用bcastPreAccept向 N-1 个对等副本广播。
PreAccept 消息结构(epaxosproto.go#L26)携带了:
- 完整命令列表
- seq 排序号
- deps 依赖数组
💡 这是整个快速路径的核心:每个副本拿到 PreAccept 后就能独立判断是否接受,无需再来回询问领导者。
③ 多数派快速确认(PreAcceptOK)
对等副本收到 PreAccept 后,在 handlePreAccept(epaxos.go#L899) 中用updateAttributes更新本地属性表并做冲突检测。
如果属性没有变化、没有未提交依赖、来自初始领导者且是首次提案,该副本只回一个极简的PreAcceptOK(仅含 instance 编号,epaxos.go#L993)——比PreAcceptReply小得多,网络开销几乎可忽略。
④ 领导者立即提交
领导者在 handlePreAcceptReply(epaxos.go#L1000) 或 handlePreAcceptOK(epaxos.go#L1083) 中累计确认数。当确认数 ≥ N/2 且满足全部条件时,直接将状态置为COMMITTED,广播 Commit,立即回复客户端——全程仅 1 轮网络往返。
快速路径生效的 4 个前提条件 ✅
epaxos.go#L1050 的判断条件清晰地列出了 4 个必须同时满足的条件:
| # | 源码条件 | 含义 |
|---|---|---|
| 1 | preAcceptOKs >= N/2 | 至少半数副本已确认 |
| 2 | allEqual == true | 所有副本算出的 seq/deps 完全一致 |
| 3 | allCommitted == true | 本 Instance 的所有依赖实例均已提交 |
| 4 | isInitialBallot | 首次提案(ballot 高位为 0,无冲突重选) |
任何一个不满足 → 走慢路径。
快速路径失败?2 轮慢路径兜底 🛡️
当属性不一致或依赖未提交时,领导者在 epaxos.go#L1072 将状态置为ACCEPTED,广播 Accept 消息,进入经典两阶段提交——这正是标准 Paxos 的 Accept 轮次。
更复杂的冲突场景(副本崩溃重启、多领导者并发提案)会触发Prepare 恢复流程(epaxos.go#L1359),通过 Prepare / TryPreAccept 机制重新协商,保证协议安全性不受影响。
🎯设计哲学:快速路径是一种乐观策略——先假设无冲突直接提交,冲突时再回退到保守路径。无冲突场景延迟从 2 轮降至 1 轮,冲突场景正确性完全不变。
核心源码导读 📖
| 模块 | 文件路径 | 职责 |
|---|---|---|
| 快速路径核心逻辑 | src/epaxos/epaxos.go | PreAccept 发送 / 接收 / 提交全流程 |
| 协议消息结构 | src/epaxosproto/epaxosproto.go | PreAccept、PreAcceptOK 等消息定义 |
| 通用副本基类 | src/genericsmr/genericsmr.go | 连接管理、RPC 分发、Beacon 延迟感知 |
| 客户端压测工具 | src/client/client.go | 无领导者模式(-e)压测 |
| TLA+ 形式化规范 | tla+/EgalitarianPaxos.tla | 模型验证用完整协议规范 |
一键启动:最小部署指南 🏁
项目使用 Go 语言构建,3 步跑起来:
- 编译:设置
GOPATH指向项目根目录,执行go install server(同时可安装master、client) - 启动 3 个副本:
bin/server -port 7070 &、bin/server -port 7071 &、bin/server -port 7072 & - 无领导者压测:
bin/client -e开启 Egalitarian 模式,客户端随机连接任意副本
3 副本可容忍 1 个故障。快速路径下,命令提交延迟 =1 × 单程网络往返时间。
EPaxos 的 PreAccept 快速路径,本质是用一次广播携带完整排序信息 + 多数派快速确认替代了传统的两阶段协商。它不是跳过共识,而是让共识在一轮内完成——这正是"Egalitarian(人人平等)"的精髓:没有固定领导者瓶颈,每个副本都可能是提案的起点,1 轮提交是常态,而非例外。
【免费下载链接】epaxos项目地址: https://gitcode.com/gh_mirrors/ep/epaxos
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考