Pig系统分析(3)-从Pig Latin到Logical plan

Pig基于Antlr进行语法解析,生成逻辑执行计划。逻辑执行计划基本上与Pig Latin中的操作步骤一一对应,以DAG形式排列。

以下面代码(参考Pig Latin paper at SIGMOD 2008)为例进行分析,包含了load、filter、join、group、foreach、count函数和stroe等常用操作。

PigServer pigServer = new PigServer(ExecType.LOCAL);
pigServer.registerQuery("A = load 'file1' as (x,y,z);");
pigServer.registerQuery("B = load 'file2' as (t,u,v);");
pigServer.registerQuery("C = filter A by y>0;");
pigServer.registerQuery("D = join C by x,B by u;");
pigServer.registerQuery("E = group D by z;");
pigServer.registerQuery("F = foreach E generate group,COUNT(D);");
pigServer.explain("F", "dot", true, false, System.out, System.out,
				System.out);
pigServer.store("F", "output");

生成的逻辑执行计划如下


Parse过程

QueryLexer.g和QueryParser.g分别是Pig Latin使用的词法文件和语法文件。

Pig不仅仅使用 Anltr生成的词法分析器和语法分析器,校验用户输入合法性(AstValidator)。还同时做了两件事情(antlr具体细节不在此展开)

1)  在语法文件中嵌入动作,加入Java代码,对表达式做进一步处理。

2)  使用了Antlr 的抽象语法树语法,在语法分析的同时将用户输入转换成抽象语法树,如

foreach_plan_complex : LEFT_CURLY nested_blk RIGHT_CURLY-> ^( FOREACH_PLAN_COMPLEX nested_blk )

下图是JOIN语句语法规则的可视化表示


Parse时序图如下(省略了宏展开,用户REGISTER语句替换等细节,其中QueryLexer,QueryParser和AstValidator都是antlr生成的类):


Logical Plan生成过程

LogicalPlanGenerator.g是一个树分析器文件,antlr生成LogicalPlanGenerator.java文件,实现org.antlr.runtime.tree.TreeParser接口,会对QueryParser.g对应的抽象语法树进行语义处理,用来生成逻辑执行计划(antlr具体细节不在此展开)。

在本节开始图4中的运行Pig Latin程序中,每次调用pigServer.registerQuery方法,注册一个查询语句,Pig都会启动解析、验证步骤,然后调用LogicalPlanGenerator.query()方法,生成该条语句对应的逻辑执行子计划。直到调用pigServer.store方法,才会生成一个完整的逻辑执行计划,触发下一阶段操作。

以上过程信息,包括最后完成的逻辑执行计划都存储在PigServer的private GraphcurrDAG成员变量中,如果在更复杂的批量执行模式下,比如脚本里边调用其他脚本,需要队列来进行存储。

    /*
     * The data structure to support gruntshell operations.
     * The grunt shell can only work on onegraph at a time.
     * If a script is contained inside anotherscript, the grunt
     * shell first saves the current graph onthe stack and works
     * ona new graph. After the nested script is done, the grunt
     * shell pops up the saved graph andcontinues working on it.
     */
    protected finalDeque<Graph> graphs = new LinkedList<Graph>();

其中currDAG中存储的具体信息如下:lp代表完整的逻辑执行计划,operator可以理解为计划中的特定步骤,它们的关系和内部结构将在下一节介绍。


Logical Plan结构   

下面是完整的逻辑执行计划,可以观察到自底而上,分别对应最初是的Load操作和最后的Store操作。

#-----------------------------------------------
# New Logical Plan:
#-----------------------------------------------
F: (Name: LOStore Schema:group#38:bytearray,#47:long)
|
|---F: (Name: LOForEachSchema: group#38:bytearray,#47:long)
    |   |
    |  (Name: LOGenerate[false,false] Schema: group#38:bytearray,#47:long)
    |  |   |
    |  |   group:(Name: Project Type:bytearray Uid: 38 Input: 0 Column: (*))
    |  |   |
    |  |   (Name:UserFunc(org.apache.pig.builtin.COUNT) Type: long Uid: 47)
    |  |   |
    |  |   |---D:(Name: Project Type: bagUid: 44 Input: 1 Column: (*))
    |   |
    |  |---(Name: LOInnerLoad[0] Schema: group#38:bytearray)
    |   |
    |  |---D: (Name: LOInnerLoad[1] Schema:C::x#36:bytearray,C::y#37:bytearray,C::z#38:bytearray,B::t#41:bytearray,B::u#42:bytearray,B::v#43:bytearray)
    |
    |---E: (Name: LOCogroup Schema:group#38:bytearray,D#44:bag{#50:tuple(C::x#36:bytearray,C::y#37:bytearray,C::z#38:bytearray,B::t#41:bytearray,B::u#42:bytearray,B::v#43:bytearray)})
        |  |
        |  C::z:(Name: Project Type: bytearray Uid: 38 Input: 0 Column: 2)
        |
        |---D: (Name: LOJoin(HASH) Schema:C::x#36:bytearray,C::y#37:bytearray,C::z#38:bytearray,B::t#41:bytearray,B::u#42:bytearray,B::v#43:bytearray)
            |  |
            |  x:(Name: Project Type: bytearray Uid: 36 Input: 0 Column: 0)
            |  |
            |  u:(Name: Project Type: bytearray Uid: 42 Input: 1 Column: 1)
            |
            |---C: (Name: LOFilter Schema:x#36:bytearray,y#37:bytearray,z#38:bytearray)
            |  |   |
            |  |   (Name: GreaterThan Type:boolean Uid: 40)
            |  |   |
            |  |   |---(Name: Cast Type: int Uid:37)
            |  |   |   |
            |  |   |   |---y:(Name: Project Type: bytearray Uid: 37Input: 0 Column: 1)
            |  |   |
            |  |   |---(Name: Constant Type: intUid: 39)
            |  |
            |  |---A: (Name: LOLoad Schema:x#36:bytearray,y#37:bytearray,z#38:bytearray)RequiredFields:null
            |
            |---B: (Name: LOLoad Schema:t#41:bytearray,u#42:bytearray,v#43:bytearray)RequiredFields:null

LogicalPlan继承自BaseOperatorPlan,如下面代码片段所示,LogicalPlan由一系列Operator组成,fromEdges和toEdges代表有向图的出边和入边,PlanEdge内部实际是一个MultiMap<Operator, Operator>数据结构。

public abstract class BaseOperatorPlan implements OperatorPlan {
    protected List<Operator> ops;
    protected PlanEdge fromEdges;
    protected PlanEdge toEdges;
    ……
}
Operator对应逻辑执行计划中的具体操作步骤。Pig为每种操作都实现了相应的Operator。


在Parse过程中,LogicalPlanBuilder负责构建Operator。Operator中包含名称、Schema、包装成LogicalExpressionPlan的运行参数等信息(以及requestedParallelism、mCustomPartitioner等用户自定义的Hadoop MapReduce运行配置信息)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值