一. 前言
在Presto中,一条SQL会生成多个stage,stage之间是并发执行的,而且不同的stage可以在不同的节点上执行,stage与stage之间数据通过exchange进行数据交换,从而达到SQL分布式并行执行的目的。本文主要探索在Presto中stage的生成过程。
二. stage的生成原理
在presto中,stage的划分是基于计划执行树中的exchange节点进行划分的。每一个exchange节点会生成一个stage。
比如对于SQL:SELECT * FROM nation n join region r on n.nationkey = r.regionkey, 其生成了3个stage如下所示:
在上图中,stage 0代表着最终coordaintor 给用户输出的操作,往下的stage1 代表着sql中的join操作,stage2 代表着sql中的tablescan操作。
对应着该SQL的计划执行树如下:
三. PlanFragment的生成
在presto中,在生成stage的过程中依赖计划执行树的PlanFragment,生成PlanFragment又是在PlanFragmenter:: visitExchange中进行的,要了解stage的生成,首先要了解PlanFragment的生成。
在PlanFragmenter:: visitExchange中,会先访问计划执行树的root节点,然后从上到下一次依次访问每个exchange节点,对于每一个exchange节点,先访问exchange节点的子树,先生成子树的PlanFragment,然后将所有子树的PlanFragment作为当前节点的subStages,
以上边的计划执行树为例,PlanFragmenter先从root的output节点开始访问,遇到第一个exchange后,先递归访问exchange所有的source节点的exchange节点,对于每一个exchange,其处理过程为,将exchange的所有source添加成当前节点的SubPlan,以第一个Exchange节点为例,第一个Exchange的所有输入作为了Output节点的SubPlan,所有的exchange节点访问完成后,再递归返回此节点,直到所有的echange节点都访问过。因此上边的计划执行树最后生成的PlanFragment架构如下所示:
四. stage的生成
stage的生成基于步骤三的PlanFragment。其大概原理是:以树的root节点生成stage0,然后递归访问整个树,每个subStage创建一个Stage来生成最后的最终执行Stage,因为上边的PlanFragment有三个PlanFragment,因此生成了3个Stage,对应着本文的图1.