本文發(fā)表于本人博客。
在上一篇文章我寫了個(gè)簡(jiǎn)單的WordCount程序,也大致了解了下關(guān)于mapreduce運(yùn)行原來,其中說到還可以自定義分區(qū)、排序、分組這些,那今天我就接上一次的代碼繼續(xù)完善實(shí)現(xiàn)自定義分區(qū)。
首先我們明確一下關(guān)于中這個(gè)分區(qū)到底是怎么樣,有什么用處?回答這個(gè)問題先看看上次代碼執(zhí)行的結(jié)果,我們知道結(jié)果中有個(gè)文件(part-r-00000),這個(gè)文件就是所有的詞的數(shù)量記錄,這個(gè)時(shí)候有沒什么想法比如如果我想把一些包含特殊的詞放置單獨(dú)的一個(gè)文件,其他我不關(guān)心的放置在另一個(gè)文件這樣我就好查看方便多了,又比如如果是統(tǒng)計(jì)關(guān)于人的某些愛好那我是不是可以把童年的放置在一個(gè)文件,成年的放置在一個(gè)文件等等這樣輸出結(jié)果。是,這個(gè)倒是非常有用哦輸出的結(jié)果就是最直接的了,那現(xiàn)在我們就來分析一下應(yīng)該怎么搞怎么實(shí)現(xiàn):
我們清楚,這個(gè)輸出文件是由reduce端輸出的,reduce端的數(shù)據(jù)是由map函數(shù)處理完通過shufflecopy至reduce端的,然而map端的輸出數(shù)量會(huì)對(duì)于reduce輸入的數(shù)量,那么map端會(huì)負(fù)責(zé)劃分?jǐn)?shù)據(jù),在shuffle過程中有個(gè)步驟就是分區(qū),我們先來看看上次代碼中使用的分區(qū)類HashPartitioner,看代碼:
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;  }}這里出現(xiàn)了個(gè)numReduceTasks變量,這個(gè)是由哪里過來的呢,那就得看誰調(diào)用了這個(gè)方法了,看:MapTask.java就可以看到其write方法調(diào)用了,然而這個(gè)方法的partitions參數(shù)是由:
jobContext.getNumReduceTasks();
覺得,那我們繼續(xù)找下去這個(gè)變量是由mapred.reduce.tasks配置節(jié)點(diǎn)決定的默認(rèn)是1。那現(xiàn)在我們雖然不知道(key.hashCode() & Integer.MAX_VALUE)值是多少但是%1我們可以知道結(jié)果就是0;現(xiàn)在我來繼承這個(gè)類(也可繼承其父類Partitioner<K, V>)重寫其getPartition方法來實(shí)現(xiàn)分區(qū),看下面自定義分區(qū)MyPartition代碼:
import org.apache.hadoop.io.LongWritable;import org.apache.hadoop.io.Text;import org.apache.hadoop.mapreduce.lib.partition.HashPartitioner;/** * 自定義分區(qū)類 * @author Liang * */public class MyPartition extends HashPartitioner<Text, LongWritable> {    @Override    public int getPartition(Text key, LongWritable value, int numReduceTasks) {        return key.toString().contains("luoliang") ? 0 : 1;    }    }上面重寫getPartition函數(shù),其中如果鍵中有字符串"luoliang"的鍵值就返回0否則其它返回1。執(zhí)行后在(hdfs://hadoop-master:9000/mapreduce/output/)會(huì)有2個(gè)文件,一個(gè)是part-r-00000,一個(gè)是part-r-00001。part-r-00000對(duì)應(yīng)的是條件key.toString().contains("luoliang")為真的!
注意先要在mian函數(shù)中加入:
job.setJarByClass(Test.class);
還需要更改:
job.setPartitionerClass(MyPartition.class);job.setNumReduceTasks(2);
再把程序打包成jar.jar文件上傳至服務(wù)器使用命令運(yùn)行:
hadoop jar jar.jar
如果本地調(diào)試或者運(yùn)行會(huì)報(bào)錯(cuò)必須打包至服務(wù)器運(yùn)行,結(jié)果會(huì)生成有那下面2個(gè)文件如下:
part-r-00000part-r-00001
這次先到這里。堅(jiān)持記錄點(diǎn)點(diǎn)滴滴!
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注