Hadoop mapreduce自定义分区HashPartitioner

 首先我们明确一下关于中这个分区到底是怎么样,有什么用处?回答这个问题先看看上次代码执行的结果,我们知道结果中有个文件(part-r-00000),这个文件就是所有的词的数量记录,这个时候有没什么想法比如如果我想把一些包含特殊的词放置单独的一个文件,其他我不关心的放置在另一个文件这样我就好查看方便多了,又比如如果是统计关于人的某些爱好那我是不是可以把童年的放置在一个文件,成年的放置在一个文件等等这样输出结果。是,这个倒是非常有用哦输出的结果就是最直接的了,那现在我们就来分析一下应该怎么搞怎么实现:

    我们清楚,这个输出文件是由reduce端输出的,reduce端的数据是由map函数处理完通过shufflecopy至reduce端的,然而map端的输出数量会对于reduce输入的数量,那么map端会负责划分数据,在shuffle过程中有个步骤就是分区,我们先来看看上次代码中使用的分区类HashPartitioner,看代码:

1
2
3
4
5
6
7
8
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;
   }
}

这里出现了个numReduceTasks变量,这个是由哪里过来的呢,那就得看谁调用了这个方法了,看:MapTask.java就可以看到其write方法调用了,然而这个方法的partitions参数是由:

1
jobContext.getNumReduceTasks();

觉得,那我们继续找下去这个变量是由mapred.reduce.tasks配置节点决定的默认是1。那现在我们虽然不知道(key.hashCode() & Integer.MAX_VALUE)值是多少但是%1我们可以知道结果就是0;现在我来继承这个类(也可继承其父类Partitioner<K, V>)重写其getPartition方法来实现分区,看下面自定义分区MyPartition代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import  org.apache.hadoop.io.LongWritable;
import  org.apache.hadoop.io.Text;
import  org.apache.hadoop.mapreduce.lib.partition.HashPartitioner;
 
/**
  * 自定义分区类
  * @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函数,其中如果键中有字符串"luoliang"的键值就返回0否则其它返回1。执行后在(hdfs://hadoop-master:9000/mapreduce/output/)会有2个文件,一个是part-r-00000,一个是part-r-00001。part-r-00000对应的是条件key.toString().contains("luoliang")为真的!

    注意先要在mian函数中加入:

1
job.setJarByClass(Test. class );

还需要更改:

1
2
job.setPartitionerClass(MyPartition. class );
job.setNumReduceTasks( 2 );

再把程序打包成jar.jar文件上传至服务器使用命令运行:

1
hadoop jar jar.jar

如果本地调试或者运行会报错必须打包至服务器运行,结果会生成有那下面2个文件如下


1
2
part-r- 00000
part-r- 00001

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值