hive是基於hadoop的乙個資料倉儲系統,在各大公司都有廣泛的應用。美團資料倉儲也是基於hive搭建,每天執行近萬次的hive etl計算流程,負責每天數百gb的資料儲存和分析。hive的穩定性和效能對我們的資料分析非常關鍵。
在幾次公升級hive的過程中,我們遇到了一些大大小小的問題。通過向社群的 諮詢和自己的努力,在解決這些問題的同時我們對hive將sql編譯為mapreduce的過程有了比較深入的理解。對這一過程的理解不僅幫助我們解決了 一些hive的bug,也有利於我們優化hive sql,提公升我們對hive的掌控力,同時有能力去定製一些需要的功能。
mapreduce實現基本sql操作的原理
詳細講解sql編譯為mapreduce之前,我們先來看看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的過程如下(這裡只是說明最基本的join的實現,還有其他的實現方式)
group by的實現原理
select rank, isonline, count(*) from city group by rank, isonline;
將groupby的字段組合為map的輸出key值,利用mapreduce的排序,在reduce階段儲存lastkey區分不同的key。mapreduce的過程如下(當然這裡只是說明reduce端的非hash聚合過程)
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即可完成去重
如果有多個distinct欄位呢,如下面的sql
select dealid, count(distinct uid), count(distinct date) from order group by dealid;
實現方式有兩種:
(1)如果仍然按照上面乙個distinct欄位的方法,即下圖這種實現方式,無法跟據uid和date分別排序,也就無法通過lastkey去重,仍然需要在reduce階段在記憶體中通過hash去重
2)第二種實現方式,可以對所有的distinct欄位編號,每行資料生成n行資料,那麼相同欄位就會分別排序,這時只需要在reduce階段記錄lastkey即可去重。
這種實現方式很好的利用了mapreduce的排序,節省了reduce階段去重的記憶體消耗,但是缺點是增加了shuffle的資料量。
需要注意的是,在生成reduce value時,除第乙個distinct欄位所在行需要保留value值,其餘distinct資料行value欄位均可為空。
MapReduce框架原理
mapreduce工作流程 reduce端 2 流程詳解 上面的流程是整個mapreduce最全工作流程,但是shuffle過程只是從第7步開始到第15步結束,具體shuffle過程詳解,如下 1 maptask 收集我們的 map 方法輸出的 kv對,放到記憶體緩衝區中 2 從記憶體緩衝區不斷溢位...
MapReduce 框架原理
1.1 自定義bean物件實現序列化介面 乙個job在map階段並行度由客戶端在提交job時的切片數決定 每乙個split切片分配乙個 maptask 並行例項處理 預設情況,切片大小 blocksize 示例 a.txt line1 rich learning form line2 intelli...
Map Reduce 計算框架(2)
mapreduce的分割槽與reducetask的數量 在mapreduce中,通過指定分割槽,會將同乙個分割槽的資料傳送到同乙個reduce中,例如為了資料的統計,可以把一批類似的資料發 送到同乙個reduce當中去,在同乙個reduce中統計相同型別的資料,就可以實現類似資料的分割槽,統計等 直...