1.解析Partition

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

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

[java] view
plain
copy

  1. 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)

Reducer是所有用户定制Reducer类的基类,和Mapper类似,它也有setup,reduce,cleanup和run方法,其中setup和cleanup含义和Mapper相同,reduce是真正合并Mapper结果的地方,它的输入是key和这个key对应的所有value的一个迭代器,同时还包括Reducer的上下文。系统中定义了两个非常简单的Reducer,IntSumReducer和LongSumReducer,分别用于对整形/长整型的value求和。

Reduce的结果,通过Reducer.Context的方法collect输出到文件中,和输入类似,Hadoop引入了OutputFormat。OutputFormat依赖两个辅助接口:RecordWriter和OutputCommitter,来处理输出。RecordWriter提供了write方法,用于输出<key, value>和close方法,用于关闭对应的输出。OutputCommitter提供了一系列方法,用户通过实现这些方法,可以定制OutputFormat生存期某些阶段需要的特殊操作。我们在TaskInputOutputContext中讨论过这些方法(明显,TaskInputOutputContext是OutputFormat和Reducer间的桥梁)。OutputFormat和RecordWriter分别对应着InputFormat和RecordReader,系统提供了空输出NullOutputFormat(什么结果都不输出,NullOutputFormat.RecordWriter只是示例,系统中没有定义),LazyOutputFormat(没在类图中出现,不分析),FilterOutputFormat(不分析)和基于文件FileOutputFormat的SequenceFileOutputFormat和TextOutputFormat输出。

基于文件的输出FileOutputFormat利用了一些配置项配合工作,包括:

mapred.output.compress:是否压缩;

mapred.output.compression.codec:压缩方法;

mapred.output.dir:输出路径;

mapred.work.output.dir:输出工作路径。

FileOutputFormat还依赖于FileOutputCommitter,通过FileOutputCommitter提供一些和Job,Task相关的临时文件管理功能。如FileOutputCommitter的setupJob,会在输出路径下创建一个名为_temporary的临时目录,cleanupJob则会删除这个目录。

SequenceFileOutputFormat输出和TextOutputFormat输出分别对应输入的SequenceFileInputFormat和TextInputFormat。

2.代码实例

[java] view
plain
copy

  1. package org.apache.hadoop.examples;
  2. import java.io.IOException;
  3. import java.util.*;
  4. import org.apache.hadoop.fs.Path;
  5. import org.apache.hadoop.conf.*;
  6. import org.apache.hadoop.io.*;
  7. import org.apache.hadoop.mapred.*;
  8. import org.apache.hadoop.util.*;
  9. /**
  10. * 输入文本,以tab间隔
  11. * kaka    1       28
  12. * hua     0       26
  13. * chao    1
  14. * tao     1       22
  15. * mao     0       29      22
  16. * */
  17. //Partitioner函数的使用
  18. public class MyPartitioner {
  19. // Map函数
  20. public static class MyMap extends MapReduceBase implements
  21. Mapper<LongWritable, Text, Text, Text> {
  22. public void map(LongWritable key, Text value,
  23. OutputCollector<Text, Text> output, Reporter reporter)
  24. throws IOException {
  25. String[] arr_value = value.toString().split("\t");
  26. //测试输出
  27. //          for(int i=0;i<arr_value.length;i++)
  28. //          {
  29. //              System.out.print(arr_value[i]+"\t");
  30. //          }
  31. //          System.out.print(arr_value.length);
  32. //          System.out.println();
  33. Text word1 = new Text();
  34. Text word2 = new Text();
  35. if (arr_value.length > 3) {
  36. word1.set("long");
  37. word2.set(value);
  38. } else if (arr_value.length < 3) {
  39. word1.set("short");
  40. word2.set(value);
  41. } else {
  42. word1.set("right");
  43. word2.set(value);
  44. }
  45. output.collect(word1, word2);
  46. }
  47. }
  48. public static class MyReduce extends MapReduceBase implements
  49. Reducer<Text, Text, Text, Text> {
  50. public void reduce(Text key, Iterator<Text> values,
  51. OutputCollector<Text, Text> output, Reporter reporter)
  52. throws IOException {
  53. int sum = 0;
  54. System.out.println(key);
  55. while (values.hasNext()) {
  56. output.collect(key, new Text(values.next().getBytes()));
  57. }
  58. }
  59. }
  60. // 接口Partitioner继承JobConfigurable,所以这里有两个override方法
  61. public static class MyPartitionerPar implements Partitioner<Text, Text> {
  62. /**
  63. * getPartition()方法的
  64. * 输入参数:键/值对<key,value>与reducer数量numPartitions
  65. * 输出参数:分配的Reducer编号,这里是result
  66. * */
  67. @Override
  68. public int getPartition(Text key, Text value, int numPartitions) {
  69. // TODO Auto-generated method stub
  70. int result = 0;
  71. System.out.println("numPartitions--" + numPartitions);
  72. if (key.toString().equals("long")) {
  73. result = 0 % numPartitions;
  74. } else if (key.toString().equals("short")) {
  75. result = 1 % numPartitions;
  76. } else if (key.toString().equals("right")) {
  77. result = 2 % numPartitions;
  78. }
  79. System.out.println("result--" + result);
  80. return result;
  81. }
  82. @Override
  83. public void configure(JobConf arg0)
  84. {
  85. // TODO Auto-generated method stub
  86. }
  87. }
  88. //输入参数:/home/hadoop/input/PartitionerExample /home/hadoop/output/Partitioner
  89. public static void main(String[] args) throws Exception {
  90. JobConf conf = new JobConf(MyPartitioner.class);
  91. conf.setJobName("MyPartitioner");
  92. //控制reducer数量,因为要分3个区,所以这里设定了3个reducer
  93. conf.setNumReduceTasks(3);
  94. conf.setMapOutputKeyClass(Text.class);
  95. conf.setMapOutputValueClass(Text.class);
  96. //设定分区类
  97. conf.setPartitionerClass(MyPartitionerPar.class);
  98. conf.setOutputKeyClass(Text.class);
  99. conf.setOutputValueClass(Text.class);
  100. //设定mapper和reducer类
  101. conf.setMapperClass(MyMap.class);
  102. conf.setReducerClass(MyReduce.class);
  103. conf.setInputFormat(TextInputFormat.class);
  104. conf.setOutputFormat(TextOutputFormat.class);
  105. FileInputFormat.setInputPaths(conf, new Path(args[0]));
  106. FileOutputFormat.setOutputPath(conf, new Path(args[1]));
  107. JobClient.runJob(conf);
  108. }
  109. }

Hadoop中Partition的定制的更多相关文章

  1. Hadoop中Partition深度解析

    本文地址:http://www.cnblogs.com/archimedes/p/hadoop-partitioner.html,转载请注明源地址. 旧版 API 的 Partitioner 解析 P ...

  2. Hadoop中Partition解析

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

  3. hadoop中实现定制Writable类

    Hadoop中有一套Writable实现可以满足大部分需求,但是在有些情况下,我们需要根据自己的需要构造一个新的实现,有了定制的Writable,我们就可以完全控制二进制表示和排序顺序. 为了演示如何 ...

  4. Hadoop中的Partitioner浅析

    转自:http://blog.csdn.net/b1198103958/article/details/47169105 Hadoop里面的MapReduce编程模型,非常灵活,大部分环节我们都可以重 ...

  5. Hadoop中的各种排序

    本篇博客是金子在学习hadoop过程中的笔记的整理,不论看别人写的怎么好,还是自己边学边做笔记最好了. 1:shuffle阶段的排序(部分排序) shuffle阶段的排序可以理解成两部分,一个是对sp ...

  6. 1 weekend110的复习 + hadoop中的序列化机制 + 流量求和mr程序开发

    以上是,weekend110的yarn的job提交流程源码分析的复习总结 下面呢,来讲weekend110的hadoop中的序列化机制 1363157985066      13726230503  ...

  7. hadoop中map和reduce的数量设置

    hadoop中map和reduce的数量设置,有以下几种方式来设置 一.mapred-default.xml 这个文件包含主要的你的站点定制的Hadoop.尽管文件名以mapred开头,通过它可以控制 ...

  8. Hadoop中Writable类之四

    1.定制Writable类型 Hadoop中有一套Writable实现,例如:IntWritable.Text等,但是,有时候可能并不能满足自己的需求,这个时候,就需要自己定制Writable类型. ...

  9. Hadoop中Comparator原理

    在前面的博文<Hadoop中WritableComparable 和 comparator>中,对于WritableComparator说的不够细致,下面说说具体的实现原理! 1.Writ ...

随机推荐

  1. keep-alive使用笔记

    vue2.0提供了keep-alive组件,用来缓存组件,避免多次加载,减少性能消耗. 1.将整个网页缓存起来 <router-view class="view" keep- ...

  2. 单链表(C++实现)

    单链表的结构有多种 这里介绍的链表有头结点.有尾节点并且尾节点指向头结点 单链表的每个结点的地址存放在其直接前驱结点的指针域中.其中第一个结点没有前驱结点,因此需要一个头指针指向第一个节点,便于我们对 ...

  3. 算法(Algorithms)第4版 练习 1.4.5

    a. N b. 1 c. 1 d. N3 e. 1 f. 1 g. 1(0)

  4. ubuntu下搭建Scrapy框架简单办法

    1. 先执行以下命令 sudo apt-get install python-lxml sudo apt-get install libxslt1-dev sudo apt-get install p ...

  5. Provider org.apache.xerces.jaxp.DocumentBuilderFactoryImpl not found 问题排查

    自定义的classLoader启动spring容器,遇到 Provider org.apache.xerces.jaxp.DocumentBuilderFactoryImpl not subtype ...

  6. Alembic Migrations

    Introduction The migrations in the alembic/versions contain the changes needed to migrate from older ...

  7. 在javascript中使用replace

    javascript中使用replace功能很强大,不仅可以替换为字符串,还可以利用正则表达式,对匹配到的字符串为所欲为的进行操作,首先我们来了解一下replace的基本语法 定义和用法 replac ...

  8. 分享知识-快乐自己:Shrio 案例Demo概述

    Shiro 权限认证核心: POM:文件: <!--shiro-all--> <dependency> <groupId>org.apache.shiro</ ...

  9. Python基础-set集合操作

    set集合,是一个无序且不重复的元素集合.定义方式类似字典使用{}创建 目前我们学过的数据类型: 1.字符串(str),2.整型(int),3.浮点型(float),4,列表(list) 5.元组(t ...

  10. ES doc_values介绍——本质是field value的列存储,做聚合分析用,ES默认开启,会占用存储空间(列存储压缩技巧,除公共除数或者同时减去最小数,字符串压缩的话,直接去重后用数字ID压缩)

    doc_values Doc values are the on-disk data structure, built at document index time, which makes this ...