hive mapjoin


 

籠統的說,Hive中的Join可分為Common Join(Reduce階段完成join)和Map Join(Map階段完成join)

一、Hive Common Join

如果不指定MapJoin或者不符合MapJoin的條件,那么Hive解析器會將Join操作轉換成Common Join,即:在Reduce階段完成join.
整個過程包含Map、Shuffle、Reduce階段。

  • Map階段

讀取源表的數據,Map輸出時候以Join on條件中的列為key,如果Join有多個關聯鍵,則以這些關聯鍵的組合作為key;
Map輸出的value為join之后所關心的(select或者where中需要用到的)列;同時在value中還會包含表的Tag信息,用於標明此value對應哪個表;
按照key進行排序

  • Shuffle階段

根據key的值進行hash,並將key/value按照hash值推送至不同的reduce中,這樣確保兩個表中相同的key位於同一個reduce中

  • Reduce階段
    根據key的值完成join操作,期間通過Tag來識別不同表中的數據。

 

 

二、Hive Map Join

1,什么是MapJoin?

MapJoin顧名思義,就是在Map階段進行表之間的連接。而不需要進入到Reduce階段才進行連接。這樣就節省了在Shuffle階段時要進行的大量數據傳輸。從而起到了優化作業的作用。


2,MapJoin的原理:

通常情況下,要連接的各個表里面的數據會分布在不同的Map中進行處理。即同一個Key對應的Value可能存在不同的Map中。這樣就必須等到Reduce中去連接

要使MapJoin能夠順利進行,那就必須滿足這樣的條件:除了一份表的數據分布在不同的Map中外,其他連接的表的數據必須在每個Map中有完整的拷貝。


3,MapJoin適用的場景:


通過上面分析你會發現,並不是所有的場景都適合用MapJoin. 它通常會用在如下的一些情景:在二個要連接的表中,有一個很大,有一個很小,這個小表可以存放在內存中而不影響性能。

這樣我們就把小表文件復制到每一個Map任務的本地,再讓Map把文件讀到內存中待用。

4,MapJoin的實現方法

     1)在Map-Reduce的驅動程序中使用靜態方法DistributedCache.addCacheFile()增加要拷貝的小表文件,。JobTracker在作業啟動之前會獲取這個URI列表,並將相應的文件拷貝到各個TaskTracker的本地磁盤上。
 
     2)在Map類的setup方法中使用DistributedCache.getLocalCacheFiles()方法獲取文件目錄,並使用標准的文件讀寫API讀取相應的文件。
 

5,Hive內置提供的優化機制之一就包括MapJoin。

在Hive v0.7之前,需要使用hint提示 /*+ mapjoin(table) */才會執行MapJoin  。Hive v0.7之后的版本已經不需要給出MapJoin的指示就進行優化。它是通過如下配置參數來控制的:
 
hive> set hive.auto.convert.join=true;
   
Hive還提供另外一個參數--表文件的大小作為開啟和關閉MapJoin的閾值。
 
hive.mapjoin.smalltable.filesize=25000000 即25M

 

 

 三、mapjoin 解決數據傾斜

今天遇到一個hive的問題,如下hive sql:

 

select f.a,f.b from A t join B f  on ( f.a=t.a and f.ftime=20110802)  

該語句中B表有30億行記錄,A表只有100行記錄,而且B表中數據傾斜特別嚴重,有一個key上有15億行記錄,在運行過程中特別的慢,而且在reduece的過程中遇有內存不夠而報錯。

 

為了解決用戶的這個問題,考慮使用mapjoin,mapjoin的原理:

MAPJION會把小表全部讀入內存中,在map階段直接拿另外一個表的數據和內存中表數據做匹配,由於在map是進行了join操作,省去了reduce運行的效率也會高很多

這樣就不會由於數據傾斜導致某個reduce上落數據太多而失敗。於是原來的sql可以通過使用hint的方式指定join時使用mapjoin。

select /*+ mapjoin(A)*/ f.a,f.b from A t join B f  on ( f.a=t.a and f.ftime=20110802) 

再運行發現執行的效率比以前的寫法高了好多。

 

mapjoin還有一個很大的好處是能夠進行不等連接的join操作,如果將不等條件寫在where中,那么mapreduce過程中會進行笛卡爾積,運行效率特別低,

如果使用mapjoin操作,在map的過程中就完成了不等值的join操作,效率會高很多。

例子:

select A.a ,A.b from A join B where A.a>B.a

 

簡單總結一下,mapjoin的使用場景:

1. 關聯操作中有一張表非常小

2.不等值的鏈接操作

 


免責聲明!

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



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