乐趣区

关于数据库:UData查询引擎优化如何让一条SQL性能提升数倍

1 UData- 解决数据应用的最初一公里

1.1 背景

在大数据的领域,咱们经验了数据产业化的历程,从各个生产零碎将数据收集起来,通过实时和离线的数据处理最终会集在一起,成为咱们的主题域数据,下一步开掘数据的价值将成为要害。

数据利用间接体现数据的价值,数据利用多种多样,它们应用数据的形式也各不相同,UData 作为数据资产和数据利用之间的桥梁,它的第一指标是解决所谓的数据应用的最初一公里问题。

UData 平台以数据指标为根本的治理单位,通过四个阶段对于数据应用提供反对,一体化整合数据链路的整个生命周期,接数据、管数据、找数据、用数据。

UData 外围聚焦数据利用场景,从数据利用倒推买通数据接入、数据管理、数据查问等环节。各种数据利用对于数据的应用形式,大部分分为两个场景:

  1. 利用在线及时拜访数据,大多数以接口的模式,UData 平台绝对应的提供了数据服务的模块;
  2. 业务人员通过在线查找本人须要的数据指标(数据指标地图),可视化的进行人工数据分析和展现,UData 平台同时提供了数据分析的模块。

1.2 UData 性能架构图

上图,UData 性能架构自底部向上,蕴含了数据流转应用的整个过程,平台内的功能模块从数据应用的流程角度,残缺的涵盖了数据应用最初一公里的整个生命周期。

1.3 Udata 的数据管理

UData 对于数据的应用,从物理和逻辑两个层面进行了划分,并且对于多个租户同样进行了资源和计算的隔离。

1.4 Udata 目前能做什么?

1.4.1 指标配置化开发治理

  1. UData 数据接入能够将内部数据实时或者定时的导入平台,同时平台提供了多种数据源的联邦查问;
  2. 在线可视化的创立数据指标,并对数据指标进行打标签;
  3. 数据指标地图使业务人员不便的查找本人须要的业务指标;
  4. 数据指标的开发,治理,应用,几个阶段互相拆散,职责划分更加松耦合,业务注意力更加聚焦;

1.4.2 指标积木式编排和接口服务

  1. UData 从底层数据源开始至最上层封装成为数据指标对外提供数据服务;
  2. 数据指标在 UData 中能够像积木一样通过可视化的形式进行任意组合;
  3. UData 提供了接口编排能力,能够在指标组合根底之上,实现带有业务逻辑的分支条件判断;

1.4.3 指标及明细交互式关联剖析和协同分享

  1. UData 能够重用数据视图和数据指标,创立数据集,以此为根底向上进行数据分析;
  2. 数据集的配置反对 SQL 模式和可视化配置模式,别离针对不同 SQL 程度的剖析人员;
  3. 面向数据分析利用,以利用场景为单位进行数据和计算函数的治理和组织,场景可共享;
  4. 数据在线化实时剖析,无需线上导出数据;
  5. 在线 Excel 操作,长久化 Excel 模式,数据实时刷新,Excel 报表在线共享;

2 Udata- 查问引擎执行介绍 - 一条 SQL 的旅行

2.1 引擎架构

Udata 查问引擎基于 StarRocks 进行了局部革新,由两局部组成 FrontEnd(FE),BackEnd(BE) 组成。

  • FE:负责接管和返回客户端的申请,元数据和集群的治理,查问打算的生成和优化,协调 BE 进行查问。
  • BE: 次要负责 SR 表的数据存储和查问,内部表模式连贯三方存储,并执行查问打算中的具体节点,例如 scan, 投影,聚合等。

执行主流程:

  1. FE 收到 Sql 客户端发动的查问申请,解析 sql 并制订查问打算;
  2. FE 下发执行打算到 BE, 并指定一个 BE 为 Coordinator;
  3. 各 BE 依照查问打算中的 PlanFragment 为执行单位,接管工作,实现工作,并将后果汇聚到 Coordinator 节点;
  4. Coordinator 的 BE 节点将数据返回给 FE;
  5. FE 向 Sql 客户端返回后果;

2.2 从 SQL 语句到执行的过程

2.2.1 过程概览

用户通过 Mysql 客户端工具或者 JDBC 等形式,将须要执行的 SQL 语句进行输出,输出后的 SQL 语句通过语法解析,Binder,Transformer,Optimizer 等过程,从根底的 sql 语句,通过语法树,Relation,逻辑打算,分布式物理打算等过程,最终在 FE 端通过 Coordinator 发送到 BE 侧进行执行,并后续收集 BE 返回的数据,返回给调用客户端。

2.2.2 举例介绍

表构造:

desc remote\_mysql\_decimal;

SQL:

select count(`decimal`) as sum,`key` from remote_mysql_decimal where id <= 1000 group by `key` order by sum desc limit 10;

2.2.3 执行过程详解

1. 解析 SQL 语句

在这一步骤中,SQL 语句会进行语法查看,不符合规范的语句返回谬误,之后通过语法解析,会生成一个形象语法树,下面实例中的 SQL 语句(语句中有聚合,排序,谓词条件,limit 等元素)生成的语法树结构如下:

2. 绑定数据表元数据信息 - 生成 Relation

生成语法树之后,只是单纯的 SQL 语法信息,在 SR 中 FE 有一个重要的作用,就是保留数据表的元数据信息(库名,表名,列名,数据类型,对应的表面)等。
在这一步骤中,会将形象语法树和 FE 中的元数据信息(Catalog)进行关联,丰盛 SQL 相干的信息,将形象语法树生成 Relation 这种数据结构。

3.Transformer – 基于 RBO, 进行 Rewrite 生成逻辑执行打算

从 Relation 到逻辑打算,只是基于一些 SQL 改写规定,将树中的一些节点转变会逻辑打算节点。

如:

  • FromClause 会转换为逻辑打算中的 LogicalScanOperator 这种扫表操作;
  • WhereClause 会转换成逻辑打算中的 LOGICAL_FILTER,领导后续进行进行条件过滤;
  • OrderByElements 会转换成逻辑打算的 LOGICAL_TOPN,领导后续进行排序和 limit;
  • SelectList 会转换为逻辑打算的 LogicalProjectOperator,领导后续进行投影操作,缩小网络数据传输;

本实例中的 SQL 会生成如下的逻辑打算:

4.Optimizer – 基于 CBO 优化

在这一步骤中,会依据上一步生成的逻辑打算,同时联合 FE 中保留的元数据信息,基于 CBO 优化执行打算,进行谓词下推,Join order 调整等。
本实例中生成的 Optimizer Plan 如下:

5. 分布式物理打算的生成 - BE 执行的并行单位(PlanFragment)

BE 是分布式的,查问理论执行的时候,会将计划分配给具体的 BE。BE 之间,BE 和 FE 之间通过 RPC 通信传输数据,BE 执行的最小并行单位是 Fragment, 在这一步骤中会生成分布式的物理打算。
本实例 SQL 生成的分布式物理打算如下:

2.3 数据的输入

2.3.1 PlanFragment 在 BE 侧的映射

物理执行打算切分成 PlanFragment 之后,会发送到 BE 侧执行,BE 会依据 Fragment 中的树形构造,生成对应的 Node,实现各自的算子逻辑,算子之间通过不停的调用上层算子的 get_next() 函数,将数据用 chunk 的模式进行组织并流动起来,chunk 的数据结构是一种列式的批构造,十分有利于向量化的执行。

2.3.2 执行模型

1. 火山模型 / 迭代模型(Volcano Model)

在这种模型中,每一种操作会形象成一个 Operator, 在执行侧作为一个操作数,从顶到下调用 next() 接口,数据从底部的 scan 节点向上传输,然而每次只传输计算一条数据,也叫做(Tuple-at-a-time), 是一种拉取执行模式。
长处:每个 Operator 能够独自实现逻辑,比拟单间,灵便。
毛病:每次传输计算一条数据,导致 next() 函数调用次数过多,cpu 效率低。

2. 物化模式 /Materialization Model

这种模型的解决形式,依然是调用自顶向下,数据从底向上,然而每一个操作 Operator 一次性解决所有的输出,解决实现之后,将后果一次性向上输入。
此模式对于数据量较大的 OLAP 不太适宜,然而比拟适宜数据量较小的 OLTP 零碎。

3. 向量化模式 / 批处理模型(Vectorized / Batch Model)

这种模型和火山模型十分相似,不同之处是每个 Operator 的 next() 函数,会返回一批的 tuples 数据,相当于是一种批处理的模型,这是一种下面两种模型的折中形式。
SR 的向量化执行器次要集中在算子向量化,表达式向量化,存储向量化;充分利用 SIMD 指令优化,CPU Cache 敌对。

3 Udata 查问引擎 - 联邦查问的加强

3.1 Udata 查问引擎倒退的三个阶段

3.1.1 社区版 FE + 自研 JAVA 版 BE

Udata 查问引擎的第一阶段,是参照 StarRocks 的 C ++ 版本 BE 实现了一个 JAVA 版本的 BE, 次要实现了 Udata 在第一个阶段的进行联邦查问的数据服务的工作,并且在第一个版本根底上,曾经实现了聚合计算的下推,同时也通过了 618 的考验,在执行引擎层面积攒了大量的教训,为咱们发展引擎革新的第二阶段提供了反对;

3.1.2 原生 StarRocks + Udata 改良

鉴于 StarRocks 表的优异性能,咱们将查问引擎切换回原生的 SR, 同时将之前的积攒的优化教训,在原生 SR 上进行了实现,包含聚合查问和 Sort 排序的下推,额定反对了表面数据源 CK,Jsf,Http,进行了查问函数 format 等的丰盛。

3.1.3 将来摸索方向

在下一个阶段,Udata 查问引擎将会在 SR 的根底之上,亲密地配合社区,引入新版本的性能,同时进行数据湖的应用摸索和高性能的点查实际,以及跨 SR 集群的联邦查问等。

3.2 计算下推 – 极限压迫底层引擎的计算能力

3.2.1 优化背景

StarRocks 在联邦查问方面针对 MySQL, ElasticSearch 曾经有了十分快的性能,StarRocks 在联邦查问方面的设计思维是针对不同的查问内部数据源,设计不同的 Scan 节点,并且尽可能的将谓词下推到 Scan 节点,在 Scan 节点查问到数据之后,下层会共用 Project 节点,Agg 节点,TopN 等这些节点的算子,根本的查问架构相似下图。

这种设计使 StarRocks 有十分好的扩展性,能够很容易的扩大到新一种的数据源,也正是这种高度可扩大的设计使咱们有机会在联邦查问的细节层面,做进一步的优化,比方将一些算子的计算也尽可能的推到内部表引擎,能够节俭一部分网络传输的工夫,同时最大水平的压迫底层引擎原生计算能力,通过咱们的测试这种计算下推也达到了数倍于原来的性能。

3.2.2 优化范畴

在优化之前咱们针对底层引擎和算子的特色做了调研,优化的范畴包含如下:

  • 针对 ES 引擎,进行了聚合算子的下推,然而某些非凡算子排除,不反对 sum(distinct), avg(distinct) 算子下推;
  • 针对 MySQL 引擎和 ClickHouse,进行了聚合算子,TopN 算子的下推;
  • 针对新减少的 Jsf 和 Http,进行了查问参数下推,运行时列过滤;

3.2.3 整体优化思路

目前整体的优化思路,次要分为两个局部,FE 侧的革新和 BE 侧的裁减,同时对于原生 StarRocks 计算形式放弃兼容,能够轻易的切换回原来的计算模式。

1)FE 侧革新优化 - Optimizer Plan 的转换

执行打算优化流程

目前 Udata 查问引擎对执行打算进行优化的节点是在原来的 Optimizer 之后,咱们从 Scan 节点开始对于执行打算,进行了模式匹配,命中模式之后,进行对应的计算下推和投影的合并,同时过滤底层引擎不反对的非凡算子(如 ES 的 sum(distinct)),最终将转变后的物理打算发送给 BE 侧进行执行。

模式匹配和打算改写

物理打算的树状封装:

ElasticSearch:

Mysql:

查问树改写:

最终,AggScanOperator 会转变为 AggNode, 发送到 BE 进行执行。

2)BE 侧革新优化

针对执行打算进行了改写之后,同样在 BE 侧咱们创立了对应的 Node 节点,实现计算下推后的执行逻辑,向下对接内部执行引擎,同时向上对接相似 join 的聚合节点,最终输入后果数据。

3)原生 SR 兼容

同时执行层面,咱们设置了灵便的开关(set agg\_push\_down = 0),能够非常容易的敞开 UData 优化。

3.2.4 革新功效 -(30 秒 vs 6 秒)

在咱们的理论过程中,咱们对于计算下推,尤其是多表聚合后关联的场景进行了察看测试,计算性能随着聚合表数目的减少,会有成倍数的成果晋升。

3.3 JSF&HTTP&ClickHouse 的反对 – 京东生态的对齐

3.3.1 简介

JSF 是京东外部的一种 RPC 调用服务,很多数据分析的场景中,一些维表是在其余服务中用 JSF 或者 Http 的形式提供的,或者一些曾经计算好的数据指标须要在咱们的 UData 计算引擎中进行关联查问,因而咱们减少了对于 JSF 和 Http 的反对,来作为京东生态的一个补充。

JSF 和 HTTP 查问的两个关注点是如何将查问参数进行下推和如何将返回的结构化数据映射为表中的列数据,以便在联邦查问中进行数据关联和聚合。

同时,京东外部有不少应用 ClickHouse 的场景,咱们也进行了查问反对,ClickHouse 反对 TCP 协定,http 协定,mysql wire 协定,目前 Udata 查问引擎通过 Mysql wire 协定和 ClickHouse 进行表面关联。

3.3.2 次要革新点介绍

  • 在 FE 侧,减少了 JSF,HTTP,ClickHouse 三种内部表对应的元数据结构,能够长久化内部表查问须要的底层引擎的属性信息;
  • FE 侧 RBO 革新,对于 SQL 语法树对应的 FromClause 转换为对应的逻辑打算,并进一步转换为物理打算节点;
  • BE 侧减少对应的 ScanNode,进行数据查问;
  • 对于 JSF 和 HTTP,通过函数,用于从 FE 侧将查问参数传输到 BE 侧实在的查问节点,查问参数下推,同时列的过滤条件在获取数据后,在 Scan 节点运行时过滤;
  • 对于 JSF 和 HTTP,建表中减少 Mapping,将返回的 JSON 数据映射到数据列;
  • ClickHouse 内部表查问节点,能够反对两种模式,一般的 scan 查问和计算下推的 Agg 查问;

3.3.3 应用形式及案例展现

1)Jsf 内部表应用

Jsf 建表语句 (表构造 + 拜访 JSF 必须的元信息):

Mapping (Jsf 返回的 json 字串与数据表构造的映射):

查问 Sql 语句(查问参数下推 和 列表达式运行时过滤):

下面的 sql 是用来查问 Jsf 表面的,同样的其余聚合函数都能够用于该 Jsf 表查问,下面次要有以下须要进行下阐明:

  1. 列表达式过滤:(recv_count >= 1000 ) 这种过滤条件用于 Scan 操作获取到数据之后,在 BE 节点内运行时进行再次过滤;
  2. 查问参数下推:jsfparam 函数内置于 Udata 查问引擎,能够通过此函数,将须要带入到 Jsf 调用中的参数从调用端始终传递到 Jsf 服务中,从而缩小数据的获取;
  3. 联邦查问:Jsf 表同其余表面一样能够反对联邦查问,也同样能够反对其余表面反对的聚合等查问操作;

2)Http 内部表应用

Http 建表语句:

Http 的建表语句同下面 Jsf 表,只是 Properties 有所变动,变成了 http 拜访的元信息。

查问函数:

  • httpconfig : 第一个参数是数据表中的某一个列名,前面是一个 map, 目前仅反对 httpmethod 示意申请的形式 get/post ;
  • httpheader : 第一个参数是数据表中的某一个列名,前面是一个 map, json 构造,解析后,依照 key=>value 的配对,放入 http 申请的 header 中去 ;
  • httpbody : 第一个参数是数据表中的某一个列名,前面是参数,将间接放入 http 的申请的 body 中,这里须要留神的是 http 申请的形式是 application/json , 还是 x-www-form-urlencoded,两种形式 body 中的写法是不一样的,x-www-form-urlencoded 写法是 key1=value&key2=value2 ;

3.4 查问代理 - 使 Udata 查问引擎在实践上具备了查问所有的可能性

UData 查问引擎目前反对的联邦数据源有 Es, Mysql, Ck, StarRocks, Hive, Iceberg, Hudi 等,同时对于 UData 目前不反对的数据源能够通过代理插件的模式进行扩大,咱们提供了 Udata Proxy 的设计,只有遵循 Udata 代理提供的接口,实现对应的逻辑,来实现其余三方数据源的读取,便能够集成到 UData 查问引擎中,并和其余数据源一样能够实现一般查问和联邦关联查问。

3.4.1 批处理 vs 分页流式

Udata 查问引擎减少了 Proxy scan 节点,Scan 节点和 Proxy 代理之间能够通过 Http 和 RPC 两种协定进行通信;

数据从 Proxy 传输到 Scan 节点有两种形式:

  • 批处理:一次性获取 proxy 返回的全副数据;
  • 分页流式:适宜数据量比拟大的场景,利用 scroll_id 的参数,使数据能够分页微批的形式流向 scan 节点,须要 Proxy 中逻辑代码也反对滑动查问;

3.4.2 逻辑读插件热插拔

任何异构的数据源能够通过逻辑读插件的模式来反对,Proxy runtime 提供插件的执行环境,并进行并行线程的治理,逻辑读插件能够通过 Proxy 治理端进行上传和治理,热插拔及时失效;


作者:刘敬斌 贺思远

退出移动版