Hive mapreduce SQL實現原理——SQL最終分解為MR任務,而group by在MR里和單詞統計MR沒有區別了


轉自:http://blog.csdn.net/sn_zzy/article/details/43446027

SQL轉化為MapReduce的過程

了解了MapReduce實現SQL基本操作之后,我們來看看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任務的變換,生成最終的執行計划

Join的實現原理

select u.name, o.orderid from order o join user u on o.uid = u.uid;

在map的輸出value中為不同表的數據打上tag標記,在reduce階段根據tag判斷數據來源。MapReduce的過程如下(這里只是說明最基本的Join的實現,還有其他的實現方式)

 MapReduce CommonJoin的實現

Group By的實現原理

select rank, isonline, count(*) from city group by rank, isonline;

將GroupBy的字段組合為map的輸出key值,利用MapReduce的排序,在reduce階段保存LastKey區分不同的key。MapReduce的過程如下(當然這里只是說明Reduce端的非Hash聚合過程)

 MapReduce Group By的實現

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的實現

如果有多個distinct字段呢,如下面的SQL

select dealid, count(distinct uid), count(distinct date) from order group by dealid;

實現方式有兩種:

(1)如果仍然按照上面一個distinct字段的方法,即下圖這種實現方式,無法跟據uid和date分別排序,也就無法通過LastKey去重,仍然需要在reduce階段在內存中通過Hash去重

 MapReduce Multi Distinct的實現

(2)第二種實現方式,可以對所有的distinct字段編號,每行數據生成n行數據,那么相同字段就會分別排序,這時只需要在reduce階段記錄LastKey即可去重。

這種實現方式很好的利用了MapReduce的排序,節省了reduce階段去重的內存消耗,但是缺點是增加了shuffle的數據量。

需要注意的是,在生成reduce value時,除第一個distinct字段所在行需要保留value值,其余distinct數據行value字段均可為空。

 MapReduce Multi Distinct的實現

 


免責聲明!

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



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