Apache Drill SQL执行流程
Apache Drill SQL执行流程
当您提交 Drill 查询时,客户端或应用程序将查询以 SQL 语句的形式发送到 Drill 集群中的 Drillbit。 Drillbit 是在每个活动的 Drill 节点上运行的进程,用于协调、计划和执行查询,以及跨集群分布查询工作以最大化数据局部性。
下图表示客户端、应用程序和 Drillbits 之间的通信:
从客户端或应用程序接收查询的 Drillbit 成为查询的工头并驱动整个查询。 Foreman 中的解析器解析 SQL,应用自定义规则将特定的 SQL 运算符转换为 Drill 理解的特定逻辑运算符语法。 这个逻辑运算符的集合形成了一个逻辑计划。 逻辑计划描述了生成查询结果所需的工作,并定义了要应用的数据源和操作。
Foreman 将逻辑计划发送到基于成本的优化器中,以优化语句中 SQL 运算符的顺序并读取逻辑计划。 优化器应用各种类型的规则将运算符和函数重新排列成最佳计划。 优化器将逻辑计划转换为描述如何执行查询的物理计划。
Foreman 中的并行器将物理计划转换为多个阶段,称为主要片段和次要片段。 这些片段创建一个多级执行树,重写查询并针对配置的数据源并行执行它,将结果发送回客户端或应用程序。
主要片段
主要片段是表示查询执行阶段的概念。 一个阶段可以包含一个或多个操作,Drill 必须执行这些操作才能执行查询。 Drill 为每个主要片段分配一个 MajorFragmentID。
例如,要执行两个文件的哈希聚合,Drill 可能会创建一个包含两个主要阶段(主要片段)的计划,其中第一阶段专门用于扫描两个文件,第二阶段专门用于数据的聚合。
Drill 使用交换运算符来分离主要片段。 交换是数据位置和/或物理计划并行化的更改。 交换由发送方和接收方组成,以允许数据在节点之间移动。
主要片段实际上不执行任何查询任务。 每个主要片段被分成一个或多个次要片段(在下一节中讨论),这些次要片段实际执行完成查询所需的操作并将结果返回给客户端。
您可以通过在文件中捕获计划的 JSON 表示,手动修改它,然后使用 SUBMIT PLAN 命令将其提交回 Drill 来处理物理计划中的主要片段。 您还可以在查询配置文件中查看主要片段,这在 Drill Web UI 中可见。 有关详细信息,请参阅 EXPLAIN 和查询配置文件。
次要片段
每个主要片段都被并行化为次要片段。 次要片段是在线程内运行的逻辑工作单元。 Drill 中的逻辑工作单元也称为切片。 Drill 创建的执行计划由小片段组成。 Drill 为每个小片段分配一个 MinorFragmentID。
Foreman 中的并行器在执行时从一个主要片段创建一个或多个次要片段,方法是将一个主要片段分成尽可能多的次要片段,因为它可以在集群上同时有效地运行。
Drill根据其上游数据需求,在自己的线程中尽快执行每个minor fragment。 Drill 在具有数据局部性的节点上调度次要片段。 否则,Drill 会在现有可用的 Drillbit 上以循环方式安排它们。
次要片段包含一个或多个关系运算符。 运算符执行关系操作,例如扫描、过滤、连接或分组依据。 每个运算符都有一个特定的运算符类型和一个 OperatorID。 每个 OperatorID 在其所属的次要片段中定义其关系。 请参见物理运算符。
例如,当执行两个文件的哈希聚合时,Drill 将专用于扫描的第一阶段分成两个小片段。 每个小片段都包含扫描文件的扫描操作符。 Drill 将专门用于聚合的第二阶段分解为四个小片段。 四个次要片段中的每一个都包含对数据执行哈希聚合操作的哈希聚合运算符。
您不能修改执行计划中的次要片段数。 但是,您可以在 Drill Web UI 中查看查询配置文件,并修改一些配置选项来更改次要片段的行为,例如最大切片数。 请参阅配置选项。
执行次要片段
次要片段可以作为根片段、中间片段或叶片段运行。 执行树只包含一个根片段。 执行树的坐标从根开始编号,根为零。 数据从叶片段向下游流向根片段。
根片段在 Foreman 中运行并接收传入的查询、从表中读取元数据、重写查询并将它们路由到服务树中的下一层。 其他片段成为中间片段或叶片段。
当数据可用或从其他片段提供给中间片段时,中间片段开始工作。 他们对数据执行操作,然后将数据发送到下游。 它们还将聚合结果传递给根片段,根片段执行进一步聚合并将查询结果提供给客户端或应用程序。
叶子碎片并行扫描表并与存储层通信或访问本地磁盘上的数据。 叶子片段将部分结果传递给中间片段,中间片段对中间结果执行并行操作。
Drill 仅计划具有并发运行片段的查询。 例如,如果集群中存在 20 个可用切片,则 Drill 计划在特定主要片段中运行不超过 20 个次要片段的查询。 Drill 是乐观的,并假设它可以并行完成所有工作。 特定主要片段的所有次要片段基于它们的上游数据依赖性同时开始。