天天看點

Impala學習--Impala前端代碼分析Impala前端代碼分析

Impala前端代碼分析

Table of Contents

  • 1 概述
  • 2 文法分析和ParseNode
  • 3 Analyzer
  • 4 生成執行計劃和Planner
  • 5 Catalog

1 概述

前端代碼使用java。感覺使用java的原因是,本身文法分析不會占用太多時間,毫秒級可以完成,不是性能瓶頸。而且文法分析的代碼通常比較複雜,邏輯較多,如果再自己管理記憶體的話,會影響開發效率。

Impala通過jni調用前端java代碼,前後端資料傳遞采用thrift格式。

前端的代碼主要包括以下幾個功能:

  • 将使用者送出的query轉換成文法樹,這個通過jflex和cup完成(hive使用的是antlr)
  • 文法分析
  • 生成執行計劃
  • 在編譯中通路中繼資料

2 文法分析和ParseNode

ParseNode定義了一個接口。jflex和cup分析完的文法樹中,每一個節點都實作了這個接口。文法分析就是在這個ParseNode組成的樹中進行的。

ParseNode的實作和繼承關系如下:

  • Expr (表達式)
    • Predicate (謂詞,出現在where語句中)
      • BetweenPredicate
      • BinaryPredicate (=, !=, <=, >=, <, >)
      • CompoundPredicate (&&, ||, !)
      • InPredicate
      • IsNullPredicate
      • LikePredicate
      • LiteralPredicate
        • BoolLiteral
        • DateLiteral
        • FloatLiteral
        • IntLiteral
        • NullLiteral
        • StringLiteral
    • AggregateExpr (count, min, max, distince, sum, avg)
    • ArithmeticExpr (*, /, %, DIV, +, -, &, |, ^, ~)
    • CaseExpr
    • CastExpr
    • FunctionCallExpr
    • LiteralExpr
    • TimestampArithmeticExpr
  • QueryStmt
    • SelectStmt
    • UnionStmt
  • InsertStmt
  • ShowDbStmt
  • ShowTablesStmt
  • DescribeStmt
  • UseStmt
  • TableRef
    • BaseTableRef
    • InlineViewTableRef (alias)

其中,Expr繼承了TreeNode類,可以組成一個求值樹。而其他ParseNode雖然沒有繼承TreeNode,但也都有類似的資料結構。可以通路孩子節點。這樣ParseNode就組成了一顆文法樹。

文法分析階段主要進行了一些基本的文法檢查,類型檢查,并抽取一些資訊,放到Analyzer類中,例如alias映射表等等。

3 Analyzer

Analyzer是文法分析的一個産出。Analyzer用于收集某一個QureyBlock内的資訊。類似Hive中的QB類。

其主要成員變量包括:

  • DescriptorTable descTbl;
  • Catalog catalog;
  • String defaultDb;
  • IdGenerator<ExprId> conjunctIdGenerator;
  • Analyzer parentAnalyzer;
  • Map<String, TupleDescriptor> aliasMap;
  • Map<String, SlotDescriptor> slotRefMap;
  • Map<ExprId, Predicate> conjuncts;
  • Map<TupleId, List<ExprId> > tuplePredicates;
  • Map<SlotId, List<ExprId> > slotPredicates;
  • Map<TupleId, List<ExprId> > eqJoinConjuncts;
  • Set<ExprId> assignedConjuncts;
  • Map<TupleId, TableRef> outerJoinedTupleIds;
  • Map<TableRef, List<ExprId> > conjunctsByOjClouse;
  • Map<ExprId, TableRef> ojClouseByConjunct;
  • Set<ExprId> whereClauseConjuncts;

4 生成執行計劃和Planner

Planner負責将分析後的文法樹轉換成執行計劃,即PlanFragments。

Planner的入口函數是Planner::createPlanFragments()。其主要流程如下:

  • createSinglePlan:

    根據文法分析的結果,周遊并生成一個邏輯執行計劃樹。樹中的節點是PlanNode。樹的根節點是最後被執行的節點。

  • createPlanFragments:

    将生成的執行計劃切割成多個PlanFragment。這個過程類似Hive中将執行計劃分割成多個MapRed階段。目前Impala劃分階段的規則是:如果遇到ScanNode, HashJoinNode, MergeNode, AggregationNode, SortNode,則産生一個新的PlanFragment。每一個PlanFragment之間通過ExchangeNode相連。ExchangeNode在運作時中會負責跨Impalad的資料傳輸。

  • computeMemLayout:

    對于輸入表,計算在記憶體中的layout。主要目的是為了計算一條記錄在記憶體中會占用多少位元組(由TupleDescriptor描述),以及每一個字段在記憶體中如何分布(由SlotDescriptor描述)。

最後PlanFragments就會成為實體執行計劃,轉成thrift後傳回給前端。

5 Catalog

Impala直接使用了Hive的HiveMeteStoreClient類,用于通路中繼資料。這就意味着,必須還要啟動一個HiveMetaStore程序,用于提供中繼資料服務。目前Catalog預設采用lazy模式,隻在需要時加載database和table對象。

Catalog主要在文法分析階段使用,用于擷取Hive中繼資料,目前在Planner中沒有使用Catalog。

Author: <[email protected]>

Date: 2013-02-20 19:43:07 CST

HTML generated by org-mode 6.21b in emacs 23