時隔兩年多,趁晴朗閒暇,把這篇博文補上。
前言
我們知道了MapReduce的執行過程(MapReduce簡介),也瞭解了Hive的基本原理(Hive簡介),也瞭解了Hive在執行時是被轉換爲一個個MR任務去執行,這時,我們一定會好奇,某一條SQL是如何轉化爲MR的,又是如何執行的呢?
下面將從Hive中兩個最基本的語法進行解析:GROUP BY
& JOIN
。
1、 GROUP BY
解析
1.1 初識
我們首先創建一個表TEST
,如下:
name |
---|
Java |
Java |
Hive |
Java |
對於如下一條簡單的 Hive SQL,分析其原理,
SELECT
name
,count(1) AS cnt
FROM TEST
GROUP BY name;
Map階段
將分組字段作爲Key,Value爲該分組下的記錄數量(我們知道Map部分的邏輯可以程序員自己實現,計算相同Key的記錄數很簡單)。
這樣Map的結果如下:
Shuffle階段
該階段會根據key進行sort排序(一般是字典排序),然後分配給不同的reduce去執行下一步操作,結果如下:
Reduce階段
根據Shuffle出的不同key,可知會分配給兩個Reduce,而這裏我們不需要對結果做出進一步操作,因而直接輸出即可,如下:
最終結合到一起,整個流程如下:
看到這裏,也許你會有些疑問,整個結果,在Map階段就已經出現了,Shuffle和Reduce的作用是什麼呢?
1.2 深入
讓我們來想象這樣一種場景,首先,表多加一個字段rank
,同時,這張表非常的龐大,龐大到我們需要兩個Map任務來計算(需要指出的是,Map任務數一般等同於數據所佔Block的數量,而Reduce的數量是和Shuffle之後的Key的數量有關,切不可認爲Map和Reduce任務數量一一對應),這裏我們截取該表中的部分數據進行分析。
name | rank |
---|---|
Java | 1 |
Java | 2 |
Java | 1 |
… | … |
Hive | 2 |
Java | 1 |
Hive | 2 |
… | … |
對於如下一條Hive SQL,分析其原理,
SELECT
name
,rank
,count(1) AS cnt
FROM TEST
GROUP BY name, rank;
Map階段
由於數據量比較多,調用兩個Map任務,因而Map前的split操作結果和Map結果如下:
map階段的Key是group by字段的組合(這裏是name和rank,如果SQL中存在distinct,則是group by字段外加distinct字段的組合)。
Shuffle階段
該階段會根據key進行sort排序(一般是字典排序),然後分配給不同的reduce去執行下一步操作,結果如下:
Reduce階段
根據Shuffle出的不同key,可知會分配給三個Reduce,而針對第二個reduce任務,我們需要進一步的合併計算,因而整個流程如下:
注意:從上述過程中,我們可以發現:
- Map階段接收的數據量和計算量基本是恆定的,不會產生數據傾斜;
- 而Shuffle階段我們基本不能控制,也不存在數據傾斜;
- Reduce階段會根據該key對應的數據量的不同,進行不同的計算量,上例中,第二個reduce需要一次合併計算,而13不需要計算,每個reduce的計算量不同,這便是數據傾斜,而最終的計算時間,取決於最慢的那個reduce。
--------------------------------------------------------- 華麗的分割線 --------------------------------------------------------------
2、 JOIN
解析
話不多說,先來兩個表和一條SQL;
學生成績表t_student
student | rank_id |
---|---|
Arvin | 1 |
Jin | 1 |
Bob | 2 |
成績維表t_rank
rank_id | rank |
---|---|
1 | good |
2 | bad |
SELECT
t.student
,tt.rank
FROM t_student t
JOIN t_rank tt
on t.rank_id = tt.rank_id;
Map階段
將關聯字段作爲Key,Value Table標記(如用1表示t_student,2表示t_rank)和其他顯示字段(student)。
這樣Map的結果如下:
Shuffle階段
該階段會根據key進行sort排序,然後分配給不同的reduce去執行下一步操作,結果如下:
Reduce階段
根據Shuffle出的不同key,可知會分配給兩個Reduce,每個reduce會分遍歷數據,將table標記不同的記錄兩兩組合,並輸出結果,如下:
注意:同group by的注意。
總結
瞭解Hive如何轉化爲MR任務是及其重要的,不僅有助於我們瞭解MR甚至Hadoop,更有助於我們寫出高質量的Hive SQL,防止數據傾斜,希望這篇博文對大家有所幫助 😃