Hadoop學(xué)習(xí)筆記 Partitioner與自定義Partitioner

一、初識Partitioner

? ? ? ? 在認(rèn)識Partitioner之前我們先來回顧一下MapReduce流程中,Map階段的五個(gè)步驟。如下圖所示:


map流程圖

? ? ? ? 我們可以通過上圖看到step1.3就是一個(gè)Partition操作。其主要作用是計(jì)算應(yīng)該將哪些Key放到同一個(gè)Reduce中去。其次從圖上我們可以得知Partition的操作是基于map的輸出結(jié)果的,而且分區(qū)操作的對象是key。

? ? ? ? 接下來讓我們一起看看官方文檔對這個(gè)Partition的解讀吧。


Apache官方文檔

? ? ? ? 該文檔主要描述了:Partition的主類名為Class Partitioner<KEY,VALUE>其直屬子類有BinaryPartitioner,?HashPartitioner,?KeyFieldBasedPartitioner,?TotalOrderPartitioner這幾個(gè)類。

? ? ? ? 并且說明了Partitioner直接采用了map的輸出,其中分區(qū)的典型方式是使用hash函數(shù)進(jìn)行分區(qū)將key相同的數(shù)據(jù)分為一組。上述的其子類?HashPartitioner就實(shí)現(xiàn)了這個(gè)功能。

/** Partition keys by their {@link Object#hashCode()}. */

public class HashPartitioner<K, V> extends Partitioner<K, V> {

/** Use {@link Object#hashCode()} to partition. */

public int getPartition(K key, V value, int numReduceTasks){

return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;

}

}//其中key和value為map輸出,numReduceTasks是reduce的數(shù)量。

? ? ? ? 我們可以看到上面的代碼中最關(guān)鍵的一行為:key.hashCode() & Integer.MAX_VALUE) % numReduceTasks。那么為什么要用hashcode與上最大整形呢?這是因?yàn)槿绻鸎ey為Text的話,Text的hashcode方法跟String的基本一致,都是采用的Horner公式計(jì)算,得到一個(gè)int整數(shù)。但是,如果string太大的話這個(gè)int整數(shù)值可能會溢出變成負(fù)數(shù),所以和整數(shù)的上限值Integer.MAX_VALUE(即0111111111111111)進(jìn)行與運(yùn)算,然后再對reduce任務(wù)個(gè)數(shù)取余,這樣就可以讓key均勻分布在reduce上。?

二、自定義Partitioner

現(xiàn)在我們有一下天氣數(shù)據(jù),我們需要按要求將每年的最高氣溫找出來。

1949-10-01 14:21:02 34C

1949-10-02 14:21:12 36C

1950-02-02 11:21:12 32C

1950-05-02 11:31:12 37C

1951-12-02 11:31:12 23C

1950-12-02 11:31:12 47C

1950-12-02 11:31:12 27C

1951-06-02 11:31:12 48C

1951-07-02 11:31:12 45C

如果需要將每年的最高氣溫找出,那我們就必然需要將氣溫?cái)?shù)據(jù)按年分組。

public class wdPartitioner extends Partitioner<Text, Text>{

@Override public int getPartition(Text key, Text value, int numReduceTasks) {

?String str = key.toString().split("-")[0];

int num = Integer.parseInt(str);

if(num == 1949){ return 1%numReduceTasks; }

else if(num == 1950) { return 2%numReduceTasks; }

else if(num == 1951){ return 3%numReduceTasks; }

return 1%numReduceTasks; }

}

可以看到這里由于年份只有這三年所以就按照年份來進(jìn)行判斷了,如果年份較多需要分成很多組那么就可以寫成return (num.hashCode() & Integer.MAX_VALUE) % numReduceTasks;在處理不同的數(shù)據(jù)的時(shí)候我們可以繼承不同的子類以方便我們運(yùn)算。其子類用法請參考


Hadoop Partition用法

總結(jié):分區(qū)Partitioner主要作用在于以下兩點(diǎn)

(1)根據(jù)業(yè)務(wù)需要,產(chǎn)生多個(gè)輸出文件;

(2)多個(gè)reduce任務(wù)并發(fā)運(yùn)行,提高整體job的運(yùn)行效率;

(3)好的Partition可以有效的避免數(shù)據(jù)傾斜;

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容