Hadoop怎樣實現二級排序

2021-10-11 18:45:11 字數 1313 閱讀 2112

即對key和value雙排序。預設情況下,map輸出的結果會對key進行預設的排序,但是有時候需要對key排序的同時還需要對value進行排序,這時候就要用到二次排序了。

有兩種方法進行二次排序,分別為:buffer and in memory sort和 value-to-key conversion。

1、buffer and in memory sort

在reduce()函式中,將某個key對應的所有value儲存到記憶體中,然後進行排序。 這種方法最大的缺點是:可能會造成out of memory。

2、value-to-key conversion

既然 mapreduce 框架自帶排序,那麼二次排序中的排序是否可以交給 shuffle 中的 sort 來執行呢?

答案是肯定的,而且 shuffle 的 sort 在大量資料的情況下具有很高的效率。

將key和部分value拼接成乙個組合key,這樣reduce獲取的結果便是先按key排序,後按value排序的結果,需要注意的是,使用者需 要自己實現paritioner,以便只按照key進行資料劃分。hadoop顯式的支援二次排序,在configuration類中有個 setgroupingcomparatorclass()方法,可用於設定排序被group的key值。

shuffle 的 sort 過程會根據鍵值對的 key 進行排序,但是二次排序中,value 也是需要排序的字段。因此需要將 value 字段合併到 key 中作為新的 key,形成新的鍵值對。在排序時使其先根據 key 排序,如果相同,再根據 value 排序。

下圖詳細描述了二次排序的流程,虛線框內為 shuffle 過程:

可以發現,在 map 階段,程式將原本的 key 和 value 組合成乙個新的 key,這是乙個新的資料型別。因此需要在程式中定義該資料型別,為了使它支援排序,還需定義它的比較方式。根據二次排序的規則,比較方式為:先比較第乙個字段,如果相同再比較第二個字段。

map 操作結束後,資料的 key 已經改變,但是分割槽依舊要按照原本的 key 進行,否則原 key 不同的資料會被分到一起。舉個例子,<1#1, 1>、<1#3, 3>、<1#5, 5>應該屬於同乙個分割槽,因為它們的原 key 都是1。如果按照新 key 進行分割槽,那麼可能<1#1, 1>、<1#3, 3>在同乙個分割槽,<1#5, 5>被分到另乙個分割槽。

分割槽和排序結束後進行分組,很顯然分組也是按照原 key 進行

參考:

氣泡排序 二級排序

a a defsort by x0y0 mylist,param print before sorting mylist length len mylist if length 2 print 傳入的列表長度必須大於1 return for i in range length 比較的趟數 flag ...

二級指標排序

define crt secure no warnings include include includevoid print array char a,int n printf n void sort array char a,int n 讓p指向一段記憶體,讓這塊記憶體儲存內容 int main...

HBase 實現二級索引

使用整合mapreduce的方式建立hbase索引。主要的流程如下 1.11.2 獲取rowkey和指定欄位名稱和字段值 1.3建立put例項,value rowkey,rowkey columnname columnvalue 1.4使用identitytablereducer將資料寫入索引表 類...