hadoop开发中我们会遇到类似这样的问题,比如 如何将不同省份的手机号分别输出到不同的文件中,本片文章将对hadoop内置的Partition类进行重写以解决这个问题。

  MapReduce的使用者通常会指定Reduce任务和Reduce任务输出文件的数量(R)。用户在中间key上使用分区函数来对数据进行分区,之后在输入到后续任务执行进程。Hadoop中自带了一个默认的分区类HashPartitioner,它继承了Partitioner类,提供了一个getPartition的方法,它的定义如下所示:

有些人死活不明白 key.hashCode() & Integer.MAX_VALUE) % numReduceTasks; 这段代码到底是怎么运算的,不要紧 ,我们main方法运行一下不久完了吗。

如果你想了解大数据的学习路线,想学习大数据知识以及需要免费的学习资料可以加群:784789432.欢迎你的加入。每天下午三点开直播分享基础知识,晚上20:00都会开直播给大家分享大数据项目实战。

  1. public class Txt {
  2. /*
  3. * 将key均匀分布在ReduceTasks上,举例如果Key为Text的话,Text的hashcode方法跟String的基本一致,
  4. * 都是采用的Horner公式计算,得到一个int,string太大的话这个int值可能会溢出变成负数,
  5. * 所以与上Integer.MAX_VALUE(即0111111111111111),然后再对reduce个数取余,这样就可以让key均匀分布在reduce上。
  6. */
  7. public static void main(String[] args) {
  8. String key = "a,b,c,d,e,f,sdf,hth,iu,44,efwfqegergegew,h,ww,b,mm,lwefwefwfwefwefkj";
  9. String[] fields = key.split(",");
  10. int numReduceTasks = 4 ;
  11. for (int i = 0; i < 16; i++) {
  12. int j = ( fields[i].hashCode() & Integer.MAX_VALUE) % numReduceTasks;
  13. System.out.println("与结果:"+(fields[i].hashCode() & Integer.MAX_VALUE)+" --> key值: "+fields[i]+" 所在区间数 :"+j);
  14. }
  15. }
  16. }

结果 :

从结果我们简单明了的看出,通过这个算法的key具体是分布到那个区间,有几个区间,就是靠你的 reducetasks值决定的,如上图代码我们写死reducetasks数量为4,也就是 4个reduce ,  那么输出结果为 0 , 1, 2, 3 个数值, 既为 4个区间。各个key值也较为均匀的分布再来 0,1,2,3 这四个区间之间的任意一个。

1,自定义 partitioner , 这是一坨数据,我们将根据相同省份的手机号放到不同文件中,省份根据手机号前三位判断。

2, 继承重写Partitioner中的getPartition()方法,根据key不同值返回不同 int 值, 共4组。

public class AreaPartitioner<KEY, VALUE> extends Partitioner<KEY, VALUE>{
private static HashMap<String,Integer> map = new HashMap<>();
static{
map.put("135", 0);
map.put("136", 1);
map.put("137", 2);
map.put("150", 3);  //其余情况既返回4
}
//map数据分组机制 hash(key)%1 == 0 ,既只有一组,所有手机号都放到一个分组里面
//现在可 返回  0 1 2 3  ,既 总共4组
//main方法中控制 reduce 任务数
@Override
public int getPartition(KEY key, VALUE value, int numPartitions) {
//从key中拿到手机号,不同的省份返回不同的组号
int a  = map.get(key.toString().substring(0, 3))==null?4:map.get(key.toString().substring(0, 3));
return a;
}
    }

3,  在main方法中定义reduce的任务数量, 改数量大于等于 你的分组数 4 。

public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
Job job = Job.getInstance(conf);
job.setJarByClass(FlowSumArea.class);
job.setMapperClass(FlowSumAreaMapper.class);
job.setReducerClass(FlowSumAreaReducer.class);
//设置我们自定义的分组逻辑定义
job.setPartitionerClass(AreaPartitioner.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(FlowBean.class);
//设置reduce的任务并发数,应该跟分组的数量保持一致
job.setNumReduceTasks(4);
FileInputFormat.setInputPaths(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
System.exit(job.waitForCompletion(true)?0:1);

}

4  , 重新打jar包, 在虚拟机上运行下,如果看到结果产生了多个文件,既为成功。

5, 这里的流程原理就是 haoop中 mapreduce中间过程 , 叫做shuffle , 下图是我总结的流程图,可以参考看下 如果写的不对请指出,谢谢 。

hadoop的自定义分组实现 (Partition机制)的更多相关文章

  1. Hadoop mapreduce自定义分组RawComparator

    本文发表于本人博客. 今天接着上次[Hadoop mapreduce自定义排序WritableComparable]文章写,按照顺序那么这次应该是讲解自定义分组如何实现,关于操作顺序在这里不多说了,需 ...

  2. 【Hadoop】Hadoop MR 自定义分组 Partition机制

    1.概念 2.Hadoop默认分组机制--所有的Key分到一个组,一个Reduce任务处理 3.代码示例 FlowBean package com.ares.hadoop.mr.flowgroup; ...

  3. 一脸懵逼学习Hadoop中的MapReduce程序中自定义分组的实现

    1:首先搞好实体类对象: write 是把每个对象序列化到输出流,readFields是把输入流字节反序列化,实现WritableComparable,Java值对象的比较:一般需要重写toStrin ...

  4. 2 weekend110的hadoop的自定义排序实现 + mr程序中自定义分组的实现

    我想得到按流量来排序,而且还是倒序,怎么达到实现呢? 达到下面这种效果, 默认是根据key来排, 我想根据value里的某个排, 解决思路:将value里的某个,放到key里去,然后来排 下面,开始w ...

  5. MapReduce实例2(自定义compare、partition)& shuffle机制

    MapReduce实例2(自定义compare.partition)& shuffle机制 实例:统计流量 有一份流量数据,结构是:时间戳.手机号.....上行流量.下行流量,需求是统计每个用 ...

  6. Hadoop自定义分组Group

    matadata: hadoop a spark a hive a hbase a tachyon a storm a redis a 自定义分组 import org.apache.hadoop.c ...

  7. 关于MapReduce中自定义分组类(三)

    Job类  /**    * Define the comparator that controls which keys are grouped together    * for a single ...

  8. hadoop的自定义数据类型和与关系型数据库交互

    最近有一个需求就是在建模的时候,有少部分数据是postgres的,只能读取postgres里面的数据到hadoop里面进行建模测试,而不能导出数据到hdfs上去. 读取postgres里面的数据库有两 ...

  9. 3 weekend110的hadoop中的RPC框架实现机制 + hadoop中的RPC应用实例demo

    hadoop中的RPC框架实现机制 RPC是Remotr Process Call, 进程间的远程过程调用,不是在一个jvm里. 即,Controller拿不到Service的实例对象. hadoop ...

随机推荐

  1. git revert .vs. git reset .vs. git rebase

    1. git rervert的工作方式是:将一个老的commit的改动完全找出来,并且在新的tip处运行反操作,最终清除老commit的改动: git revert的应用场景多在对public rep ...

  2. SQL Server ->> THROW字句对比RAISERROR子句

    SQL Server 2012开始引入了THROW字句用于替代从SQL Server开始沿用至今的RAISERROR.既然作用相同,都是在TRY... CATCH代码块后不抓错误然后抛出错误,它们之间 ...

  3. tomcat运行报错Failed to start component [StandardEngine[Catalina].StandardHost[localhost].

    tomcat运行报错Failed to start component [StandardEngine[Catalina].StandardHost[localhost].多半情况是找不到jar包 解 ...

  4. C# 转换运算符:implicit(隐式),explicit(显示)

    //A类 class Cls1 { public string name; //构造函数 public Cls1(string name) { this.name = name; } //implic ...

  5. C++ 源代码到可执行代码的详细过程

    编译,编译程序读取源程序(字符流),对之进行词法和语法的分析,将高级语言指令转换为功能等效的汇编代码,再由汇编程序转换为机器语言,并且按照操作系统对可执行文件格式的要求链接生成可执行程序. 源代码-- ...

  6. 7za 命令解析

    转载自:blog.chinaunix.net/uid-26330274-id-3055157.html 7za 命令讲的很详细,收藏下来. 命令行压缩解压一 7z   1) 简介 7z,全称7-Zip ...

  7. 设计模式:命令(Command)模式

    设计模式:命令(Command)模式 一.前言 命令也是类,将命令作为一个类来保存,当要使用的时候可以直接拿来使用,比如脚本语言写出的脚本,只需要一个命令就能执行得到我们想要的需要操作很长时间才能得到 ...

  8. tree 向上查找(更新删除后页面的数据)

    需求 : 根据选择的id,需要找到一整条tree,id以及id数据的子集都已被删除(向下查找-----上一篇笔记),此时需要更新页面的数据(向上查找) //知道最底层的节点的id,查找满足id的整个t ...

  9. 一个老IT产品管理者对于产品经理工作的经验总结

    一个老IT产品管理者对于产品经理工作的经验总结 1. 任何行业,包括IT行业,所谓产品管理.产品经理,其核心应该是企业产品管理制度,也就是说,只有企业存在相应的.合理的产品管理体系和制度,产品管理.产 ...

  10. sql2005 和 mysql 定时备份批处理

    保存为sqlbak.bat  目录我直接放winrar 的根目录了 或者拷贝一个winrar.exe 具体目录随意. 然后添加计划任务个人的话建议一周或者一天 虚拟主机等 建议每周或者每月 @echo ...