HQL 轉化 MapReduce的過程(源碼篇)


轉自    窩窩頭

我們學習hive的時候 都知道hive 是基於Hadoop的一個數據倉庫工具,可以將結構化的數據文件映射為一張表,並提供類SQL查詢功能 它的本質是:將HQL轉化成MapReduce程序

這篇文章就是從源碼角度看看 hive的底層是如何進行轉化的

為了能更好的理解源碼 需要先了解如下文字流程

SQL轉化為MapReduce任務的,整個編譯過程分為六個階段:

1.Antlr定義SQL的語法規則,完成SQL詞法,語法解析,將SQL轉化為抽象語法樹AST Tree
2.遍歷AST Tree,抽象出查詢的基本組成單元QueryBlock
3.遍歷QueryBlock,翻譯為執行操作樹OperatorTree
4.邏輯層優化器進行OperatorTree變換,合並不必要的ReduceSinkOperator,減少shuffle數據量
5.遍歷OperatorTree,翻譯為MapReduce任務
6.物理層優化器進行MapReduce任務的變換,生成最終的執行計划

接下來就開始看源碼 一點點找到上述流程對應的位置

image.png

image.png

首先CliDriver類是hive的入口 先看一下它的main方法

image.png

image.png

image.png

點進去 會發現一塊代碼專門處理 記錄歷史指令

image.png

image.png

image.png

記錄歷史指令的代碼下面 會看到一處while循環 不停的讀取命令執行

image.png

image.png

image.png

image.png

image.png

image.png

processLocalCmd 這個方法有4個主要流程

image.png

image.png

image.png

這樣就跟hive中查詢到的結果有了匹配 如下

image.png

既然數據都查出來 並且展示了 那么還是沒有看到是哪塊代碼進行轉化的

這里就需要看一下流程1的部分 里面包含了復雜的邏輯 下面一點點進行分析 底層是如何解析sql 然后一步步轉化Mapreduce 最后查詢結果的

image.png

image.png

而runInternal這個方法 又包含兩個步驟 一個是編譯 一個是執行

image.png

image.png

image.png

compile 里面包含三個步驟

image.png

image.png

image.png

第一個步驟點進去 會看到

image.png

這里是靠antlr 的解析器對sql語句轉化成 抽象語法樹 ASTNode 如果想對antlr有過多的了解 根據下面鏈接 自行了解 這里不深入說明
antlr :https://baike.baidu.com/item/antlr/9368750?fr=aladdin

第二個步驟點進去 會看到

image.png

image.png

analyzeInternal 這個方法設計的很有意思 它包含了11個步驟 並且作者每個步驟處都寫好了注釋 一個個分開說明 下面來看一下這11個小步驟都干了什么

image.png

image.png

image.png

image.png

這里可以了解一下 Operator:

Operator
Hive最終生成的MapReduce任務,Map階段和Reduce階段均由OperatorTree組成。邏輯操作符,就是在Map階段或者Reduce階段完成單一特定的操作。
基本的操作符包括TableScanOperator,SelectOperator,FilterOperator,JoinOperator,GroupByOperator,ReduceSinkOperator
從名字就能猜出各個操作符完成的功能,TableScanOperator從MapReduce框架的Map接口原始輸入表的數據,控制掃描表的數據行數,標記是從原表中取數據。JoinOperator完成Join操作。FilterOperator完成過濾操作
ReduceSinkOperator將Map端的字段組合序列化為Reduce Key/value, Partition Key,只可能出現在Map階段,同時也標志着Hive生成的MapReduce程序中Map階段的結束。
Operator在Map Reduce階段之間的數據傳遞都是一個流式的過程。每一個Operator對一行數據完成操作后之后將數據傳遞給childOperator計算。
Operator類的主要屬性和方法如下
RowSchema表示Operator的輸出字段
InputObjInspector outputObjInspector解析輸入和輸出字段
processOp接收父Operator傳遞的數據,forward將處理好的數據傳遞給子Operator處理
Hive每一行數據經過一個Operator處理之后,會對字段重新編號,colExprMap記錄每個表達式經過當前Operator處理前后的名稱對應關系,在下一個階段邏輯優化階段用來回溯字段名
由於Hive的MapReduce程序是一個動態的程序,即不確定一個MapReduce Job會進行什么運算,可能是Join,也可能是GroupBy,所以Operator將所有運行時需要的參數保存在OperatorDesc中,OperatorDesc在提交任務前序列化到HDFS上,在MapReduce任務執行前從HDFS讀取並反序列化。Map階段OperatorTree在HDFS上的位置在Job.getConf(“hive.exec.plan”) + “/map.xml”

image.png

image.png

image.png

image.png

image.png

image.png

總結 上面這11小個步驟 驗證了前面的文字流程

遍歷AST Tree,抽象出查詢的基本組成單元QueryBlock(步驟1)
遍歷QueryBlock,翻譯為執行操作樹OperatorTree(步驟2)
邏輯層優化器進行OperatorTree變換,合並不必要的ReduceSinkOperator,減少shuffle數據量(步驟7)

在這些步驟走完之后 compileInternal方法會生成一個執行計划 交給execute方法處理 接下來就看execute方法如何轉換MapReduce

image.png

有幾個點需要注意一下

image.png

下面基本就是轉換MapReduce的入口了 后面詳解

image.png

image.png

image.png

由此 基本可以了解HQl轉換MapReduce的整個流程 先是做一些判斷處理 然后處理sql 再切分遍歷執行每條sql 然后先通過antlr 根據語法文件 生成語法 詞法解析器 將sql解析成抽象語法樹 ASTNode 再將它解析成QB 然后翻譯成一個個的OperatorTree 接下來處理一下邏輯優化 最后生成執行計划 交給execute執行 它將task取出 放入隊列然后一個個提交任務 最后得出結果 打印ok 最后對返回數據的控制台打印處理。

整體流程說完了 接下來詳細說明一下 轉換MapReduce的入口

image.png

image.png

image.png

execute 這個方法很重要 根據task的類型不同 進行不同計算引擎的任務提交

image.png

先看一下MR

image.png

image.png

image.png

image.png

再看一下 Spark 我們都知道hive-on-Spark的說法 那么底層調用也是在這里

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

TezTask 不再贅述。

總結:hive的源碼還是值得去學習和思考的

前面通過不同的Task類型 進行可插拔的多計算引擎的選擇

不同的類型 不同的提交邏輯 提高程序的高擴展性。

最后附上完整流程圖

image.png


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM