Drill查询拆分过程

来源:互联网 发布:北京云梦网络怎么样 编辑:程序博客网 时间:2024/05/17 00:06

Drill代码分析(查询拆分)

Drill代码分析(查询拆分) 
Drill架构 
Drill是什么 
Drill查询服务总体执行流程 
Drill查询引擎执行流程 
物理执行计划生成 
查询拆分和分布执行 
非根查询片段执行流程 
Calcit架构 
Drill与Calcite交互

Drill架构

Drill是什么

Drill是开源、低延迟、分布式查询系统,可扩展到数千节点,适用于PB级交互式BI和分析。
Drill具有标准查询引擎的服务器,编译,优化,执行模块,并利用zookeeper负责节点协调,支持基于calcite的优化器,支持查询拆分分布执行和定制存储插件,支持用分布式内存系统加速中间结果集的查询,支持hadoop生态,传统RDB系统和mongdb等数据源 。 
Drill架构图如下:



Drill查询服务总体执行流程

Drill的Sqlline客户端:
Zookeeper集群:
Drill服务节点:


  1. 客户端通过sqlline发起查询请求
  2. Zookeeper协调请求,并分配一个Drill节点执行任务。
  3. 节点的Drillbit服务在UserServer中接收请求由UserWorker执行任务。
  4. UserWorker建立工头Foreman,并把当前节点作为这个查询的主节点,负责把最终查询结果发送给客户端。
  5. Foreman负责把原始sql查询经过编译优化转换为物理执行计划树。
  6. 把物理执行计划树用SimpleParallelizer拆分成可分布执行的查询片段树。
  7. 查询片段树的根节点在本机执行,执行的前提是查询片段树根节点下的处于内部节点位置的查询片段和处于叶子节点位置的查询片段都执行完毕。
  8. Foreman把非根节点的查询片段发送到远程的相关Drillbit服务。
  9. 远程Drillbit服务如果接收到类型为叶子节点的查询片段,则直接执行物理执行计划并返回执行结果给上层查询片段。
  10. 远程Drillbit服务如果接收到类型为内部节点的查询片段,则等待直到其子树内所有查询片段树执行完毕才开始执行,执行完毕结果发送到上层查询片段

 

Drill查询引擎执行流程

物理执行计划生成


即下面节点的变换过程:
sql string->SqlNode经词法语法分析生成抽象语法树
->RelNode转换为calcite内部关系表达式
->DrillRel经基本优化规则集(实现了RelOptRule接口)转换后的逻辑计划
->Prel经物理执行计划规则集(实现了Prule接口)转换后的节点
->PhysicalOperator为执行计划添加了行数、代价等元数据的物理操作符
->PhysicalPlan

相应的查询语句变换过程示例如下:

原始sql:SELECT `nations`.`N_NAME`, `regions`.`R_NAME`FROM `dfs_test`.`/opt/huxl/drill-master/exec/java-exec/../../sample-data/nation.parquet` AS `nations`INNER JOIN `dfs_test`.`/opt/huxl/drill-master/exec/java-exec/../../sample-data/region.parquet` AS `regions` ON `nations`.`N_REGIONKEY` = `regions`.`R_REGIONKEY`calcite逻辑执行计划:ProjectRel(N_NAME=[$2], R_NAME=[$5]): rowcount = 1500.0, cumulative cost = {3200.0 rows, 3202.0 cpu, 0.0 io, 0.0 network, 0.0 memory}, id = 12  JoinRel(condition=[=($1, $4)], joinType=[inner]): rowcount = 1500.0, cumulative cost = xxx, id = 10    EnumerableTableAccessRel(table=[[dfs_test, /opt/huxl/drill-master/exec/java-exec/../../sample-data/nation.parquet]]): rowcount = 100.0, cumulative cost = xxx, id = 4    EnumerableTableAccessRel(table=[[dfs_test, /opt/huxl/drill-master/exec/java-exec/../../sample-data/region.parquet]]): rowcount = 100.0, cumulative cost = xxx, id = 5drill逻辑执行计划:DrillScreenRel: rowcount = 25.0, cumulative cost = {107.5 rows, 78.5 cpu, 0.0 io, 0.0 network, 0.0 memory}, id = 62  DrillProjectRel(N_NAME=[$1], R_NAME=[$3]): rowcount = 25.0, cumulative cost = {105.0 rows, 76.0 cpu, 0.0 io, 0.0 network, 0.0 memory}, id = 61    DrillJoinRel(condition=[=($0, $2)], joinType=[inner]): rowcount = 25.0, cumulative cost = xxx      DrillProjectRel(N_REGIONKEY=[$1], N_NAME=[$0]): rowcount = 25.0, cumulative cost = xxx, id = 59        DrillScanRel(table=[[dfs_test, /opt/huxl/drill-master/exec/java-exec/../../sample-data/nation.parquet]], groupscan=[ParquetGroupScan [entries=[ReadEntryWithPath [path=file:/opt/huxl/drill-master/sample-data/nation.parquet]], selectionRoot=/opt/huxl/drill-master/sample-data/nation.parquet, numFiles=1, columns=[`N_REGIONKEY`, `N_NAME`]]]): rowcount = 25.0, cumulative cost = xxx, id = 44      DrillScanRel(table=[[dfs_test, /opt/huxl/drill-master/exec/java-exec/../../sample-data/region.parquet]],groupscan=[ParquetGroupScan [entries=[ReadEntryWithPath [path=file:/opt/huxl/drill-master/sample-data/region.parquet]], selectionRoot=/opt/huxl/drill-master/sample-data/region.parquet, numFiles=1, columns=[`R_REGIONKEY`, `R_NAME`]]]): rowcount = 5.0, cumulative cost = xxx, id = 42drill物理执行计划:Screen: rowcount = 25.0, cumulative cost = {137.5 rows, 446.5 cpu, 0.0 io, 0.0 network, 88.0 memory}, id = 390  Project(N_NAME=[$0], R_NAME=[$1]): rowcount = 25.0, cumulative cost = xxx, id = 389    Project(N_NAME=[$1], R_NAME=[$3]): rowcount = 25.0, cumulative cost = xxx, id = 388      HashJoin(condition=[=($0, $2)], joinType=[inner]): rowcount = 25.0, cumulative cost = xxx, id = 387        Project(N_REGIONKEY=[$1], N_NAME=[$0]): rowcount = 25.0, cumulative cost = xxx, id = 385          Scan(groupscan=[ParquetGroupScan [entries=[ReadEntryWithPath [path=file:/opt/huxl/drill-master/sample-data/nation.parquet]], selectionRoot=/opt/huxl/drill-master/sample-data/nation.parquet, numFiles=1, columns=[`N_REGIONKEY`, `N_NAME`]]]): rowcount = 25.0, cumulative cost = xxx, id = 384        Scan(groupscan=[ParquetGroupScan [entries=[ReadEntryWithPath [path=file:/opt/huxl/drill-master/sample-data/region.parquet]], selectionRoot=/opt/huxl/drill-master/sample-data/region.parquet, numFiles=1, columns=[`R_REGIONKEY`, `R_NAME`]]]): rowcount = 5.0, cumulative cost = x, id = 386

查询拆分和分布执行

物理执行计划经过SimpleParallelizer拆分后形成类似如下的查询片段树: 
              fragment1(root)
                /                   \
fragment2(internal)   fragment3(leaf)
         /
fragment4(leaf) 

上面fragment1-4四个查询片段分别在drill节点1-4四台机器上执行。下面是各机器上drill服务的执行逻辑 
drill节点1:根查询片段的控制和计算节点
UserServer接收zookeeper指派过来的用户请求,并建立Foreman
Foreman对原始查询生成物理执行计划
对物理执行计划改写为查询片段树
将查询片段树中非根查询片段通过ControlClient发送到相应节点
DataServer接受节点2、3返回的数据,每次接受都将状态通知ControlServer
根查询片段在所有子孙查询片段全部执行完毕后在ControlServer中触发执行。
根查询片段执行完毕结果通过UserServer返回给用户。  
drill节点2:内部查询片段的控制和计算节点
ControlServer接受节点1发送过来的内部查询分片并建立片段管理器
DataServer接受节点4发过来的查询片段执行结果,并将当前状态信息通过WorkEventBus通知ControlServer中的片段管理器
当前所有依赖的查询片段都已执行完,触发执行当前查询片段,调度执行
WorkManager执行完当前查询片段,把结果通过DataClient发往节点1的DataServer 
drill节点3:父亲为根查询片段的叶子查询片段所在的计算节点
ControlServer接受节点1发送过来的叶子查询分片并建立执行器,调度执行
WorkManager执行完叶子查询片段,把结果通过DataClient发往节点1的DataServer 
drill节点4:父亲为内部查询片段的叶子查询片段所在的计算节点
ControlServer接受节点1发送过来的叶子查询分片并建立执行器,调度执行
WorkManager执行完叶子查询片段,把结果通过DataClient发往节点2的DataServer

非根查询片段执行流程

特别的,非根查询片段所建立的片段管理器执行流程如下:

IncomingBuffers对应要接收的所有查询片段结果集接收器Receiver
DataCollector对应每个查询片段结果集接收器,一个接收器对应多个发送器Sender的结果
RawRawBatchBuffer表示每个Sender执行后结果,Sender结果集可能比较大,会多次发送
RawFragmentBatch对应一个Sender返回的结果集块,
FragmentRecordBatch结果集块对应的protobuf消息格式

Calcit架构

Calcite是可灵活定制的查询编译和优化器开发框架。Calcite内部实现了100种左右的优化规则。
架构如下:

Drill与Calcite交互

Calcite主要负责编译和优化。所以drill和calcite之间的交互主要在物理执行计划生成之前
RelOptRule优化规则抽象接口
RelNode: 代数表达式抽象接口
Planner: 编译器和优化器函数调用的接口
Program:优化规则被执行调用的接口 
Drill利用了calcite定制优化规则,Drill定制的优化规则定义主要是实现了Prule接口的针对物理执行计划优化。针对逻辑执行计划的规则主要还是利用了calcite,Drill定制较少。




0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 车子违章扣50分怎么办 车子扣了12分怎么办 大学把档案丢了怎么办 学校把档案丢了怎么办 高考考了200多分怎么办 高考报名号忘了怎么办 中考只考500分怎么办 档案自提了之后怎么办 冬天衣服上的毛怎么办 四维预约不上怎么办 交了订金后悔了怎么办 信而富认证失败怎么办 南京市民卡坏了怎么办 南京市民卡断了怎么办 义乌市民卡丢了怎么办 常熟市民卡丢了怎么办 昆山市民卡丢了怎么办 市民卡丢了看病怎么办 儿童市民卡丢了怎么办 眉毛纹的太黑怎么办 法院执行书下了怎么办 汽车临牌过期了怎么办 考试用了hb铅笔怎么办 处对象处的心累怎么办 孩子初中毕业考不上高中怎么办 单位停交社保后怎么办 58同城电话骚扰怎么办 回民误吃了猪肉怎么办 回族人吃了猪肉怎么办 商场倒闭了商铺怎么办 吃了金毓婷出血怎么办 吃过毓婷后怀孕怎么办 新鲜枣子吃多了怎么办 xp系统重启黑屏怎么办 15岁初中生厌学怎么办 被九州教育骗了怎么办 腰疼的不能弯腰怎么办 长期弯腰导致的腰疼怎么办 孕妇闻了油漆味怎么办 闻了油漆味头晕怎么办 84消毒液闻多了怎么办