天天看點

Hive源碼分析:Driver類運作過程概括Driver初始化總結

說明:

本文的源碼分析基于hive-0.12.0-cdh5.0.1。

Driver類的主要作用是用來編譯并執行hive指令,然後傳回執行結果。這裡主要分析Driver類的運作邏輯,其時序圖如下:

從時序圖上可以看出有以下步驟:

run方法調用内部方法runInternal

在runInternal方法内部先,調用HiveDriverRunHookContext的preDriverRun方法

調用compileInternal方法

compileInternal方法内部調用compile方法

compile方法内,先調用HiveSemanticAnalyzerHookContext的preAnalyze方法

再進行文法分析,調用BaseSemanticAnalyzer的analyze方法

調用HiveSemanticAnalyzerHookContext的postAnalyze方法

再進行文法校驗,調用BaseSemanticAnalyzer的validate方法

compileInternal方法運作完成之後,調用checkConcurrency方法

再來運作execute方法,該方法用于運作任務

最後,調用HiveDriverRunHookContext的postDriverRun方法

在繼續分析之前,需要弄清楚Driver類初始化時做了什麼事情。

在CliDriver的<code>processCmd(String cmd)</code>方法中可以看到proc是在CommandProcessorFactory類中new出來的并調用了init方法。

CommandProcessorFactory.get方法代碼片段:

init方法和構造方法代碼如下:

從上可以看出僅僅是初始化了conf屬性和重置了Operator的id。

1、調用runInternal方法,根據該方法傳回值判斷是否出錯。

2、runInternal方法内,運作HiveDriverRunHook的前置方法preDriverRun

3、判斷是否需要編譯,如果需要,則運作<code>compileInternal(command)</code>方法,并根據傳回值判斷是否該釋放Hive鎖。hive中可以配置<code>hive.support.concurrency</code>值為true并設定zookeeper的伺服器位址和端口,基于zookeeper實作分布式鎖以支援hive的多并發通路。這部分内容不是本文重點故不做介紹。

<code>compileInternal(command)</code>方法内部代碼說明見下文。

4、判斷是否需要對Task加鎖。如果需要,則調用checkConcurrency方法。

5、調用execute()方法執行任務。

執行計劃開始:<code>plan.setStarted();</code>

先運作ExecuteWithHookContext的前置hook方法,ExecuteWithHookContext類型有三種:前置、運作失敗、後置。

然後建立DriverContext用于維護正在運作的task任務,正在運作的task任務會添加到隊列runnable中去。

其次,在while循環中周遊隊列中的任務,然後啟動任務讓其執行,并且輪訓任務執行結果,如果任務運作完成,則将其從running中删除并将目前任務的子任務加入隊列中;如果運作失敗,則會啟動備份的任務,并運作失敗的hook。

在launchTask方法中,先判斷是否支援并發執行,如果支援則調用TaskRunner的start()方法,否則調用<code>tskRun.runSequential()</code>方法順序執行,隻有當是MapReduce任務時,才執行并發執行:

最後任務的執行情況,就要看具體的<code>Task&lt;? extends Serializable&gt;</code>的實作類的邏輯了。

執行計劃完成:<code>plan.setDone();</code>

6、運作HiveDriverRunHook的後置方法postDriverRun

1、儲存目前查詢狀态

QueryState中儲存了HiveOperation以及目前查詢語句或者指令。

2、建立Context上下文

3、建立ParseDriver對象,然後解析指令、生成AST樹。文法和詞法分析内容,不是本文重點故不做介紹。

簡單歸納來說,解析程包括如下:

詞法分析,生成AST樹,ParseDriver完成。

分析AST樹,AST拆分成查詢子塊,資訊記錄在QB,這個QB在下面幾個階段都需要用到,SemanticAnalyzer.doPhase1完成。

從metastore中擷取表的資訊,SemanticAnalyzer.getMetaData完成。

生成邏輯執行計劃,SemanticAnalyzer.genPlan完成。

優化邏輯執行計劃,Optimizer完成,ParseContext作為上下文資訊進行傳遞。

生成實體執行計劃,SemanticAnalyzer.genMapRedTasks完成。

實體計劃優化,PhysicalOptimizer完成,PhysicalContext作為上下文資訊進行傳遞。

4、讀取環境變量,如果配置了文法分析的hook,參數為:<code>hive.semantic.analyzer.hook</code>,則:先用反射得到<code>AbstractSemanticAnalyzerHook</code>的集合,調用<code>hook.preAnalyze(hookCtx, tree)</code>方法,然後再調用<code>sem.analyze(tree, ctx)</code>方法,該方法才是用來作文法分析的,最後再調用<code>hook.postAnalyze(hookCtx, tree)</code>方法執行一些使用者定義的後置操作;

否則,直接調用<code>sem.analyze(tree, ctx)</code>進行文法分析。

5、校驗執行計劃:<code>sem.validate()</code>

6、建立查詢計劃QueryPlan。

7、初始化FetchTask。

8、得到schema

9、授權校驗工作。

上面分析中,提到了hive的hook機制,hive中一共存在以下幾種hook。

通過hook機制,可以在運作前後做一些使用者想做的事情。如:你可以在文法分析的hook中對hive的操作做一些超級管理者級别的權限判斷;你可以對hive-server2做一些session級别的控制。

本文主要介紹了hive運作過程,包括hive文法詞法解析以及hook機制,任務的最後運作過程取決于具體的<code>Task&lt;? extends Serializable&gt;</code>的實作類的邏輯。關于hive文法詞法解析,這一部分沒有做詳細的解釋。

hive Driver類的執行過程如下(該圖是根據hive-0.11版本畫出來的):