阿里如何实现高性能分布式强一致的独立 Paxos 基础库?
Paxos 从理论界到工业界,阿里怎样实现分布式系统的一致性?
近来 Paxos 的分享和讨论越来越频繁,它是分布式系统保持一致性的法宝,但是同时又有着最难理解的算法之“美誉”。在阿里看来,虽然 Paxos 有一定社区热度,但是真正工业级的应用仍属少数。“X-Paxos”是阿里巴巴数据库团队面向高性能、全球部署以及阿里业务特征等需求,实现的一个高性能分布式强一致的 Paxos 独立基础库。不过 X-Paxos 并不是终点,阿里在乎的是基于 X-Paxos 的 AliSQL X-Cluster。那么 X-Paxos 是有怎样的技术参数?其技术架构、功能和性能是怎样的?杀手锏 X-Paxos 怎么帮助到 AliSQL X-Cluster?
分布式一致性协议(Consensus Protocol)是分布式计算的基石,用来保证分布式系统中各节点的状态一致,而 Paxos 就是一种分布式一致性协议。
Chubby 的作者 Mike Burrows 在论文中说过“there is only one consensus protocol, and that’s Paxos”。这话虽然有点绝对,但是不无道理。现在的 Paxos 不单是指 Leslie Lamport 最初论文中提出的 Basic Paxos 或者 Multi Paxos,还泛指大量变种的 Paxos,例如 Cheap Paxos、Fast Paxos、Mecius、EPaxos 等;以及各种类 Paxos 的一致性协议,例如 Raft、ZAB、Viewstamped Replication。这些分布式一致性协议从本质上来说,都是相通的。大致上都包含了 冲突处理 / 选主、Quorum、Recovery、成员变更等技术组成,不同的 Paxos 其组成也各有差别,但是其本质上都是一样的。在深入调研了广泛的 Paxos 变种和类 Paxos 协议的基础上,结合整体架构和设计目标,设计或继承了 Paxos 中的各个技术组成,完成了阿里针对高性能、全球部署的 X-Paxos 分布式强一致协议。
Paxos 的理论提出已经 17 年了,工业界第一个实现也已经 11 年了。近几年,顶级会议、业内文章中有越来越多 Paxos 的讨论。Google 并没有开源其任何 Paxos 基础库(连包含 Paxos 的项目都没有 开源过); Facebook 也没有公布过包含 Paxos 的产品 ; Apache 有 Zookeeper,但是其协议并不能支持 一个高吞吐的状态机复制,且并没有提供独立的第三方库,可供快速接入。在 Github 上能找到的 Paxos 的独立库,star 最高的是腾讯于去年开源的 PhxPaxos;但是阿里依然认为,止业内还鲜有真正成熟的工业级基础类库。
工业级的 Paxos 意味着什么?首先,必须针对高吞吐、高延迟等工业级要求做针对性的架构设计和优化;其次,必须针对各种可能存在的网络分区 / 闪断 / 丢包、硬件异常、节点 Crash 等做完善的设计,理论的论证及系统的测试;最后,必须在大规模的线上部署,并经过长期的实践运行检验。目前业界满足这些要求的 Paxos 基础库凤毛麟角,同时这些基础库往往是大企业的核心竞争力,不会对外开源;同时 Paxos 往往结合 DB 等使用,也很少以云服务形式对外提供,所以外界很难受益。
在《Paxos made live》就提到:Paxos 从理论到现实世界的实现之间有巨大的鸿沟,在真正实现一个 Paxos 的时候,往往需要对 Paxos 的经典理论做一些扩展,(尤其是在实现一个高性能的 Paxos 的时候,扩展点就更多了,可以参考后文的功能增强和性能优化),这往往会导致真正的 Paxos 实现其实都是基于一个未被完全证明的协议。这也就是传说中,理论证明一个 Paxos 的实现,比实现这个 Paxos 还要难的原因了。
因此一个成熟的 Paxos 实现很难独立产生,往往需要和一个系统结合在一起,通过一个或者多个系统来验证其可靠性和完备性。这也是为什么大部分成熟的 Paxos 案例都是和分布式数据库相结合的,例如最早的 Paxos 实现(Chubby),当前的主要 Paxos 实现(Google 的 MegaStore、Spanner,AWS 的 DynamoDB、S3 等)。而阿里的 X-Paxos 类库也是依托于 AliSQL X-Cluster 验证了其可靠性和完备性。
上面已经提到,工业级的 Paxos,从性能设计,容错设计、实现、测试、规模验证都有非常高的要求。
X-Paxos 从架构设计到最终上线,都做了大量的工作:
针对高吞吐,整个 X-Paxos 都是建立在基于 SEDA 架构的异步多线程框架之上
针对搞延迟,设计了一整套自适应的 Batching 和 Pipelining 机制,保证在延迟提升的情况下,不影响吞吐
X-Paxos 理论和实现都经过了 TLA+、Jepsen 等分布式测试框架的验证,并长时间在自动随机异常系统中进行 24 小时验证
基于 X-Paxos 的 X-Cluster 已经在数千个线上业务集群长时间稳定运行,无异常。
X-Paxos 的整体架构如上图所示,主要可分为网络层、服务层、算法模块、日志模块 4 个部分。
网络层:
网络层基于阿里内部非常成熟的网络库 libeasy 实现。libeasy 的异步框架和线程池非常契合阿里整体异步化设计,此外 X-Paxos 还对 libeasy 的重连等逻辑进行了修改,以适应分布式协议的需求。
服务层:
服务层是驱动整个 Paxos 运行的基础,为 Paxos 提供了事件驱动,定时回调等核心的运行功能,每 一个 Paxos 实现都有一个与之紧密相关的驱动层,驱动层的架构与性能和稳定性密切相关。 X-Paxos 的服务层是一个基于 C++11 特性实现的多线程异步框架。常见的状态机 / 回调模型存在开发效率较低,可读性差等问题,一直被开发者所诟病;而协程又因其单线程的瓶颈,而使其应用场景受到限制。C++11 以后的新版本提供了完美转发(argument forwarding)、可变模板参数(variadic templates)等特性,为实现一种全新的异步调用模型提供了可能。 例如这是 X-Paxos 内实际的一行创建单次定时任务的代码 。
cpp new ThreadTimer(srv_->getThreadTimerService(), srv_, electionTimeout_, ThreadTimer::Oneshot, &Paxos::checkLeaderTransfer, this, targetId, currentTerm_.load(), log_- >getLastLogIndex());
以上一行程序,包含了定时器的创建,任意回调函数的设置,回调函数参数的转发,并保证在回 调触发后(Oneshot)内存的自动回收。同时服务层支持嵌套回调,即在回调函数中再一次生成一 个定时 / 即时任务,实现一个有限次定时循环逻辑。
算法模块:
X-Paxos 当前的算法基于 unique proposer 的 multi-paxos[3] 实现,大量理论和实践已经证明了基于 unique proposer 的 multi-paxos,性能好于 multi-paxos/basic paxos,当前成熟的基于 Paxos 的系统,大部分都采用了这种方式。
算法模块的基础功能部分本文不再重复,感兴趣的读者可以参考相关论文 [1,2,4]。在基础算法的基础上,结合阿里业务的场景以及高性能和生态的需求,X-Paxos 做了很多的创新性的功能和性能的 优化,使其相对于基础的 multi-paxos,功能变的更加丰富,在多种部署场景下性能都有明显的提 升。
日志模块:
日志模块本是算法模块的一部分,但是出于对极致性能要求的考虑,日志模块还是被独立出来,并实现了一个默认的高性能的日志模块;有极致性能以及成本需求的业务场景下,可以结合已有的日志系统,对接日志模块接口,以获取更高的性能和更低的成本。
X-Paxos 在标准 multi-paxos 的基础上,支持在线添加 / 删除多种角色的节点,支持在线快速将 leadership 节点转移到其他节点(有主选举)。
集团及蚂蚁目前的多地有中心的架构,很多应用因其部署的特点,往往要求其在未发生城市级容 灾的情况下,仅在中心写入数据库,或调用其他分布式服务;同时又要求在发生城市级容灾的时 候(同一个城市的多个机房全部不可用),可以完全不丢失任何数据的情况下,将写入点切换到 非中心。
而经典的 multi-paxos 并不能满足这些需求。经典理论中,多数派强同步以后即可完成提交,而多 数派是非特定的,并不能保证某个 / 某些节点一定能得到完整的数据,并激活服务。在实际实现 中,往往地理位置较近的节点会拥有强一致的数据,而地理位置较远的节点,一直处于非强一致 结合广泛的业务场景,构建开放的生态 节点,在容灾的时候永远无法激活为主节点,形同虚设。
同时当中心单节点出现故障需要容灾的时候,往往需要将主节点就近切换到同中心的另外一个节 点;由于应用在多地的部署往往是非对称的原因,才出现单个 region 全挂的时候,写需要将主节点 切到特定的 region 内。这些需求都需要 Paxos 在选主的时候,可以由用户指定规则,而经典理论中 同样没有类似的功能,添加权重也需要保证 Paxos 的正确性。
X-Paxos 在协议中实现了 【策略化多数派】 和【权重化选主】。基于策略化多数派,用户可以通过动态配置, 指定某个 / 某些节点必须保有强一致的数据,在出现容灾需求的时候,可以立即激活为主节点。基于权重化选主,用户可以指定各个节点的选主权重,只有在高权重的节点全部不可用的时候,才会激活低权重的节点。
在经典的 multi-paxos 实现中,一般每个节点都包含了 Proposer/Accepter/Learner 三种功能,每一个 节点都是全功能节点。但是某些情况下并不需要所有节点都拥有全部的功能,例如:
经典的三个副本部署中,可以裁剪其中一个节点的状态机,只保留日志(无数据的纯日志 节点,但是在同步中作为多数派计算),此时需要裁剪掉协议中的 Proposer 功能(被选举 权),保留 Accepter 和 Learner 功能。
我们希望可以有若干个节点可以作为下游,订阅 / 消费协议产生的日志流,而不作为集群的成员 (不作为多数派计算,因为这些节点不保存日志流),此时裁剪掉协议的 Proposer/Accepter 功能,只保留 Learner 功能。
当然还有其他的组合方式,通过对节点角色的定制化组合,还可以开发出很多的定制功能节点。
基于上节节点角色定制化中的单独 Learner 角色的功能,引发了无穷的想象力。Learner 角色,可以抽象成一个数据流订阅者(Witness Node),整个集群中可以加入无数个订阅者,当有新的日志被 提交的时候,这些订阅者会收到其关心的日志流,基于订阅者功能,可以让一个集群很容易的实现下游订阅消费,日志即时备份,配置变更推送等等的功能。
Learner 角色单独封装成了一个 SDK。基于这个 SDK,用户可以快速的为自己的集群添加,订阅注册,流式订阅定功能;结合特定的用途打造一个完成的生态。 例如日志流 SDK 在 AliSQL X-Cluster 中打造的生态:
采用了 X-Paxos 也可以利用 Witness SDK 快速实现分布式系统和下游的其他系统的对接,形成一个完 整的生态。
以 MySQL 的日志(binlog)备份来举例:
普通方案
每隔固定时间 Tb,将 MySQL 生成的 binlog 文件备份到永久备份系统(OSS、S3 等)
RPO (Recovery Point Objective) 为 Tb
SDK 方案
X-Paxos 支持由 SDK 订阅增量日志,备份系统只需要简单的实现从 SDK 流到 OSS 流的对接,即 可实现流式备份
RPO (Recovery Point Objective) 为 0
除备份以外,Witness SDK 在下游流式订阅(DRC)、自封闭高可用系统(X-Driver)、异步只读备 库等方面都有实战案例,更多的应用案例在不断的添加中。
Paxos 除了设计之初的强一致和高可用以外,其高性能也是至关重要的,尤其是应用于 AliSQL X-Cluster 这种高性能分布式数据库的时候,对协议的吞吐,延迟都提出了很高的要求。同时作为可 全球部署的分布式一致性协议,在高延迟下的性能挑战变得尤为重要。
X-Paxos 针对高延迟网络做了大量的协议优化尝试和测试,并结合学术界现有的理论成果 [5,6,7] 通 过合理的 Batching 和 Pipelining,设计并实现了一整套自适应的针对高延迟高吞吐和低延迟高吞吐 网络的通信模式,极大的提升了 X-Paxos 的性能。类似的优化在同类竞品中还非常 的罕见。
Batching:将多个日志合并成单个消息进行发送;Batching 可以有效的降低消息粒度带来的额 外损耗,提升吞吐。但是过大 Batching 容易造成单请求的延迟过大,导致并发请求数过高,继而影 响了吞吐和请求延迟。
Pipelining:是指在上一个消息返回结果以前,并发的发送下一个消息到对应节点的机制,通过提高 并发发送消息数量(Pipelining 数量),可以有效的降低并发单请求延迟,同时在 transmission delay 小于 propagation delay 的时候(高延迟高吞吐网络),有效提升性能。
经推导可知 Batching(消息大小:M)和 Pipeling(消息并发:P)在如下关系下,达到最高吞吐 M/R * P = D
其中 R 为网络带宽,D 为网络传播延迟(propagation delay,约为 RTT/2) X-Paxos 结合以上理论,通过内置探测,针对不同节点的部署延迟,自适应的调整针对每个节点的 Batching 和 Pipeling 参数,达到整体的最大吞吐。
Pipeling 的引入,需要解决日志的乱序问题,特别是在异地场景下,window 加大,加大了乱序的概 率。X-Paxos 实现了一个高效的乱序处理模块,可以对底层日志实现屏蔽乱序问题,实现高效的乱序日志存储。
由于 Paxos 的内部状态复杂,实现高效的单实例多线程的 Paxos 变成一个非常大的挑战。无论上面提到的 github 中 star 最多的 PhxPaxos,还是 Oracle MySQL Group Replication 中使用的 xcom,都是单线程的实现。PhxPaxos 采用了单分区单线程,多实例聚合的方式提升总吞吐,但是对单分区 的性能非常的有限;而 xcom 是一个基于协程的单线程实现。单线程的 Paxos 实现,在处理序列化 / 反序列化,分发、发包等逻辑的时候都为串行执行,性能瓶颈明显。
X-Paxos 完全基于多线程实现,可以在单个分区 Paxos 中完全的使用多线程的能力,所有的任务都有通用的 woker 来运行,消除了 CPU 的瓶颈。依赖于服务层的多线程异步框架和异步网络层,X-Paxos 除了必要的协议串行点外,大部分操作都可以并发执行,并且部分协议串行点采用了无锁设 计,可以有效利用多线程能力,实现了 Paxos 的单分区多线程能力,单分区性能远超竞品,甚至超过了竞品的多分区性能。
基于 unique proposer 的分布式系统的存在的一个瓶颈点就是主节点是唯一的内容输出源,当集群 存在大量节点的时候,主节点的大量网络收发工作会导致主节点的负载过大,引发 CPU 和带宽的瓶颈;在全国 / 全球部署的时候,所有节点和主节点之间的直接通信会造成跨 region 之间的长传 / 国际 链路的带宽占用过大。
X-Paxos 是旨在解决全球分布式强一致问题的 Paxos 独立库,在设计之初就考虑到了这个问题。X-Paxos 在稳态运行时会感知各个节点之间的网络延迟(物理距离),并形成级联拓扑,有效降低主 节点的负载,降低长传链路的带宽使用;而在有节点异常的时候,又会自动重组拓扑,保证各个 存活节点间的同行的正常进行。同时 X-Paxos 支持有业务来设定重组拓扑的规则,业务可以根据自 己 APP 的部署架构和延迟特性来针对性的设置拓扑重组规则。
X-Paxos 和现有的大部分 paxos 库很大的不同点就是 X-Paxos 支持可插拔的日志模块。日志模块是 Paxos 中一个重要的模块,它的持久化关系到数据的一致性,它的读写性能很大程度上会影响协议 整体的读写性能。当前大部分独立 Paxos 库都是内置日志模块,并且不支持插拔的。这会带来两个弊端:
默认的日志模块提供通用的功能,很难结合具体的系统做针对性的优化
现有的系统往往已经存在了 WAL(Write Ahead Log), 而 Paxos 协议中需要再存一份。这使得 a) 单次 commit 本地需要 sync 2 次(影响性能);b) 双份日志浪费了大量的存储
例如:PhxPaxos 内置的日志模块采用 LevelDB,作为日志系统其操作大量冗余,无针对优化,性能 堪忧;同时采用 PhxPaxos 的 phxsql 单节点需要即保存 binlog,又保存 Paxos log(在独立的 phxbinlogsvr 中),严重影响了性能,浪费了存储空间。而采用 X-Paxos 的 AliSQL X-Cluster 直接改造 了现有的 binlog 模块,对接到 X-Paxos 的日志模块,单节点仅一份日志,即降低了存储,又提高了性能。
X-Paxos 的核心武器有两点: 高性能;全球部署能力。
在高性能方面:
服务层实现了一整套基于 SEDA 架构和 C++ 11/14 特性的多线程异步调度服务。
基于高性能的服务层,将整个 X-Paxos 的流程进行完全的异步化,消除 IO(网络 / 磁盘)和临界资源引发的线程调度,提高 CPU 执行效率
服务层实现了同类任务自动合并和同类任务线程亲和,降低了任务指令数,同时提升了 CPU 指令缓存(icache)命中率,从而提升 IPC
在 Paxos 实现上引入了大量无锁操作,提升并发能力
在全球部署方面:
X-Paxos 在架构设计上支持 Batching 和 Pipelining,并且支持动态调整;同时从理论上结合了网络通信的最佳效率模型,针对不同距离的节点,自适应的调整每个节点间的通信模型,保证最高的通信效率。
从而使得 X-Paxos 无论是在小范围部署还是在跨 Region 或者全球部署中都保持高吞吐当然 X-Paxos 还有很多其他的优势,例如插件日志、丰富的定制角色、LACD 等,都是非常领先的。
理论上来说网络延迟其实是不影响吞吐的,但是现实的强一致系统中,往往在网络延迟增加的情况下,会导致吞吐的急剧下降呢?究其原因,是在于现实中的系统,往往在内部调用或者是网络通信上存在同步点,或者说不能完全的 scale out。
例如从阿里的测试来看 MySQL Group Replication 在网络延迟从 0.1ms 上升到 30ms 的时候,吞吐下降到原来的 1/4,而 PhxPaxos 在同样的网络延迟上升情况下,吞吐下降到原来的 1/30。从公开资料和源码可以看到,MySQL Group Replication 核心的 Paxos 库 xcom,只支持固定的 10 条 pipelining;而 PhxPaxos 不支持 pipelining,可想而知。
X-Paxos 实现了完全动态的 pipelining,可以动态任意的调节 pipelining 数量;同时 X-Paxos 基于网络最优化理论和每个节点间的网络延迟不同,可以自适应的独立调整每个节点的 pipelining 数量,以及 batching 大小,从而使得 X-Paxos 在网络延迟从 0.1ms 上升到 30ms 的时候,其吞吐完全没有下降。
我们的愿景是希望能够提供一个经过实践检验的,高度成熟可靠的独立 Paxos 基础库。使得一个后 端服务能够通过简单的接入,就能拥有 Paxos 算法赋予的强一致、高可用、自动容灾等能力。真正将晦涩难懂的 Paxos,变得平易近人,带入千万家。——江疑
单纯的 X-Paxos 并不是终点,它是阿里巴巴分布式数据库 AliSQL X-Cluster 的前期铺垫工作。如上文提到 Paxos 是分布式系统的基石,用于解决分布式系统中的一致性问题。
X-Cluster 是第一个接入 X-Paxos 生态的重要产品,利用了 X-Paxos 实现了自动选主、日志同步、集群内数据强一致,在线集群配置变更等功能。AliSQL X-Cluster 替换了原有的复制机制。整体的复制、回放、提交、恢复都整合了 Paxos 逻辑,并且针对 WAN 部署做了针对性的优化。
同时 X-CLuster 基于 MySQL 生态,兼容最新版本的 MySQL 5.7,集成 AliSQL。 MySQL 的用户可以零成本迁移到 X-Cluster 上。
上图展示的是一个部署三个实例的 Cluster 集群。X-Cluster 是一个单点写入,多点可读的集群系统。在同一时刻,整个集群中至多会有一个 Leader 节点 来承担数据写入的任务。相比多点写入,单点写入不需要处理数据集冲突的问题,可以达到更好的性能与吞吐率。
X-Cluster 的每个实例都是一个单进程的系统,X-Paxos 被深度整合到了数据库内核之中,替换了原有的复制模块。集群节点之间的增量数据同步完全 是通过 X-Paxos 来自驱动,如何复制,从哪个点回放不再需要运维人员或者外部工具来介入。 X-Cluster 利用 MySQL 的 Binlog 进 行深度改造和定制来作为 X-Paxos 的 Consensus 日志,实现了一系列的 X-Paxos 日志接口,赋予 X-Paxos 直接操纵 MySQL 日志的能力。
为了保证集群数据的一致性以及全球部署的能力,在事务提交、日志复制回放以及恢复上 X-Cluster 都进行了重新设计。
X-Cluster 的复制流程是基于 X-Paxos 驱动 Consensus 日志进行复制。
Leader 节点在事务 prepare 阶段会将事务产生的日志收集起来,传递给 X-Paxos 协议层后进入等待。X-Paxos 协议层会将 Consensus 日志高效地转发给 集群内其他节点。当日志在超过集群半数实例上落盘后 X-Paxos 会通知事务可以进入提交步骤。否则如果期间发生 Leader 变更,期间 prepare 的事务会 根据 Paxos 日志的状态进行相应的回滚操作。相比原生 MySQL,日志传输采用了多线程、异步化、Batching、Pipelining 等优化手段,特别是在长传链 路的场景中,效率提升明显。
Follower 节点也使用 X-Paxos 进行日志的管理操作,为提升接收效率,收到 Leader 传递过来的日志以后将日志内容 Append 到 Consensus Log 末尾,Leader 会异步的将达成多数派的日志的消息发送给 Follower,Follower 的协调者线程会负责读取达成多数派的日志并加以解析,并传递给各个回放 工作线程进行并发的数据更新。 Follower 的并发回放可以有多种方式,包括按照 Leader 上的 Group Commit 维度或者是按照表级别的维度,未来会引入 最新的 writeset 方式来精确控制最大并发。
X-Cluster 只要半数以上的节点存活就能保证集群正常对外服务。 因此当少数的 follower 节点故障时并不影响集群的服务能力。当 Leader 节点故障时会 自动触发集群的重新选主流程。 选主流程由 X-Paxos 驱动,在 Paxos 协议的基础上,结合优先级推选出新的 Leader 节点。
对于 X-Cluster 而言,failovertime = electiontime + apply_time electiontime 代表协议选主的时间,一般在 10s 左右, applytime 是数据应用日志的时间,取决于回放的速度,优秀的并行回放算法能把应用日志的时间 控制在非常短的时间之内。
相对来说之下 Leader 节点故障是一个相对复杂的场景,故障包括了宕机、网络隔离等等。
如上图所示,一个经典的三节点的 X-Cluster 集群,左边的 Case 是原 Leader A 节点宕机,因此 B 节点和 C 节点会在较长的时间内收不到 Leader 的心跳,因此在 一个选举超时周期后,B 节点开始尝试推选自己为 Leader, 并且 C 节点同意, 那么 B 成为新的主节点,恢复服务能力。
右边的 Case 是原 Leader A 节点发生网络分区,此时在选举超时后,BC 两个节点的行为和之间的 Case 类似。 A 节点由于无法将心跳和日志发送给 BC 两个节点在超时后会降级,然后不断尝试选自己为 Leader,但是因为没有其他节点的同意,达不成多数派,一直都不会成功。当网络分区恢复后,A 收到 B 节点的心跳,触发 Leader stickness 机制,A 节点加回集群。
在传统的 Master-Slave 下数据一致性和可用性是很难同时保证的,并且很容易在网络分区时产生脑裂的问题。过去,DBA 们更多的使用的是回滚回补方式来尽量保证节点数据的一致性,但是对于用户来说,更新丢失,stall read 这样的问题很难避免。 Paxos 和类 Paxos 协议是目前已经论证的解决分布式一致性问题最好的手段。曾经很多开发者使用 Zookeeper 或者 etcd 这样的提供一致性能力的组件来做 Master-Slave 的仲裁。这样的方式能避免脑裂,但是依然无法解决上述数据回滚回补以及用户可能会遇到的不一致问题。
这两年,有开发者尝试将协议和数据库做深度整合。 目前市面上开源的 Paxos 协议库多是一体化的日志 / 状态机 / 协议 实现,这样协议库要记录一份状态机、日志,数据库要维护一份数据和日志,对于整体系统来说是冗余和低效的。X-Paxos 有插件化的状态机和日志实现,提供了一种更为高效的接入方式。除此之外 X-Paxos 本身对于 WAN 下的传输同步效率是很高的,这也给 X-Cluster 在跨域部署下的性能打下了良好的基础。
阿里希望的是高性能、低成本、能提供数据强一致能力,可以承担阿里巴巴巨大体量电商系统业务的数据库系统。
X-Cluter、Galera、Group Replication 三种方案相比而言:Galera 是先驱,然而从实现原理以及目前的表现上上无法支持阿里的目标。GR 是官方出品但 GA 时日尚短,这两个开源的产品在功能和性能上在实测评估中无法满足阿里的要求。
这三者之间是有明显的相同点和不同点的。这三个产品都是为了解决数据强一致问题的基于 MySQL 的高可用解决方案。都是通过类 binlog event 的方式进行复制,同样只支持事务引擎,failover 对于运维友好。
然而他们之间的不同点也是非常多了。首先是从同步协议上,Galera 采用的是 Totem 算法,而 GR 和 X-Cluster 是采用的 Paxos,因此 Galera 需要每个节点都接受 writeset 后才能提交,而 GR 和 X-Cluster 一样采用多数派 ack 即可提交的方式。Galera 和 GR 支持多点写入(虽然冲突严重很容易导致事务失败)而 X-Cluster 是单点写入系统。Galera 和 X-Cluster 是明确支持 WAN 部署的,而 GR 在 WAN 下则是不被推荐的。Galera 和 GR 都是 All nodes have all data 系统, X-Cluster 还提供低成本的 node have no data 的选项。GR 支持最多 9 个节点,X-Cluster 支持 99 个一致性节点而 Galera 支持的更多的节点(虽然意义不大)。
运维方面:Galera 和 X-Cluster 支持分区节点自动恢复而 GR 需要手动运维;
性能方面:Galera 集群性能取决于最慢的节点,这不满足对于低延时、异地容灾部署的需求。
而且,Galera 的同步使用 GCache,而不是 binlog,这对于已有的外部配套系统不是很友好,如果同时又开启 binlog 的话会额外付出存储和 IO 的代价。GR 对于分区的运维不够友好,被隔离的节点无法自动加回集群, 在 WAN 下表现一般,官方也不推荐在这种网络环境下的部署。 X-Cluster 继承了 AliSQL 的优势,又特别优化了 WAN 下的性能。对于同一行数据更新,相比 Galera 和 GR 的表现,而 X-Cluster 的性能完全满足阿里的预期,这在类似于秒杀的场景下会非常有用。除此之外,X-Cluster 继承于 AliSQL,因此除了支持 InnoDB 引擎之外还支持 Rocksdb 引擎,可以有效的优化存储成本。
阿里还进行了 AliSQL X-Cluster 性能表现的测试,测试使用了三节点部署方式,分别在同城三机房、跨城三机房的网络环境下进行了测试,测试工具使用标准的 Sysbench 的 insert/oltp。
Insert 测试下,并且每个事务中只包含一条插入语句,属于密集的小事务场景, 而相反的 OLTP 是读写大事务。 针对热点环境,测试的场景是改造update_nonindex , 使更新同一行数据。 只读场景不在本次测试的范畴内,原因是只读不涉及到节点的日志、数据同步,因此可以认为只读测试对分布式系统是没有意义的。
Sysbench 主要是针对写以及读写混合场景下的测试,数据量为 10 张表,每张表 20 万记录。测试同域下的集群,Insert 使用 300 并发线程、 OLTP 使用 400 并发线程, 热点更新使用 300 并发线程。
备注:最新的单机版 MySQL 5.7.19 以及该版本下的 Group Replication。Group Replication 在测试中关闭限流,测试机均是 64core 512G 内存 PCIE SSD。
江疑,10+ 年 Linux C/C++ 底层研发经验,数据库内核研发经验。长期从事 MySQL 内核研发,分布式数据库研发工作。同时作为数据库内核负责人多次参加阿里巴巴双十一购物节。AliSQL 项目主要开发人员,主导阿里的分布式强一致协议 X-Paxos 开发工作。
胡炜,2016 年加入阿里巴巴,数据库技术团队 AliSQL 内核贡献者,X-Cluster 的核心开发成员。毕业于浙江大学,专攻数据库方向。从业以来一直深耕于数据库领域,擅长 RDBMS, NOSQL 等技术方向。