Partitioner, SortComparator and GroupingComparator in Hadoop

来源:http://roserouge.iteye.com/blog/746391

 

hadoop 0.20.2 api里面,作业被重新定义到了类 org.apache.hadoop.mapreduce.Job。

它有3个特别的方法:

job.setPartitionerClass(Partitioner p);

job.setSortComparatorClass(RawComparator c);
job.setGroupingComparatorClass(RawComparator c);

 

数据在被map处理过之后,会根据 Partitioner 定义的规则,把中间结果分发到特定的reduce。

Partitioner<Key, Value> 包含一个方法:public int getPartition(Key k, Value v, int parts)

Java代码 收藏代码
  1. publicstaticclassPextendsPartitioner<IdWithTimestamp,Value>{
  2. @Override
  3. publicintgetPartition(IdWithTimestampk,Valuev,intparts){
  4. inthash=k.getId().hashCode();
  5. return(hash&Integer.MAX_VALUE)%parts;
  6. }
  7. }

 

接下来,可以做一些控制,使得不同 Key的中间数据,能够被分发到同一个reduce 处理,setGroupingComparatorClass提供分组规则。

例如,key可能是[id, timestamp],这样可以使相同的id(String)能按时间戳(long)排序,现在拆出包含在key里的相同id,分到相同的组。

Java代码 收藏代码
  1. publicclassIdComparatorextendsTextComparator{
  2. @Override
  3. publicintcompare(IdWithTimestampo1,IdWithTimestampo2){
  4. returno1.getId().compareTo(o2.getId());
  5. }
  6. }

 

然后,中间数据在被reduce处理之前,会先被集中排序,setSortComparatorClass提供排序规则。

Java代码 收藏代码
  1. publicclassTimestampComparatorextendsTextComparator{
  2. @Override
  3. publicintcompare(IdWithTimestampo1,IdWithTimestampo2){
  4. returno1.getTimestamp()-o2.getTimestamp();
  5. }
  6. }

 

如果不提供这些东西,默认使用的是 Key类型的 compareTo方法,而不是 hashCode和 equals。

可以自定义 WritableComparable类型,提供优化比较方法,以提高执行效率。。。字节比较,那是个挺麻烦的事情,我都是很偷懒地一直用Text,拼接、拆分字符串做比较。

 

Partitioner,SortComparator 和 GroupingComparator 配合即可实现某些对顺序有要求的计算。如果数据集很大的话,可能还需要控制map对输入的分割

Java代码 收藏代码
  1. publicclassNoSplitInputFormatextendsTextInputFormat{
  2. @Override
  3. protectedbooleanisSplitable(JobContextcontext,Pathfile){
  4. returnfalse;
  5. }
  6. }

 

排序 + 计算 两个任务,不等于一个完整任务里的 按顺序计算。

 

实践证明,使用外部的RawComparator 更具灵活性,可以提供不同的排序和分组策略。

 

 

附例子程序,测试数据,测试结果

 

Join的时候也用得着它们

 

enjoy it!

 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值