翻过三座大山:MatrixOne 从 NewSQL 到 HTAP 分布式架构演进
作者:张潇 MO 产品架构师
导读
最近的几年中,HTAP 数据库成为了一个时髦词汇,言必称 HTAP 也成了很多数据库领域从业者的风潮。如何打造一款 HTAP 数据库,从架构层面出发,去应对未来的变化,拥抱变化,也是很多数据库公司所一直在探索的。
MatrixOne 是矩阵起源(MatrixOrigin)开源的一款超融合 HTAP 云原生数据库,与业内诸多数据库产品非常不同的点是,MatrixOne 的自研之路是从第一行代码开始的。MO 的目标是打造一款极简、高扩展性、高灵活性、高性价比的全新数据库。
在过去的两年里,MatrixOne 经历了一次架构的演进,更具有实验性质的旧架构到面向未来的新架构,成为了诸多数据库开发工程师与运维工程师的关注点,他们经历怎样的架构演进,这中间又有哪些值得借鉴的内容,将在本文中为大家一一揭晓。
Part 1 早期架构的千层糕
MatrixOne 作为一款开源分布式架构的数据库,已有接近 2 年的生命历程。我相信有很多社区老用户,会对早期架构时 SSB 测试的高性能留有印象。而到了 0.5 版本发布之后,性能突然就大幅下滑。当时就有朋友问我,怎么还越做越回去了?我对他说,有个大动作,整个架构做了一个大规模的升级。
此时此刻,我觉得很有必要,对整个架构的演进升级,做一个完整的阐述。
如何界定 MatrixOne 的早期架构?明确地说,是指 MatrixOne 从 0.1 到 0.4 版本的架构,也是在 2022 年上半年之前,在各类推送中出现的那个架构。与其说这是一个架构,更不如说,这是一场实验,通过一个架构,去探索出各种架构的不足,找到真正适合于与原生的 HTAP 分布式架构。
这个实验的旧架构,有两个显著的特征:NewSQL 与 MPP。前者是基于 Google 当年的几篇经典论文所衍生出的,也是今天很多数据库产品的总思路。后者 MPP,顾名思义,大规模并行处理,并行计算是它们的显著特点。落地到 MatrixOne 的早期架构,又有了更具体的含义。
NewSQL
分布式架构:多节点的分布式数据库服务器,每一台服务器既包含了计算资源,又有各自的存储节点,解决了传统单机数据库伸缩性和高可用问题。
多引擎:数据库服务器中可能存在多个存储引擎,不同的引擎特性不同,负责不同的场景。
MPP
并行计算:将任务并行地分散到多个服务器和节点上,在每个节点上计算完成后,将各自部分的结果汇总在一起得到最终的结果。
1.1 早期架构详解
进一步拆解,将视角拉到 MatrixOne Server 内部,它又有着多个模块,分工协同,完成整个分布式数据库的功能。一共分为 5 个部分,前端、计算层、分布式框架、存储层、元数据层。五个部分各自的功能与特性又各有不同。
SQL Frontend
亦称 SQL 前端,是直接处理 SQL 语句的部分,它提供了如下功能:
提供 MySQL 兼容协议,确保 MySQL 的各类协议能够被 MatrixOne 接收;
兼容 MySQL 的语法,对接收的 SQL 做符合 MySQL 的语法判断。
Query Parser
是 MatrixOne 中对语法解析的功能模块,它提供了如下功能:
SQL 解析,对前端的 SQL 并转化抽象语法树;
方言支持,提供支持多种 SQL 方言基础。
MPP SQL Execution
是实现 MPP 的 SQL 执行器,它提供了如下功能:
SQL 加速,对 SQL 计算引擎的一些基础操作的向量化加速,部分操作采用汇编改写做加速;
Plan 构建,使用独有的因子化加速能力做 SQL 的 Plan 构建。
分布式框架
早期 MatrixOne 的分布式框架叫做 MatrixCube,同样是一个开源项目,它具备了如下组件与功能:
提供高可用、多副本、强一致与自动负载均衡;
提供分布式事务的支持能力(WIP);
提供基于 Raft 的副本调度机制,该调度器在代码中称为 Prophet。
存储层
早期的 MatrixOne 存储层是一个拥有多个引擎的架构,多种存储引擎互相分工协作,共同完成 HTAP 数据库功能:
AOE 引擎,Append Only Engine,这是一个 Append Only 的列存引擎,不支持事务;
TPE 引擎,Transaction Processing Engine,用于保存元数据 Catalog;
TAE 引擎,Transactional Analytical Engine,基于列存的 HTAP 引擎,会提供完整 ACID 能力及强大的 OLAP 能力。
元数据层是一个在早期 MatrixOne 架构中被每个其他模块都频繁调用的内容,保存在 TPE 引擎中,提供了全局的元数据的保存与读取,是一个频繁使用的模块。
1.2 早期架构,何以不足?
作为一个早期的架构,更多的是承载了研发团队早期的探索和研究,通过实验架构,逐步探索出一条面向未来的架构。随着开发进度的不断推进,毫无意外地,旧架构的问题开始凸显出来,并且随着功能与性能的提升,愈发成为后续发展的桎梏,集中在三个方面爆发:
拓展性
Share nothing 架构,每扩展 1 单位节点,需同时扩展存算资源;
每份数据至少要保存 3 副本,从扩展节点到完成,时间更久.
性能
Raft 协议所包含的 leader 角色,容易造成热点;
在性能较差的存储下,数据库整体性能下降会超过预期;
多种引擎各自用途不同,性能各异,无法有效应对 HTAP 场景。
成本
数据保存 3 副本,随节点规模,成本不断攀升,云上版本更甚;
只有高配存储才能发挥数据库的预期性能。
这三大难题不得不令 MatrixOne 团队去思考,到底什么样的架构才能满足未来 HTAP 的需求,让云用户与私有化客户,获得最佳产品体验与最佳实践。如同很多破而后立的故事的开端,此时此刻恰如彼时彼刻,由 CTO 田丰博士引领,MatrixOne 团队开始了架构的升级之路。
Part 2 三座大山,推倒重来
三大难题是旧的实验架构的表象,如果仅仅根据表象去解决问题,无疑只能做到知其然而不知其所以然。更深层次的原因,仍然需要去被挖掘与确认,经过 MatirxOne 研发团队的反复的假设与论证后,旧架构不足的根因,归结为三个大问题,这是压在 MatrixOne 之上的三座大山,如同幽灵一般,在每个 MOer 的头上盘旋
2.1 分布式框架
MatrixCube 作为当时的分布式框架,提供了多副本存储模式,每一份数据都保存 3 副本并且以分片(shard)形式保存,使得存储的成本飙升。
而基于 Raft 选举的 Leader 节点,频繁成为了热点,各类操作都需要通过 Leader 节点进行分发,在极端业务场景下,Leader 节点的负载会数倍于普通节点
2.2 引擎众多
早期的 MatrixOne 内置了三种存储引擎,三个引擎之间代码复用率较低,使得对功能的维护需要投入更多人力。
而基于因子化算法的 Plan 构建方式过于激进和抽象,在计算组内部对其完全理解的程序员数量有限,往往添加功能时仍旧需要主开一人完成,新功能添加缓慢。
2.3 资源分配
旧架构采用了存算不分离的架构,这个架构导致了扩展性较差。每扩展一个单位的计算节点必须同步扩展存储资源。
由于存储采用了 shard 分片,使得在 shard 较大时影响了 OLTP 的性能,在 shard 较小时,又会影响 OLAP 性能。
在找到了三座大山之后,接下来要做的事情就是一一扳倒它们,田丰博士结合 MatrixOne 的产品愿景以及未来的技术趋势,对于实验架构进行了总结,并提出了 MatrixOne 独有的架构设想,从整个架构的现状来看,要分三步走:
第一步,将旧架构 share nothing 的框架破除,完成更灵活的解耦;
第二步,将多种引擎合二归一,实现内部引擎的大一统;
第三部,重构计算引擎,留有足够的空间给未来的产品发展。
Part 3 重生后的 MatrixOne
新架构通过解耦,最终实现了三个各自独立的层级,每个层级有自己的对象单元与分工,不同类型的节点可以灵活伸缩,不再受到其他层的制约:
计算层 ,以计算节点 Compute Node 为单位,实现了计算和事务处理的 Serverless 化,又有自己的 Cache,可以实现任意重启与扩缩容;
事务层 ,以数据库节点 Database Node 为与日志节点 Log Service 为单位,提供完整的日志服务以及元数据信息,内置 Logtail 用于保存最近数据;
存储层 ,全量数据保存在以 S3 为代表的对象存储中,实现了低成本的无线伸缩存储方式,以 File Service 命名的统一文件操作服务,实现了不同节点对底层存储的无感知操作。
在确定了以 TAE 作为唯一存储引擎之后,对融合后的 TAE 引擎又做了诸多设计上的调整,才有了后来融合后的 TAE 存储引擎。完成了单一引擎完成所有数据库存储行为的目标,并且具备了如下优势:
列存管理 ,统一的列存与压缩,对于 OLAP 业务有着先天的性能优势;
事务处理 ,共享日志与 DN 节点共同完成对计算节点的事务支持;
冷热分离 ,使用 File Service 以 S3 对象存储作为目标,每个计算节点都有自己的 Cache。
多次运行测试,得出置信度较高的结果:
早期的计算引擎中,兼容 MySQL 的大目标没有变化,但是对于节点调度、执行计划、SQL 能力又有着更高的要求。重构后的高性能计算引擎,既具备了实验架构中计算引擎的 MPP,又弥补了过去的诸多不足:
兼容 MySQL ,既有对 MySQL 协议的支持,又包含了对 MySQL 语法的支持;
融合引擎 ,基于 DAG 重新构建执行计划,可以同时执行 TP 和 AP;
节点调度 ,未来可支持自适应节点内和节点间调度,同时满足并发和并行执行;
完善 SQL 能力,支持子查询、窗口函数、CTE、Spill 内存溢出处理等。
Part 4 三座大山,推倒重来
回顾历时数月的架构升级之路,充满了各种辛酸和痛苦。无论考虑的多么充分,在实际开发中,总会遇到各种各样意想不到的问题出现,尤其是在一些关键问题上的困难,让研发团队从开始的一筹莫展,到偶尔的灵光乍现,再到很后面的零之曙光,走向最终的黎明时刻。个中三昧,不言而喻。
这些难题中,主要围绕在存储、事务、负载隔离与资源配比几个方面。
4.1 寻找更合适的存储
在意识到三副本存储带来的问题后,如何寻找一个新的存储适配新架构,成为了当时一大难题,而这个新的存储必须满足两个核心需求,低成本与冷热数据分离。
在对市面上的诸多存储进行了调研以及试验之后,AWS S3 成为了最终的选择。单一副本,自带的冷热数据分离。
4.2 事务分工的调整
最初的新架构中,计算节点 CN 与数据库节点 DN 之间的分工是 CN 负责计算,计算结果推给 DN,由 DN 完成事务。随着开发进度的不断推进,这个分工开始出现了问题,DN 对事务的处理能力成为整个系统的瓶颈。因此,对于 CN 和 DN 的分工,必须做重新定义:
CN 负责所有的计算以及事务逻辑,DN 负责保存元数据信息、日志信息以及事务裁决,DN 不再成为瓶颈;
在日志中引入 Logtail 对象,用于保存最近日志中的关联数据,定期将 Logtail 的数据写入 S3 中,CN 扩容可以实时将 Logtail 数据同步至 Cache,实现了部分数据共享;
为事务大小设置阈值,超过阈值上限的事务直接写 S3,日志只保存记录写入记录,未超过阈值的事务继续由 DN 写入,极大增加了吞吐量。
4.3 实现 HTAP 的工作负载隔离
作为 HTAP 数据库,如何实现不同类型的工作负载隔离,是一个必须解决的问题。在完成了对旧的实验架构的灵活解耦之后,工作负载的隔离也得以实现:
服务器级别的隔离,硬件资源充裕的情况下,各个组件分别在不同的物理机运行,接入同一个对象存储;
容器级别的隔离,硬件资源有限的情况下,利用所有节点无状态的特性,以容器作为各个节点的隔离手段。
4.4 实现资源配比的灵活调整
作为 HTAP 数据库,日常业务中,不同业务场景的比例是在动态变化中,对于资源的配比也有着更高的要求,而旧架构下的资源分配模式注定无法实现灵活调整,需要对各个节点实现更加精细化的管理,包含但不限于:
CN 节点的分工,允许用户对 CN 进行划分,用于 TP 或 AP 业务,其中某项业务资源出现瓶颈之后,对 CN 进行水平扩容;
在不类业务的 CN 组之间,动态判断各组的负载情况,当前两类业务的负载差异较大时,可以自动将闲置资源分配至繁忙组内;
通过租户(account)的逻辑概念,实现逻辑资源的完全隔离,不同的租户可以以独享或共享的方式使用指定的 CN 资源。
Part 5 复盘收获
在诸多问题得以解决的背后,是众多 MOer 一次次发起的攻坚,在阵痛之后,也收获了很多过去不曾涉足过的知识与经验。这些不仅仅是解决问题的积累,同样也为今后 MatrixOne 的开发积累了一比宝贵的财富。
为此我从解耦之后的三层架构角度,对相关几位同事做了访谈,在倾听了他们对问题的回顾与思考之后,做出了如下的反馈:
计算层
理解 SQL 的执行,通过重构 Plan,对于 SQL 语法的解析、执行计划以及 SQL 标准语法都有了更多认识;
事务与 ACID,专注于单一引擎之后,几乎每一条 SQL 都要考虑事务与 ACID,需要对这些有更深的理解。
事务层
CN 与 DN 的适配,从架构升级开始,CN 与 DN 的分工与适配成为了巨大难题,反复验证中得到了最优解;
部分数据共享,Logtail 的引入,实现了某一部分数据在不同 CN 之间共享。
存储层
使用 S3 存储,积累了基于 S3 等对象存储的引擎开发经验,原来对象存储也可以很好地适配数据库;
Fileservice,一种存储服务,去实现不同节点不同底层存储类型的读写,是个极大的挑战。
Part 6 总结
矩阵起源公司成立于 2021 年,在上海、深圳、北京、硅谷等城市设有分支机构。团队成员由各领域专家组成,在分布式基础架构、数据库、大数据及人工智能领域经验丰富。致力于成为行业领先的数据基础软件公司,帮助所有企业和用户简单、敏捷、高效地拥抱数据价值。
整个 MatrixOne 的架构升级之路,始于 0.4 迭代,在 0.6 迭代初步完成,历时半年多,数十位一线研发与测试工程师投入其中。删掉了关联的几十万行代码,又新增了体量更多的新代码。最终完成了从 share nothing 的 newSQL 架构到今天的新分布式 HTAP 架构,团队与产品共同获得了成长。
最后,让我们总结一下 MatrixOne 架构升级的关键点:
▶ 从存算一体到计算、事务、存储三层解耦
▶ 从多引擎到单一 TAE 的 HTAP 融合引擎
▶ 从因子化算法到 DAG 的计划构建
▶ 从多副本存储到对象存储与 Logtail 的引入
▶ 灵活调整节点分配带来的资源隔离
版权声明: 本文为 InfoQ 作者【MatrixOrigin】的原创文章。
原文链接:【http://xie.infoq.cn/article/6a2c3573ce731a30f9a42bbcb】。文章转载请联系作者。
评论