Paxos 在选主的时候,可以由用户指定规则(权重),最好就近选择(强一致性)
Zookeeper不能支持一个高吞吐的状态机复制,且并没有提供独立的第三方库
X-Paxos:有主选举、策略和权重选主、可插拔的日志模块、节点角色定制化、Witness SDK
X-Paxos 是阿里巴巴数据库团队面向高性能、全球部署以及阿里业务特征等需求,实现的一个高性能分布式强一致的 Paxos 独立基础库。
一、X-Paxos 的整体架构
X-Paxos 的整体架构如下图所示,主要可分为网络层、服务层、算法模块、日志模块四个部分:

网络层
网络层基于阿里内部非常成熟的网络库 libeasy 实现。libeasy 的异步框架和线程池非常契合整体的异步化设计,同时我们对 libeasy 的重连等逻辑进行了修改,以适应分布式协议的需求。
服务层
X-Paxos 的服务层是一个基于 C++11 特性实现的多线程异步框架。
算法模块
基于 unique proposer 的 multi-paxos性能好于 multi-paxos/basic paxos。
日志模块
日志模块独立出来,并实现了一个默认的高性能的日志模块。
二、X-Paxos 的功能增强
1. 在线添加/删除节点,在线转让 leader
X-Paxos 在标准 multi-paxos 的基础上,支持在线添加/删除多种角色的节点,支持在线快速将 leadership 节点转移到其他节点(有主选举)。
2. 策略化多数派和权重化选主
在实际实现中,往往地理位置较近的节点会拥有强一致的数据,而地理位置较远的节点,一直处于非强一致节点,在容灾的时候永远无法激活为主节点。
基于策略化多数派,用户可以通过动态配置,指定某个/某些节点必须保有强一致的数据,在出现容灾需求的时候,可以立即激活为主节点。
基于权重化选主,用户可以指定各个节点的选主权重,只有在高权重的节点全部不可用的时候,才会激活低权重的节点。
3.节点角色定制化

4. Witness SDK
Learner 角色,可以抽象成一个数据流订阅者(Witness Node),整个集群中可以加入无数个订阅者,当有新的日志被提交的时候,这些订阅者会收到他关心的日志流。可以让一个集群很容易的实现下游订阅消费、日志即时备份、配置变更推送等的功能。
因此我们把 Learner 角色单独封装成了一个 SDK。基于这个 SDK,用户可以快速地为自己的集群添加、订阅注册、流式订阅功能。

三、X-Paxos 的性能优化
3.1 Batching & Pipelining
Batching 是指将多个日志合并成单个消息进行发送;Batching 可以有效的降低消息粒度带来的额外损耗,提升吞吐。但是过大 Batching 容易造成单请求的延迟过大,导致并发请求数过高,继而影响了吞吐和请求延迟。
Pipelining 是指在上一个消息返回结果以前,并发的发送下一个消息到对应节点的机制,通过提高并发发送消息数量(Pipelining 数量),可以有效的降低并发单请求延迟。
X-Paxos 通过内置探测,针对不同节点的部署延迟,自适应的调整针对每个节点的 Batching 和 Pipeling 参数,达到整体的最大吞吐。
Pipeling 的引入需要解决日志的乱序问题,特别是在异地场景下,window 加大,加大了乱序的概率。X-Paxos 通过一个高效的乱序处理模块,可以对底层日志实现屏蔽乱序,实现高效的乱序日志存储。
3.2 多线程,全异步的 Paxos 库
X-Paxos 是完全基于多线程实现的,可以在单个分区 Paxos 中完全的使用多线程的能力,所有的任务都有通用的 woker 来运行,消除了 CPU 的瓶颈。
其依赖于服务层的多线程异步框架和异步网络层,X-Paxos 除了必要的协议串行点外,大部分操作都可以并发执行,并且部分协议串行点采用了无锁设计,可以有效利用多线程能力,实现了 Paxos 的单分区多线程能力。
3.3 Locality Aware Content Distribution
X-Paxos 在稳态运行时会感知各个节点之间的网络延迟(物理距离),并形成级联拓扑,有效降低主节点的负载,降低长传链路的带宽使用;而在有节点异常的时候,又会自动重组拓扑,保证各个存活节点间的同行的正常进行。
同时 X-Paxos 支持由业务来设定重组拓扑的规则,业务可以根据自己 APP 的部署架构和延迟特性来针对性的设置拓扑重组规则。

3.4 可插拔日志
当前大部分独立 Paxos 库都是内置日志模块,并且不支持插拔的。这会带来两个弊端:
1、默认的日志模块提供通用的功能,很难结合具体的系统做针对性的优化。
2、现有的系统往往已经存在了 WAL(Write Ahead Log),而 Paxos 协议中需要再存一份。这使得 a)单次 commit 本地需要 sync 2 次(影响性能);b)双份日志浪费了大量的存储。