Hive是什么?Hive 是數據倉庫工具,再具體點就是一個 SQL 解析引擎,因為它即不負責存儲數據,也不負責計算數據,只負責解析 SQL,記錄元數據。
Hive直接訪問存儲在 HDFS 中或者 HBase 中的文件,通過 MapReduce、Spark 或 Tez 執行查詢。
我們今天來聊的就是 Hive 底層是怎樣將我們寫的 SQL 轉化為 MapReduce 等計算引擎可識別的程序。了解 Hive SQL 的底層編譯過程有利于我們優化Hive SQL,提升我們對Hive的掌控力,同時有能力去定制一些需要的功能。
我們先來看下 Hive 的底層執行架構圖, Hive 的主要組件與 Hadoop 交互的過程:
Hive底層執行架構
在 Hive 這一側,總共有五個組件:
上圖的基本流程是:
步驟1:UI 調用 DRIVER 的接口;
步驟2:DRIVER 為查詢創建會話句柄,并將查詢發送到 COMPILER(編譯器)生成執行計劃;
步驟3和4:編譯器從元數據存儲中獲取本次查詢所需要的元數據,該元數據用于對查詢樹中的表達式進行類型檢查,以及基于查詢謂詞修建分區;
步驟5:編譯器生成的計劃是分階段的DAG,每個階段要么是 map/reduce 作業,要么是一個元數據或者HDFS上的操作。將生成的計劃發給 DRIVER。
如果是 map/reduce 作業,該計劃包括 map operator trees 和一個 reduce operator tree,執行引擎將會把這些作業發送給 MapReduce :
步驟6、6.1、6.2和6.3:執行引擎將這些階段提交給適當的組件。在每個 task(mapper/reducer) 中,從HDFS文件中讀取與表或中間輸出相關聯的數據,并通過相關算子樹傳遞這些數據。最終這些數據通過序列化器寫入到一個臨時HDFS文件中(如果不需要 reduce 階段,則在 map 中操作)。臨時文件用于向計劃中后面的 map/reduce 階段提供數據。
步驟7、8和9:最終的臨時文件將移動到表的位置,確保不讀取臟數據(文件重命名在HDFS中是原子操作)。對于用戶的查詢,臨時文件的內容由執行引擎直接從HDFS讀取,然后通過Driver發送到UI。
編譯 SQL 的任務是在上節中介紹的 COMPILER(編譯器組件)中完成的。Hive將SQL轉化為MapReduce任務,整個編譯過程分為六個階段:
Hive SQL編譯過程
Antlr是一種語言識別的工具,可以用來構造領域語言。使用Antlr構造特定的語言只需要編寫一個語法文件,定義詞法和語法替換規則即可,Antlr完成了詞法分析、語法分析、語義分析、中間代碼生成的過程。
為便于理解,我們拿一個簡單的查詢語句進行展示,對5月23號的地區維表進行查詢:
select * from dim.dim_region where dt = '2021-05-23';
階段一:詞法、語法解析
根據Antlr定義的sql語法規則,將相關sql進行詞法、語法解析,轉化為抽象語法樹AST Tree:
ABSTRACT SYNTAX TREE:TOK_QUERY TOK_FROM TOK_TABREF TOK_TABNAME dim dim_region TOK_INSERT TOK_DESTINATION TOK_DIR TOK_TMP_FILE TOK_SELECT TOK_SELEXPR TOK_ALLCOLREF TOK_WHERE = TOK_TABLE_OR_COL dt '2021-05-23'
階段二:語義解析
遍歷AST Tree,抽象出查詢的基本組成單元QueryBlock:
AST Tree生成后由于其復雜度依舊較高,不便于翻譯為mapreduce程序,需要進行進一步抽象和結構化,形成QueryBlock。
QueryBlock是一條SQL最基本的組成單元,包括三個部分:輸入源,計算過程,輸出。簡單來講一個QueryBlock就是一個子查詢。
QueryBlock的生成過程為一個遞歸過程,先序遍歷 AST Tree ,遇到不同的 Token 節點(理解為特殊標記),保存到相應的屬性中。
階段三:生成邏輯執行計劃
遍歷QueryBlock,翻譯為執行操作樹OperatorTree:
Hive最終生成的MapReduce任務,Map階段和Reduce階段均由OperatorTree組成。
基本的操作符包括:
Operator在Map Reduce階段之間的數據傳遞都是一個流式的過程。每一個Operator對一行數據完成操作后之后將數據傳遞給childOperator計算。
由于Join/GroupBy/OrderBy均需要在Reduce階段完成,所以在生成相應操作的Operator之前都會先生成一個ReduceSinkOperator,將字段組合并序列化為Reduce Key/value, Partition Key。
階段四:優化邏輯執行計劃
Hive中的邏輯查詢優化可以大致分為以下幾類:
階段五:生成物理執行計劃
生成物理執行計劃即是將邏輯執行計劃生成的OperatorTree轉化為MapReduce Job的過程,主要分為下面幾個階段:
階段六:優化物理執行計劃
Hive中的物理優化可以大致分為以下幾類:
經過以上六個階段,SQL 就被解析映射成了集群上的 MapReduce 任務。
在階段五-生成物理執行計劃,即遍歷 OperatorTree,翻譯為 MapReduce 任務,這個過程具體是怎么轉化的呢
我們接下來舉幾個常用 SQL 語句轉化為 MapReduce 的具體步驟:
以下面這個SQL為例,講解 join 的實現:
select u.name, o.orderid from order o join user u on o.uid = u.uid;
在map的輸出value中為不同表的數據打上tag標記,在reduce階段根據tag判斷數據來源。MapReduce的過程如下:
MapReduce CommonJoin的實現
以下面這個SQL為例,講解 group by 的實現:
select rank, isonline, count(*) from city group by rank, isonline;
將GroupBy的字段組合為map的輸出key值,利用MapReduce的排序,在reduce階段保存LastKey區分不同的key。MapReduce的過程如下:
MapReduce Group By的實現
以下面這個SQL為例,講解 distinct 的實現:
select dealid, count(distinct uid) num from order group by dealid;
當只有一個distinct字段時,如果不考慮Map階段的Hash GroupBy,只需要將GroupBy字段和Distinct字段組合為map輸出key,利用mapreduce的排序,同時將GroupBy字段作為reduce的key,在reduce階段保存LastKey即可完成去重:
MapReduce Distinct的實現
本文鏈接:http://www.tebozhan.com/showinfo-26-88727-0.htmlHive SQL底層執行過程詳細剖析
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com