Hadoop的Partitioner
Hadoop的Partitioner
MapReduce的使用者通常會指定Reduce任務和Reduce任務輸出檔案的數量(R)。我們在中間key上使用分割槽函式來對資料進行分割槽,之後再輸入到後續任務執行程式。一個預設的分割槽函式是使用hash方法(比如,hash(key) mod R)進行分割槽。hash方法能產生非常平衡的分割槽。然而,有的時候,其它的一些分割槽函式對key值進行的分割槽將非常有用。比如,輸出的key值是URLs,我們希望每個主機的所有條目保持在同一個輸出檔案中。為了支援類似的情況,MapReduce庫的使用者需要提供專門的分割槽函式。例如,使用“hash(Hostname(urlkey)) mod R”作為分割槽函式就可以把所有來自同一個主機的URLs儲存在同一個輸出檔案中。
/**
* to keep sort as global
*
* @author hadoop
*
*/
public static class Partition extends Partitioner<IntWritable, IntWritable> {
@Override
public int getPartition(IntWritable key, IntWritable value,
int numPartitions) {
int MaxNumber = 65223;
int bound = MaxNumber / numPartitions + 1;
int keynumber = key.get();
for (int i = 0; i < numPartitions; i++) {
if (keynumber < bound * i && keynumber >= bound * (i - 1))
return i - 1;
}
return 0;//return -1; (error)
}
}
上面的這段程式碼是自己實現的簡單分割槽,最大值未輸入的一個最大數字。我用1.2.1版本,無論如何,分割槽返回不能為-1,所以改成0
hadoop的map/reduce中支援對key進行分割槽,從而讓map出來的資料均勻分佈在reduce上,當然,有時候由於機器間配置問題,可能不需要資料均勻,這時候也能派上用場。
框架自帶了一個預設的分割槽類,HashPartitioner,先看看這個類,就知道怎麼自定義key分割槽了。
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;
}
}
很簡單,繼承Partitioner即可。
先解釋一下這個HashPartitioner做的事情
(key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;
將key均勻分佈在ReduceTasks上,舉例如果Key為Text的話,Text的hashcode方法跟String的基本一致,都是採用的Horner公式計算,得到一個int,string太大的話這個int值可能會溢位變成負數,所以與上Integer.MAX_VALUE(即0111111111111111),然後再對reduce個數取餘,這樣就可以讓key均勻分佈在reduce上。
這個簡單演算法得到的結果可能不均勻,因為key畢竟不會那麼線性連續,這時候可以自己寫個測試類,計算出最優的hash演算法。
PS:hadoop框架本身包含了一些跟hash演算法相關的數學之美,比如布隆過濾器(BloomFilter),寫好hash函式是關鍵。
Partitioner
首先需要繼承自Partitioner類(在0.19中為Partitioner介面),並過載它的getPartition方法:
[java]
public static class CatPartitioner extends Partitioner<Text, Text> {
@Override
public int getPartition(Text key, Text value, int numPartitions) {
String[] parts = key.toString().split("-");
if (parts.length == 2) {
return Math.abs(parts[0].hashCode()) % numPartitions;
}
return Math.abs(key.toString().hashCode()) % numPartitions;
}
}
然後在job配置中設定Partitioner Class
相關文章
- MapReduce之自定義partitioner
- MapReduce框架Partitioner分割槽方法框架
- MapReduce之自定義分割槽器Partitioner
- 一個MapReduce 程式示例 細節決定成敗(五) :Partitioner
- Hadoop的故事Hadoop
- hadoop:spark-project專案的hadoop配置HadoopSparkProject
- hadoop1.0 和 Hadoop 2.0 的區別Hadoop
- Hadoop的fsck工具Hadoop
- 將Hadoop部署在雲上的好處,Hadoop的官方wikiHadoop
- [Hadoop]以前整理的一份Hadoop學習指南Hadoop
- Hadoop1.x與Hadoop2的區別Hadoop
- hadoop之 hadoop用途方向Hadoop
- hadoop歷史版本,包括大名鼎鼎的hadoop 0.20.2Hadoop
- [hadoop]hadoop api 新版本與舊版本的差別HadoopAPI
- Hadoop的I/O操作Hadoop
- Hadoop的版本演變Hadoop
- Hadoop httpfs API的使用HadoopHTTPAPI
- hadoop的安裝部署Hadoop
- Hadoop的架構模型Hadoop架構模型
- Hadoop 工具的認識Hadoop
- HADOOP的PIG框架Hadoop框架
- SQL on Hadoop 的真相(2)SQLHadoop
- SQL on Hadoop 的真相(1)SQLHadoop
- Hadoop的TeraSort問題Hadoop
- hadoop之 hadoop 機架感知Hadoop
- [hadoop]hadoop學習路線Hadoop
- 用Hadoop,還是不用Hadoop?Hadoop
- HadoopHadoop
- 從hadoop發展角度徹底明白hadoop1.x與hadoop2.x的區別Hadoop
- Hadoop - macOS 上編譯 Hadoop 3.2.1HadoopMac編譯
- Hadoop演進與Hadoop生態Hadoop
- hadoop 之Hadoop生態系統Hadoop
- hadoop之 HDFS-Hadoop存檔Hadoop
- 高可用Hadoop平臺-Hue In HadoopHadoop
- Hadoop 3.0 中的新功能Hadoop
- hadoop和spark的區別HadoopSpark
- hadoop中的序列化Hadoop
- hadoop 在centos中的搭建HadoopCentOS