為什麼需要二次排序?
在mapreduce操作時,我們知道傳遞的會按照key的大小進行排序,最後輸出的結果是按照key排過序的。有的時候我們在key排序的基礎上,對value也進行排序。這種需求就是二次排序:
解決思路:
我們可以把key和value聯合起來作為新的key,記作newkey。這時,newkey含有兩個字段,假設分別是k,v。這裡的k和v是原來的key和value。原來的value還是不變。這樣,value就同時在newkey和value的位置。我們再實現newkey的比較規則,先按照key排序,在key相同的基礎上再按照value排序。在分組時,再按照原來的key進行分組,就不會影響原有的分組邏輯了。最後在輸出的時候,只把原有的key、value輸出,就可以變通的實現了二次排序的需求.
案例原始碼資料:
1 自定義key。
mr中的分割槽和分組都和key相關,所有的key是需要被比較和排序的,需要二次排序時,先根據key中的第乙個屬性進行比較排序,第乙個屬性相同時,在第乙個屬性相同的情況下,再進行下乙個的比較和排序;(程式設計師必知的8大排序:
所有自定義的key應該實現介面writablecomparable,因為是可序列的並且可比較的。並過載方法
2自定義分割槽類(繼承partitionner).
2.1 自定義分割槽函式類繼承partitioner。(第一次比較)。
在job中設定使用setpartitionerclasss
2.2 key比較函式類需要繼承writablecomparator(第二次比較)
。public
class pairwritableimplementswritablecomparable<pairwritable>
//在第乙個字段
name
一樣的情況下比較
money,
基本資料型別是沒有
compareto
,需要裝箱成包裝類
//return(float.valueof(this.money)).compareto(float.valueof(o.money));
returnfloat.valueof(o.money).compareto(float.valueof(
this
.money));
}
}
public static class keycomparator extends writablecomparator
必須有乙個建構函式,並且過載 public int compare(writablecomparable w1, writablecomparable w2)
另一種方法是 實現介面rawcomparator。
在job中設定使用setsortcomparatorclass。
3自定義分組函式類,需要繼承writablecomparator。
public static class groupingcomparator extends writablecomparator
必須有乙個建構函式,並且過載 public int compare(writablecomparable w1, writablecomparable w2)
分組函式類另一種方法是實現介面rawcomparator。
在job中設定使用setgroupingcomparatorclass。
另外注意的是,如果reduce的輸入與輸出不是同一種型別,則不要定義combiner也使用reduce,因為combiner的輸出是reduce的輸入。除非重新定義乙個combiner。
mapreduce二次排序案例
為什麼需要二次排序?在mapreduce操作時,我們知道傳遞的會按照key的大小進行排序,最後輸出的結果是按照key排過序的。有的時候我們在key排序的基礎上,對value也進行排序。這種需求就是二次排序 解決思路 我們可以把key和value聯合起來作為新的key,記作newkey。這時,newk...
MapReduce二次排序
預設情況下,map輸出的結果會對key進行預設的排序,但個別需求要求對key排序的同時還需要對value進行排序 這時候就要用到二次排序了。本章以hadoop權威指南中計算每年最大氣溫值為例,原始資料雜亂無章 2008 33 2008 23 2008 43 2008 24 2008 25 2008 ...
Map reduce二次排序
map reduce的流程切面 splitmapperpartitioncombinergroupreducer 這裡要解釋下 partition 和 group 它們都是shuffle的重要步驟 的區別.他們的作用都是為了reducer分配記錄去處理.但區別是partition是把記錄分給不同的r...