OceanBase Multi-Paxos实现原理详解
OceanBase利用Multi-Paxos协议来实现高可用的分布式事务,核心目标是替换传统的主备同步机制,确保在未发生多数派永久性故障的前提下,所有提交成功的数据均可恢复。
🔧 Multi-Paxos在OceanBase中的工作原理
在OceanBase中,事务日志的提交和回放过程是其分布式一致性的核心。整个过程涉及多个步骤的协同,具体流程如下:
-
日志提交
- 事务层调用
log_service->submit_log()接口提交日志。该日志中包含了在成功时需要执行的回调函数指针 (on_succ_cb)。 - 日志模块(CLOG)为这条日志分配一个全局唯一的
log_id和一个提交时间戳 (submit_timestamp)。 - 日志被放入一个滑动窗口,并创建一个新的
log_task。随后,日志会并行执行本地持久化(写盘)和通过RPC同步给其他副本(Follower)。
- 事务层调用
-
达成多数派与确认
- 本地写盘完成:触发
log_service->flush_cb(),更新对应的log_task状态,标记为本地持久化成功。 - Follower写盘完成:Follower在本地写盘成功后,会向Leader回复确认(ACK)。
- Leader收到ACK后,会更新
log_task的确认列表 (ack_list)。 - 关键步骤:Leader在收集本地和Follower的确认时,会实时统计是否已达成多数派(Majority)。一旦满足条件:
- Leader会按顺序调用
log_task->on_success,回调通知事务层提交成功。 - 同时,Leader会发送
confirmed_info消息给所有Follower。 - 最后,将该日志从滑动窗口中滑出。
- Leader会按顺序调用
- 本地写盘完成:触发
-
Follower的回放
- Follower收到Leader的
confirmed_info消息后,会尝试将对应的日志从自己的滑动窗口中滑出。 - 滑出时,Follower会更新本地的回放位点,并将待回放的日志提交到一个全局线程池中进行异步消费。
- 为了保持事务顺序,回放时会根据事务ID (
trans_id) 进行哈希,确保同一个事务的所有日志被分配到同一个队列中串行回放。
- Follower收到Leader的
📊 Multi-Paxos与Multi-Raft的关键区别
虽然都与分布式一致性有关,但OceanBase采用的Multi-Paxos与常见的Multi-Raft在设计和优势上有显著不同:
| 特性维度 | OceanBase Multi-Paxos | Multi-Raft | 对性能的影响 |
|---|---|---|---|
| “Multi”的含义 | 指一次提案(Proposal)可以提交多个日志值。 | 指管理多个独立的Raft组。 | 设计目标不同。 |
| 日志提交顺序 | 允许乱序提交和空洞。只要多数派确认即可推进,不要求严格连续。 | 要求日志索引严格连续递增,不允许有空缺。 | Paxos在网络延迟稍大(如跨城机房)时性能优势更明显。 |
| 数据一致性模型 | 通过滑动窗口、按顺序回调等方式,在乱序确认后最终达成一致顺序。 | 强依赖Leader串行处理和日志的连续复制。 |
简单来说,Multi-Paxos通过允许日志空洞、乱序确认来换取更高的吞吐和更低的延迟,尤其在跨地域部署场景下;而Raft则通过严格的顺序性来简化实现和理解。
💎 核心总结
总的来说,OceanBase对Multi-Paxos的工程实现,是在保证分布式系统强一致性和高可靠性的前提下,为追求极致性能而做的优化。它通过滑动窗口管理、异步并行化I/O(本地写盘与网络同步同时进行)以及智能的回放机制,充分发挥了Paxos协议在乱序提交上的理论优势。
浙公网安备 33010602011771号