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