Hadoop值Partition分區


分區操作

為什么要分區?

要求將統計結果按照條件輸出到不同文件中(分區)。比如:將統計結果按
照手機歸屬地不同省份輸出到不同文件中(分區)

默認 partition 分區

/**
	源碼中:numReduceTasks如果等於1 不會走getPartition方法
	numReduceTasks:默認是1
*/
public class HashPartitioner<K, V> extends Partitioner<K, V> {
	public int getPartition(K key, V value, int numReduceTasks) {
		return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;
	}
}

默認分區是根據 key 的 hashCode 對 reduceTasks 個數取模得到的。
用戶沒法控制哪個key 存儲到哪個分區

自定義Partition

(1)自定義類繼承 Partitioner,重寫 getPartition()方法

/**
	該方法返回不同的partition的值,從而就控制了分區個數、前提是numReduceTasks不等於1
	KV:是Map的輸出
*/
public class ProvincePartitioner extends Partitioner<Text, FlowBean> {
	@Override
	public int getPartition(Text key, FlowBean value, int numPartitions) {
		// 1 獲取電話號碼的前三位
		String preNum = key.toString().substring(0, 3);
		int partition = 4;
		// 2 判斷是哪個省
		if ("136".equals(preNum)) {
			partition = 0;
		}else if ("137".equals(preNum)) {
			partition = 1;
		}else if ("138".equals(preNum)) {
			partition = 2;
		}else if ("139".equals(preNum)) {
			partition = 3;
		}
		return partition;
	}
}

(2)在Runner類中設置partition

job.setPartitionerClass(CustomPartitioner.class);

(3)自定義 partition 后,要根據自定義 partitioner 的邏輯設置相應數量的 reduce task

job.setNumReduceTasks(5);

(4)注意:

如果 reduceTask 的數量 > getPartition 的結果數,則會多產生幾個空的輸出文件part-r-000xx;

如果 1 < reduceTask的數量 < getPartition 的結果數,則有一部分分區數據無處安放,會Exception;

如果 reduceTask 的數量 = 1,則不管 mapTask 端輸出多少個分區文件,最終結果都交給這一個 reduceTask,
最終也就只會產生一個結果文件 part-r-00000;

例如:假設自定義分區數為 5,則
(1)job.setNumReduceTasks(1);會正常運行,只不過會產生一個輸出文件
(2)job.setNumReduceTasks(2);會報錯
(3)job.setNumReduceTasks(6);大於 5,程序會正常運行,會產生空文件

本博客僅為博主學習總結,感謝各大網絡平台的資料。蟹蟹!!


免責聲明!

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



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