Hadoop的Partition解析


1.解析Partition

Map的结果,会通过partition分发到Reducer上,Reducer做完Reduce操作后,通过OutputFormat,进行输出,下面我们就来分析参与这个过程的类。

Mapper的结果,可能送到Combiner做合并,Combiner在系统中并没有自己的基类,而是用Reducer作为Combiner的基类,他们对外的功能是一样的,只是使用的位置和使用时的上下文不太一样而已。Mapper最终处理的键值对<key, value>,是需要送到Reducer去合并的,合并的时候,有相同key的键/值对会送到同一个Reducer那。哪个key到哪个Reducer的分配过程,是由Partitioner规定的。它只有一个方法,

  1. getPartition(Text key, Text value, int numPartitions)  
getPartition(Text key, Text value, int numPartitions)

输入是Map的结果对<key, value>和Reducer的数目,输出则是分配的Reducer(整数编号)。就是指定Mappr输出的键值对到哪一个reducer上去。系统缺省的Partitioner是HashPartitioner,它以key的Hash值对Reducer的数目取模,得到对应的Reducer。这样保证如果有相同的key值,肯定被分配到同一个reducre上。如果有N个reducer,编号就为0,1,2,3……(N-1)

2.代码实例

package org.apache.hadoop.examples;

import java.io.IOException;
import java.util.*;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.conf.*;
import org.apache.hadoop.io.*;
import org.apache.hadoop.mapred.*;
import org.apache.hadoop.util.*;

/**
 * 输入文本,以tab间隔
 * kaka    1       28
 * hua     0       26
 * chao    1
 * tao     1       22
 * mao     0       29      22
 * */

//Partitioner函数的使用

public class MyPartitioner {
	// Map函数
	public static class MyMap extends MapReduceBase implements
			Mapper<LongWritable, Text, Text, Text> {
		public void map(LongWritable key, Text value,
				OutputCollector<Text, Text> output, Reporter reporter)
				throws IOException {
			String[] arr_value = value.toString().split("\t");
			//测试输出
//			for(int i=0;i<arr_value.length;i++)
//			{
//				System.out.print(arr_value[i]+"\t");
//			}
//			System.out.print(arr_value.length);
//			System.out.println();		
			Text word1 = new Text();
			Text word2 = new Text();
			if (arr_value.length > 3) {
				word1.set("long");
				word2.set(value);
			} else if (arr_value.length < 3) {
				word1.set("short");
				word2.set(value);
			} else {
				word1.set("right");
				word2.set(value);
			}
			output.collect(word1, word2);
		}
	}
	
	public static class MyReduce extends MapReduceBase implements
			Reducer<Text, Text, Text, Text> {
		public void reduce(Text key, Iterator<Text> values,
				OutputCollector<Text, Text> output, Reporter reporter)
				throws IOException {
			int sum = 0;
			System.out.println(key);
			while (values.hasNext()) {
				output.collect(key, new Text(values.next().getBytes()));	
			}
		}
	}

	// 接口Partitioner继承JobConfigurable,所以这里有两个override方法
	public static class MyPartitionerPar implements Partitioner<Text, Text> {
		/**
		 * getPartition()方法的
		 * 输入参数:键/值对<key,value>与reducer数量numPartitions
		 * 输出参数:分配的Reducer编号,这里是result
		 * */
		@Override
		public int getPartition(Text key, Text value, int numPartitions) {
			// TODO Auto-generated method stub
			int result = 0;
			System.out.println("numPartitions--" + numPartitions);
			if (key.toString().equals("long")) {
				result = 0 % numPartitions;
			} else if (key.toString().equals("short")) {
				result = 1 % numPartitions;
			} else if (key.toString().equals("right")) {
				result = 2 % numPartitions;
			}
			System.out.println("result--" + result);
			return result;
		}
		
		@Override
		public void configure(JobConf arg0) 
		{
			// TODO Auto-generated method stub
		}
	}

	//输入参数:/home/hadoop/input/PartitionerExample /home/hadoop/output/Partitioner
	public static void main(String[] args) throws Exception {
		JobConf conf = new JobConf(MyPartitioner.class);
		conf.setJobName("MyPartitioner");
		
		//控制reducer数量,因为要分3个区,所以这里设定了3个reducer
		conf.setNumReduceTasks(3);

		conf.setMapOutputKeyClass(Text.class);
		conf.setMapOutputValueClass(Text.class);

		//设定分区类
		conf.setPartitionerClass(MyPartitionerPar.class);

		conf.setOutputKeyClass(Text.class);
		conf.setOutputValueClass(Text.class);

		//设定mapper和reducer类
		conf.setMapperClass(MyMap.class);
		conf.setReducerClass(MyReduce.class);

		conf.setInputFormat(TextInputFormat.class);
		conf.setOutputFormat(TextOutputFormat.class);

		FileInputFormat.setInputPaths(conf, new Path(args[0]));
		FileOutputFormat.setOutputPath(conf, new Path(args[1]));

		JobClient.runJob(conf);
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值