UHP博客文章地址:http://yuntai.1kapp.com/?p=1043
原创文章,转载请注明出处:http://blog.csdn.net/wind5shy/article/details/8562844
流程
流程图
- 用户通过ODBC/Beeswax Thrift API提交query到某个impalad。Impalad的Query Planner使用jflex和CUP解析SQL语句。然后Planner把这个query的parse trees变成若干PlanFragment,然后把PlanFragment发送到Backend/Query Coordinator。
- PlanFragment由PlanNode组成的,能被分发到单独节点上原子执行,每个PlanNode表示一个relational operator和对其执行优化需要的信息。
- Coordinator初始化相应impalad上的任务执行(存储了这个query相关数据的节点都会被分配任务)。
- 对于distributed-aggregation,将先在各个impalad上做局部aggregation,然后在coordinator节点上merge aggregation。
- Query Executor通过流式交换中间输出。Query Coordinator汇总来自各个impalad的结果后返回给client。
具体例子
表
SQL语句
select i_item_id, i_list_price, avg(ss_sales_price) agg1
FROM store_sales
JOIN item on (store_sales.ss_item_id = item.i_item_id)
JOIN customer on (store_sales.ss_customer_id = customer.c_id)
where
i_list_price > 1000 and
c_gender = ‘M’ and
c_marital_status = ‘S‘ and
c_city in (‘Beijing’,'Shanghai’,'Guangzhou’)
group by i_item_id,
order by i_list_price
limit 1000
查询计划树的生成与执行
- 生成基本的查询计划树
图中每个方框代表一个PlanNode。
- 对查询计划树进行分布式修改
Group By & Local Agg之下(包含自身)的PlanNode都可以在各个Backend节点上分布式执行,而之上的PlanNode只能在Coordinator上处理。
- 生成PlanFragment
上图中的每个虚线框代表一个PlanFragment,每个PlanFragment将被分配到相应的Backend节点上进行处理。
- 执行查询计划树
设处理sales_store的Backend节点数为N,处理item的Backend节点数为K,处理customer的Backend节点数为M。
执行步骤:
- Scan
相关表各个节点分别获取相关表数据。
- Join on item_id
目前Impala在处理join是需要将join右边表加载到左边处理的各个节点上。所以处理这个join时每个sales_store相关节点都需要通过网络从相应item节点获得item的全部数据,这将导致N*K次网络传输。
- Join on customer_id
sales_store相关节点根据上次join的结果处理进行新的join处理,同样将导致N*M次网络传输。
- Group by & Aggregation
sales_store相关节点分别在各自的join数据上进行Group by & Aggregation处理。
- Total Aggregation
Coordinator接收sales_store相关节点数据进行Aggregation。
- Sort/Limit
Coordinator对Aggregation后的数据进行Sort(Order By)和Limit处理,得到最终的结果。