通過Map Reduce實現Join系列之三

2021-09-01 18:47:25 字數 2124 閱讀 3618

在這個系列的前兩篇中,介紹了基本的join演算法以及在hadoop環境中,如何利用map-reduce過程來完成join。而前面的介紹都是基於兩個集合的join,本文將會介紹利用map-reduce來完成2個以上檔案的join的相關演算法(multi-way join algorithms)。基本的思路與第二篇文章中介紹的map-reduce join類似,根據將這個演算法擴充套件到多個檔案的方式,可以分為兩種,一種是使用乙個map-reduce任務完成所有檔案的join,另外乙個中使用多個任務來完成多個檔案的join。 

1.使用單個map-reduce任務完成join

這種演算法可以看作是第二篇中提到的基於乙個完整的map-reduce來完成join的演算法的擴充套件。比如,有n個資料檔案需要join,他們分別是t1(a1,b),t2(a2,b),t3(a3,b),....,tn(an,b),需要在b列上進行join。

map階段從每個檔案讀取資料,然後根據一定的規則為不同**的資料打上標記,然後以b列的值為key,將資料寫出到中間檔案中。

所有在b列上具有相同值的來自不同檔案的記錄會被同乙個reducer進行處理。在第二篇的介紹中,對於兩個檔案的join,reducer在呼叫reduce方法之前,會對同乙個key下面的資料進行排序,保證來自於乙個檔案的所有資料會優先與另外乙個檔案的資料,對於多個檔案的join,這一點也同樣需要得到保證。通過自定義reducer端的分組和排序方式,可以達到這樣的效果。recude方法將同乙個key下來自於前n-1個檔案的資料全部讀到記憶體快取起來,當讀第n個檔案的資料時,開始進行執行join操作,並將結果寫出到結果檔案中。 

這種演算法的優點在於可以通過乙個map-reduce任務完成所有資料檔案的join,同時,產生的零時檔案也是最少的,比較節省hdfs的磁碟空間。但是這個演算法存在乙個最大的劣勢,reducer階段需要快取大量的資料,當需要進行join的資料檔案個數比較多時,很容易產生記憶體的不足的情況。雖然可以將快取的資料進行切分,放入磁碟,但是這樣做會帶來效能上的損失,同時也增加了演算法的複雜度。 

2.使用多個map-reduce任務完成join

除了上面說的將多個檔案的join放到乙個map-reduce任務中去完成之外,我們還可以將多個檔案的join切分成多個不同的map-reduce任務去執行。例如, 有n個資料檔案需要join,他們分別是t1(a1,b),t2(a2,b),t3(a3,b),....,tn(an,b),需要在b列上進行join。我們可以將t1和t2進行join,然後將其結果與t3進行join,以此類推,最終完成n個資料檔案的join操作。 

這種join方式適用於任何大小任何資料量的檔案之間的join,而且相比於第一種方式,單個map-reduce任務需要處理的資料量小了很多。但是,由於需要實用多個map-reduce任務來完成join,這種方式會產生很多的中間檔案,占用hdfs的磁碟空間,同時對整個hadoop集群帶來的壓力也比第一種方式要高很多。

簡單的每次join兩個資料檔案的方式其實是非常低效的,不僅消耗儲存資源,對計算資源的消耗也非常巨大,下面有集中方式可以來優化多map-reduce任務的join。 

第二,可以通過優化資料檔案的join順序來提高效率。這種優化主要通過衡量兩個資料檔案join之後可能產生的資料量來決定各個資料檔案的join順序。join之後產生的資料量最小的兩個檔案將被有限進行join,以此類推。現在考慮如下的兩個資料集合: 

這兩個檔案join之後的結果如下: 

資料的記錄數可以通過下面的公式得到: 

其中,t(k)表示資料檔案t中,join條件用到的列上,具有k值的記錄條數。 

在上面給出的例子中,通過計算,我們可以得到這兩個資料集合join之後,將會產生的記錄數是: 

1 x 1 + 2 x 1 + 1 x 2 = 5 

只要我們能夠找出每個資料檔案中包含的key的數量,已經每個key下面對應的記錄的條數,我們可以很容易的決定各個資料檔案之間的join順序。這個計算我們可以放到乙個資料的預處理過程中,然後將預處理的結果存到hdfs上的乙個指定檔案中,當執行多檔案join時,首先讀取這個檔案,然後根據檔案內容逐個兩兩join不同的資料檔案。 

第三,在知道了不同檔案join之後所產生的資料量之後,我們可以在乙個map-reduce任務中盡量多地join幾個資料檔案,而不是每次只join兩個資料檔案,這樣做也可以起到一定的節省儲存和計算資源的效果。

**:

如何使用MapReduce實現兩表的join

map join map side join 是針對一下場景進行的優化。兩個待連線的表中,有乙個表非常大,而另乙個非常小,以至於小表可以直接存放到記憶體中。這樣,我們可以將小表複製多份,讓每乙個map task記憶體中存在乙份 比如放在hash table中 然後只掃瞄大表 對於大表中的每一條記錄k...

如何使用MapReduce實現兩表的join

map join map side join 是針對一下場景進行的優化。兩個待連線的表中,有乙個表非常大,而另乙個非常小,以至於小表可以直接存放到記憶體中。這樣,我們可以將小表複製多份,讓每乙個map task記憶體中存在乙份 比如放在hash table中 然後只掃瞄大表 對於大表中的每一條記錄k...

如何使用MapReduce實現兩表的join

map join map side join 是針對一下場景進行的優化。兩個待連線的表中,有乙個表非常大,而另乙個非常小,以至於小表可以直接存放到記憶體中。這樣,我們可以將小表複製多份,讓每乙個map task記憶體中存在乙份 比如放在hash table中 然後只掃瞄大表 對於大表中的每一條記錄k...