关于数据库:轻松驾驭EB级千万QPS集群TDSQL新敏态引擎元数据管控与集群调度的演进之路

2次阅读

共计 5643 个字符,预计需要花费 15 分钟才能阅读完成。

日前,TDSQL 新敏态引擎正式公布,反对有限扩大、在线变更,能够完满解决对于敏态业务倒退过程中业务状态、业务量的不可预知性,高度适配金融敏态业务。
 
该引擎 100% 兼容 MySQL,计算 / 存储资源均可独立全透明弹性扩缩容,实现了 PB 级存储的 Online DDL;计算层每个节点均可读写,轻松撑持千万级 QPS 流量,能够有效应对业务的变动。针对海量数据存储的场景,实现最高 20 倍压缩率的超高压缩比存储能力,大幅节俭资源老本。其独有的数据状态主动感知个性,使数据能依据业务负载状况实现主动迁徙,打散热点,升高分布式事务比例,取得极致的扩展性和性能。

计算存储拆散和管控数据拆散的体系架构,为 TDSQL 新敏态引擎带来了动静扩大上的灵活性,但同时也带来了在集群海量元数据管控和多维资源调度上的挑战。

本期将由腾讯云数据库专家工程师唐彦,为大家深度解读 TDSQL 新敏态引擎元数据管控与集群调度的摸索实际,次要讲述 TDSQL 在海量元数据管控、简单资源调度方面的架构原理,以及线上利用场景中在高性能和高可用方面的实际。以下是分享实录:

TDSQL 架构介绍

TDSQL 最新公布的新敏态引擎技术架构,它描述了一个计算 / 存储拆散、数据面 / 管控面拆散的高可用的原生分布式架构的关系型数据库。

TDSQL 分为三层:绿色局部是计算层,称之为 SQLEngine;紫色局部是管控层,简称为 MC,负责整个集群的管控调度工作;蓝色局部是存储层,称为 TDStore。

TDSQL 有三个重要的架构个性:全分布式,无论在计算层还是管控层,每一层都是分布式的架构;计算与存储齐全拆散,每一层均可独立动静扩缩容;数据流与管制面齐全拆散,要害读写门路与资源调度逻辑互不影响。

TDSQL 的四个次要性能特点:

● 高度兼容 MySQL。对于从单机 MYSQL 迁徙过去的业务,TDSQL 实现高达 100% 的兼容,对业务层无入侵,可能实现无感知迁徙。

● 高可扩展性。在存储层和计算层,用户只需手动在治理界面上增加一个存储节点或计算节点,后续外部的管控机制会自洽地实现整个扩缩容流程。

● 反对原生 Online DDL,可多写架构下以原生形式实现 Online DDL。

● 全局读一致性。TDMetaCluster 统一分配全局惟一递增事务工夫戳,实现金融级场景下的数据强统一。

分布式架构次要分为计算层、存储层和管控层。

首先是计算层。TDSQL 计算层最大的特点是多主架构,每个节点都反对读写,齐全互相独立;每个计算节点为无状态,具备扩容劣势,可高度兼容 MySQL 8.0,具备无状态化的弹性扩容的架构个性。

其次是存储层 TDStore,它是咱们自研的分布式 KV 存储引擎。在存储层和计算层的交互中,存储层承当事务协调者的角色。咱们以肯定形式将数据打散到每个存储节点上,每个数据分片称为 Region。存储层对所有数据的状态本身无感知,只负责数据的读写,所有数据的调度都由它与 MC 的交互来进行。

最初是管控层。它是一个分布式的集群,以一主 N 备的形式去部署。在整个集群中,它要同时承当管控层面和数据层面的工作。比方在数据层面,MC 负责全局惟一且严格递增的事务工夫戳的调配,同时负责管理所有的计算节点、存储节点的元数据、MDL 锁等等。

以下是数据库中常见的主性能流程:

● 分布式事务。TDSQL 人造反对分布式事务的个性。整体流程为:从 MySQL 客户端发送申请,通过计算层对存储层进行读写,读写过程中,存储层和计算层都会去和 MC 交互,获取工夫戳,最终确定每个事务之间的偏序关系,实现整个流程。

● 无感知扩缩容。当存储空间不够时就须要扩容。在扩容过程中,必然会波及到数据的搬迁。如下图例子所示,整个集群中只有一个存储节点,当须要扩容时,能够在界面上点击多购买一个存储节点。此时存储节点上数据的决裂搬迁、计算层对最终数据路由的感知、计算层感知路由的变动后实现的重试等过程能够齐全自洽地蕴含在整个数据库体系中,实现业务层无感知。

● Online DDL。TDSQL 的分布式体系架构采纳多写架构。为达到更好的并发性能,须要在多写的架构下,实现 Online DDL。相较同类产品,当业务尝试在运行过程中加一列、加一个索引时,须要借助内部的工具,及梗塞业务来实现 DDL 的操作。为了更好的用户体验,升高 DDL 操作对失常业务读写的影响,TDSQL 实现了在多写架构下以原生形式反对的形式去实现 Online DDL 操作的实现。

TDSQL 管控层在分布式场景下的挑战

TDSQL 架构的三大性能个性:

● 原生分布式,全部都是分布式,没有核心节点管控。

● 存算拆散,计算跟存储齐全拆散,不在一个服务器上。

● 数据跟管控齐全拆散,数据层面齐全不参加数据管理。

这些个性从字面上看起来都比拟间接、简略,但咱们却在工程落地时遇到诸多的技术挑战,总结起来次要是高性能、高可用、简单调度三个方面。上面将着重分享咱们在高性能、简单调度方面遇到的挑战。

首先是高性能方面的挑战。在架构上,要做到分布式的齐全存算拆散的架构,MC 作为集群内惟一一个核心的管控模块,必须承当全局授时源角色。

在分布式事务的整体架构图中,能够理解到 MC 在事务过程中须要和存储层做网络交互,提供工夫戳,这是要害门路。同时 TDSQL 的计算层和存储层都能够灵便扩缩容。存算拆散、高扩大的两个个性也意味着 MC 必须要具备十分高的性能。

在简单调度层面。咱们设计成数据和管控齐全拆散的架构,数据齐全存储在 TDStore 上,只负责数据流的读写。其余工作齐全交由管控层去进行,MC 只须要监控整个集群的状态做出对于存储资源的决策。

TDSQL 元数据管控挑战与实际

3.1 高性能方面的摸索与实际

在高性能方面,咱们采纳十分经典的三段式协程架构,即一个协程收、解决、最初再发。这种架构在咱们冲破 60 万时就达到性能瓶颈。

通过性能剖析,咱们意识到性能瓶颈集中在第二个协程里。于是咱们将呈现瓶颈的中央并行化。但第二个协程减少到肯定时,下个瓶颈又呈现,因为协程 1 是单管道模式,新的瓶颈点集中在协程 1。

咱们在下个版本里做了一个稍微简单的 N 对 N 架构,也是多协程架构。基于此咱们发现性能能够晋升但 CPU 的耗费十分大。咱们的设计指标是 MC 在性能方面有较强的体现,其性能数据能达到 500 万。但过后只管达到 75 核,数据还是停留在 320 万。咱们对此进行 perf 剖析,发现问题次要来自 RPC 解析,因为 MC 次要网络框架的实现是基于 GRPC 的网络通讯,会有比拟大的头部序列化和反序列化的性能开销。

已知性能妨碍存在于网络框架,咱们优化的指标就成为解脱网络框架带来的性能限度。对此咱们给工夫戳的获取开发了 TCP ROW Socket 通道。因为工夫戳数据结构有一个人造劣势,即申请无状态、无依赖,只蕴含两三个整型字段。这时在网络上发来的任何申请,MC 只须要收到一个,答复一个,能够去定制化实现申请。

在弃用该框架后,性能晋升飞快,在比拟低的 CPU 开始的状况下,能够将性能晋升到 450 万。但在后续过程中,咱们发现瓶颈呈现在申请进队列还有申请出队列的过程中。咱们应用 Go Channel 作为音讯的进出队列载体,Channel 尽管好用且轻量,但底层仍旧带锁实现,push/pull 操作存在着百纳秒级别的开销。

对此咱们打算实现无锁队列,须要实现单生产者、单消费者模式的场景。基于这种场景,咱们实现一个简略的信号量,作为两者之间的唤醒机制。应用该优化计划后,资源的耗费明显降低且达到更高的性能,峰值吞吐冲破 750 万。

最后 500 万的指标虽已实现,但咱们团队仍认为性能数据还能够更好。以下为经典的 CPU 缓存的 MESI 状态转换图。一行 CPU 的 Cache Line 能够包容 64 个字节,在咱们的数据结构中,将其中多个 8 字节的变量放在同一个缓存行,如果一个更新十分多,另一个更新的少,就会影响另一个原子变量的读写。从图片左边可知,在这里把变量的 8 字节对齐后,就解决 CPU 缓存行的问题,性能数据也从 750 万回升至 920 万。此时咱们的指标是实现单核心的千万级别的性能数据。

为了进一步实现单核心的千万级别的性能数据,咱们从业务场景进一步深挖。在整个集群中,MC 在工夫戳方面是繁多的提供者,而集群中泛滥的计算节点和存储节点会产生源源不断的申请,因而在剖析生产者和消费者速度时,咱们发现生产者速度远远跟不上消费者速度。为此咱们进行了简略的革新,即来一批申请再生产一批工夫戳,以批量申请形式去唤醒消费者。为了适应业务场景,咱们还对该优化做了开关,运维人员能够依据业务场景的需要进行调节。执行批量化操作后,整体峰值曾经晋升至两千万,许多数据库实例的业务场景都无奈达到这种高压力。

3.2 简单调度方面的摸索与实际

因为实现数据面与管控面的拆散,MC 要负责整个集群所有跟资源相干的管控。如图所示,图中画的就是 MC 的次要性能。

MC 须要负责工夫戳的提供,治理全局的惟一 ID 的调配、DDL 的协调、计算层管控层资源的元数据以及数据分片的治理。在管控层的不同层面,所有跟治理调度相干的工作都集中在 MC。

为了实现简单调度,咱们首先划分资源层级,制订可用的具备可扩展性的根底框架,将存储模块从治理工作中开释。MC 必须将每个资源层级划分分明,使得数据门路上的所有模块只须要被动执行,不须要关怀数据的状态。咱们从集群层面、复制组层面和正本层面进行划分,划分出许多子状态及子步骤。
 
比方在扩容过程中,有一个数据分片,正本散布在 123 三个存储节点中,如果要进行数据迁徙使得一主两备变为 124 的分布模式,在整个过程中,任意时刻这四个节点都晓得本人要做的原子子步骤,而无须感知到整个迁徙过程。
 
迁徙过程蕴含五个原子子步骤:先在节点 4 上创立新局部,再将新局部退出到本来的数据复制同步组中,去掉的正本的状态设置为 offline,最初再把该正本删除。在分布式数据库中随时可能有节点挂掉,但通过步骤划分,无论是 MC 挂掉还是 TDStore 挂掉,节点拉起来后都晓得要如何操作。通过这样的机制,存储层对每个工作的推动或回滚齐全无感知,全副由 MC 来做协调。

该机制次要有以下三方面的成果:
 
首先是性能。该机制对性能晋升的促成十分显著,在集群比拟大时能够轻松反对 EB 级存储。比方在 500 万数据分片的量级下,MC 用 20 个核就能齐全反对。通过数据状态与调度状态的拆散,大大降低了 MC 负载。性能上的收益还体现在存储层上。在任意时刻它只须要接管到一个原子步骤即可。因而在代码层面,存储层不须要任何关注数据资源状态的代码,更有利于进行性能优化。
 
其次是健壮性。每个工作都是无限的状态机,任意一个参与者,如管控或存储,呈现交互中断,都可能以确定形式进行工作的回滚或复原。
 
最初是可扩展性。每个管控工作分为多个原子步骤进行,有利于以插件式形式去定义其余更多更简单的工作。整个过程中只须要将原子步骤拼装组合,MC 就能够实现简单调度。

3.3 数据分布方面的摸索与实际

原始版本中,MC 对数据分布治理只有物理地位概念,基于扩大引擎和分布式协定打造的 KV 存储引擎,数据分片在整个分布式存储集群中依照主键从空到正无穷的字符序来进行散布。比方创立表或二级索引时,如果要表白成 KV 模式,主键和二级索引都有对应的 ID。存储层中以 Key 区间代表一个数据分片,如 01-02 数据分片,落在存储节点 1 上,02-03 数据分片,落到存储节点 2 上。这种状况下,同一张表的数据的主键和二级索引会落在不同的 TDStore 上,这就会造成很大的负面影响。

举个例子,有一张表,每天有大量不同的流水写入,有三亿行数据,业务为不便查问,做了 20 个索引。在最坏的状况下,20 个索引别离落在不同的 Region,又落在了不同的 TDStore。数据库使用者从操作上更新了一行,但可能会倒退成 20 个波及到 60 个参与者的分布式事务,带来 60 次同步的性能损耗。在这种状况下,咱们针对经常出现的业务场景对两阶段提交进行优化,让更多的提交变成一阶段提交。

咱们设立表内数据的概念,每个数据在物理层面都能够晓得每个 Key 落在哪个 TDStore,但无奈感知到它们属于哪个二级索引。对此咱们须要建设关系去创立表,使得在创立表和索引时,MC 能够感知到每个 Key 在物理意义上属于哪个 TDStore,逻辑意义上属于哪些表的分区、属于哪些表的二级索引。

咱们还引入了复制组的概念。在原始版本中,每个数据分片是一个复制组,当初则是将多个 Region 归属于一个复制组,通过管控体系架构的扭转,将表数据和二级索引放在同一复制组里。这种做法的益处有两方面:一方面,业务中经常依照分区键来划分事务,一次性批改的数据十分大,可能只落在同一复制组里,这时须要进行屡次网络交互能力实现一个分布式事务,优化后只须要一次落盘即可实现;另一方面的益处是计算下推,因为计算层能够感知到要写的主键、二级索引都在同一 TDStore 的同一复制组内,就能够提前将逻辑下推到存储层中实现。

接下来解决的问题是表与表之间的亲和性。在局部零碎中,以肯定规定如哈希去分区的表构造中,在更新表 1 的 1 分区时,也会去拜访表 2 的 1 分区。这就要求管控层必须了解表与表之间的概念。如果能感知到它们是在同一组事务里被操作的单位,就能够更好地改善事务的两阶段提交。

对此咱们提供了一个扩大语法。如果用户有需要,能够去指定他所偏向的数据分布策略,为该策略命名,容许在该散布策略里再指定分区策略。如下图所示,当上面第三行创立表时,如果有两个表在业务场景中常常被拜访,就能够将它们关联到同一 DP 组里,MC 会在后盾创立表。所有的散布策略都会通过 MC 进行,MC 能够在后盾将这些关联的表做背地的调度优化。这就为更多跨表之间的操作提供较多的可能性。

将来时机与挑战瞻望

将来咱们仍有许多挑战须要克服。首先是全局事务工夫戳,目前 MC 承当许多的管控操作,后续咱们打算将其设计成多过程模式,全局事务工夫戳独占一个过程。其次是 Lieutenant 分流,咱们打算减少副队长角色,分流局部网络。最初是数据亲和调度的利用也是咱们将来会去重点攻坚的畛域。

正文完
 0