hadoop mapreduce 中的map 和reduce 函数遵循下面的形式
  1. map: (K1, V1) list(K2, V2)
  2. reduce: (K2, list(V2)) list(K3, V3)

  1. 能够从源码中看出为什么是这种类型:
  1. map: (K1, V1)  list(K2, V2)
  1. reduce: (K2, list(V2))  list(K3, V3)
  1. public class Mapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT> {
  2.   public class Context extends MapContext<KEYIN, VALUEIN, KEYOUT, VALUEOUT> {
  3.     // ...
  4.   }
  5.   protected void map(KEYIN key, VALUEIN value,
  6.       Context context) throws IOException, InterruptedException {
  7.     // ...
  8.   }
  9. }
  10. public class Reducer<KEYIN, VALUEIN, KEYOUT, VALUEOUT> {
  11.   public class Context extends ReducerContext<KEYIN, VALUEIN, KEYOUT, VALUEOUT> {
  12.     // ...
  13.   }
  14.   protected void reduce(KEYIN key, Iterable<VALUEIN> values,
  15.       Context context) throws IOException, InterruptedException {
  16.     // ...
  17.   }
  18. }
  19. context用来接收输出键值对,写出的方法是:
  20. public void write(KEYOUT key, VALUEOUT value)
  21.     throws IOException, InterruptedException
  22. 假设有combiner :这里的 combiner就是默认的reducer

  23. map: (K1, V1)  list(K2, V2)
  24. combiner: (K2, list(V2))  list(K2, V2)
  25. reduce: (K2, list(V2))  list(K3, V3)
  26. 假设partitioner被使用:

  27. partition: (K2, V2)  integer(非常多时候仅仅取决于key 值被忽略来进行分区)
  1. 以及combiner 甚至partitioner让同样的key聚合到一起
  2. public abstract class Partitioner<KEY, VALUE> {
  3.   public abstract int getPartition(KEY key, VALUE value, int numPartitions);
  4. }
  5. 一个实现类:
  6. public class HashPartitioner<K, V> extends Partitioner<K, V> {
        public int getPartition(K key, V value, int numReduceTasks) {
            return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;
        }
    }

  7.  
  8. 输入数据的类型是通过输入格式进行设定的。比如,对于TextlnputFormat ,它的键类型就是LongWritable 。而值类型就是Text 

  9. 其它的类型能够通过调用JobConf 中的方法来进行显式地设置。假设没有显式地设置。 中阔的类型将被默认设置为(终于的)输出类型,也就是LongWritable Text.综上所述,假设K2 K3是同样类型,就不须要手工调用setMapOutputKeyClass,由于它将被自己主动设置每个步骤的输入和输出类型.一定非常奇怪,为什么不能从最初输入的类型推导出每个步骤的输入/输出类型呢?

  10. 原来Java 的泛型机制具有非常多限制,类型擦除导致了运行时类型并不一直可见.所以须要Hadoop 时不时地"提醒"一下。这也导致了可能在某些MapReduce 任务中出现不兼容的输入和输出类型,由于这些配置在编译时无法检查出来。与MapReduce 任务兼容的类型已经在以下列出。全部的类型不兼容将在任务真正运行的时候被发现,所以一个比較聪明的做法是在运行任务前先用少量的数据跑一次測试任务。以发现全部的类型不兼容问题。


  11. Table 8-1. Configuration of MapReduce types in the new API
  12. Property
  13. Job
  14. setter method
  15. Input
  16. types
  17. Intermediate
  18. types
  19. Output
  20. types
  21. K1
  22. V1
  23. K2
  24. V2
  25. K3
  26. V3
  27. Properties
  28. for configuring types:
  29. mapreduce.job.inputformat.class
  30. setInputFormatClass()




  31. mapreduce.map.output.key.class
  32. setMapOutputKeyClass()





  33. mapreduce.map.output.value.class
  34. setMapOutputValueClass()





  35. mapreduce.job.output.key.class
  36. setOutputKeyClass()





  37. mapreduce.job.output.value.class
  38. setOutputValueClass()





  39. Properties
  40. that must be consistent with the types:
  41. mapreduce.job.map.class
  42. setMapperClass()


  43. mapreduce.job.combine.class
  44. setCombinerClass()




  45. mapreduce.job.partitioner.class
  46. setPartitionerClass()




  47. mapreduce.job.output.key.comparator.class
  48. setSortComparatorClass()





  49. mapreduce.job.output.group.comparator.class
  50. setGroupingComparatorClass()





  51. mapreduce.job.reduce.class
  52. setReducerClass()


  53. mapreduce.job.outputformat.class
  54. setOutputFormatClass()




  55. Table 8-2. Configuration of MapReduce types in the old API
  56. Property
  57. JobConf
  58. setter method
  59. Input
  60. types
  61. Intermediate
  62. types
  63. Output
  64. types
  65. K1
  66. V1
  67. K2
  68. V2
  69. K3
  70. V3
  71. Properties
  72. for configuring types:
  73. mapred.input.format.class
  74. setInputFormat()




  75. mapred.mapoutput.key.class
  76. setMapOutputKeyClass()





  77. mapred.mapoutput.value.class
  78. setMapOutputValueClass()





  79. mapred.output.key.class
  80. setOutputKeyClass()





  81. mapred.output.value.class
  82. setOutputValueClass()





  83. Properties
  84. that must be consistent with the types:
  85. mapred.mapper.class
  86. setMapperClass()


  87. mapred.map.runner.class
  88. setMapRunnerClass()


  89. mapred.combiner.class
  90. setCombinerClass()




  91. mapred.partitioner.class
  92. setPartitionerClass()




  93. mapred.output.key.comparator.class
  94. setOutputKeyComparatorClass()





  95. mapred.output.value.groupfn.class
  96. setOutputValueGroupingComparator()





  97. mapred.reducer.class
  98. setReducerClass()


  99. mapred.output.format.class
  100. setOutputFormat()




  101. 一个最简单的hadoop mapreduce:

  102. public class MinimalMapReduce extends Configured implements Tool {
  103.   @Override
  104.   public int run(String[] args) throws Exception {
  105.     if (args.length != 2) {
  106.       System.err.printf("Usage: %s [generic options] <input> <output>\n",
  107.           getClass().getSimpleName());
  108.       ToolRunner.printGenericCommandUsage(System.err);
  109.       return -1;
  110.     }
  111.     Job job = new Job(getConf());
  112.     job.setJarByClass(getClass());
  113.     FileInputFormat.addInputPath(job, new Path(args[0]));
  114.     FileOutputFormat.setOutputPath(job, new Path(args[1]));
  115.     return job.waitForCompletion(true) ? 0 : 1;
  116.   }
  117.   public static void main(String[] args) throws Exception {
  118.     int exitCode = ToolRunner.run(new MinimalMapReduce(), args);
  119.     System.exit(exitCode);
  120.   }
  121. }
  122. 运行方法:


  123.  hadoop MinimalMapReduce "input/ncdc/all/190{1,2}.gz" output
  124. 输出结果:
  125. 00029029070999991901010106004+64333+023450FM-12+000599999V0202701N01591...
  126. 00035029070999991902010106004+64333+023450FM-12+000599999V0201401N01181...
  127. 1350029029070999991901010113004+64333+023450FM-12+000599999V0202901N00821...
  128. 1410035029070999991902010113004+64333+023450FM-12+000599999V0201401N01181...
  129. 2700029029070999991901010120004+64333+023450FM-12+000599999V0209991C00001...
  130. 2820035029070999991902010120004+64333+023450FM-12+000599999V0201401N01391...
  131. 改默认最简mapreduce等同于一下的程序:
  132. public class MinimalMapReduceWithDefaults extends Configured implements Tool {
  133.   @Override
  134.   public int run(String[] args) throws Exception {
  135.     Job job = JobBuilder.parseInputAndOutput(this, getConf(), args);
  136.     if (job == null) {
  137.       return -1;
  138.     }
  139.     job.setInputFormatClass(TextInputFormat.class);
  140.     job.setMapperClass(Mapper.class);
  141.     job.setMapOutputKeyClass(LongWritable.class);
  142.     job.setMapOutputValueClass(Text.class);
  143.     job.setPartitionerClass(HashPartitioner.class);
  144.     job.setNumReduceTasks(1);
  145.     job.setReducerClass(Reducer.class);
  146.     job.setOutputKeyClass(LongWritable.class);
  147.     job.setOutputValueClass(Text.class);
  148.     job.setOutputFormatClass(TextOutputFormat.class);
  149.     return job.waitForCompletion(true) ? 0 : 1;
  150.   }
  151.   public static void main(String[] args) throws Exception {
  152.     int exitCode = ToolRunner.run(new MinimalMapReduceWithDefaults(), args);
  153.     System.exit(exitCode);
  154.   }
  155. }
  156. 那么。默认使用的mapreduce是:
  157. Mapper.class 
  158. HashPartitioner.class
  159. Reducer.class
  160. 默认map代码,就是读取key value输出
  161. public class Mapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT> {
  162.   protected void map(KEYIN key, VALUEIN value,
  163.       Context context) throws IOException, InterruptedException {
  164.     context.write((KEYOUT) key, (VALUEOUT) value);
  165.   }
  166. }
  167. 默认Partitionerhash切割,默认仅仅有一个reducer因此我们这里仅仅有一个分区
  168.  class HashPartitioner<K, V> extends Partitioner<K, V> {
  169.   public int getPartition(K key, V value,
  170.       int numReduceTasks) {
  171.     return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;
  172.   }
  173. }
  174. 默认Reduce 输出传进来的数据:

  175. public class Reducer<KEYIN, VALUEIN, KEYOUT, VALUEOUT> {
  176.   protected void reduce(KEYIN key, Iterable<VALUEIN> values, Context context
  177.       Context context) throws IOException, InterruptedException {
  178.     for (VALUEIN value: values) {
  179.       context.write((KEYOUT) key, (VALUEOUT) value);
  180.     }
  181.   }
  182. }
  183. 由于什么都没做,仅仅是在map中读取了偏移量和value,分区使用的hash,一个reduce输出的便是我们上面看到的样子。

  184. 相对于java api,hadoop流也有最简的mapreduce
  185. % hadoop jar $HADOOP_HOME/share/hadoop/tools/lib/hadoop-streaming-*.jar \
  186.   -input input/ncdc/sample.txt \
  187.   -output output \
  188.   -mapper /bin/cat
  189. 等于以下的命令:

  190. % hadoop jar $HADOOP_HOME/share/hadoop/tools/lib/hadoop-streaming-*.jar \
  191.   -input input/ncdc/sample.txt \
  192.   -output output \
  193.   -inputformat org.apache.hadoop.mapred.TextInputFormat \
  194.   -mapper /bin/cat \
  195.   -partitioner org.apache.hadoop.mapred.lib.HashPartitioner \
  196.   -numReduceTasks 1 \
  197.   -reducer org.apache.hadoop.mapred.lib.IdentityReducer \
  198.   -outputformat org.apache.hadoop.mapred.TextOutputFormat
  199.   -io text
  200. 流操作的键与值
  201. 一个文本文件流怎么知道哪里是一个记录的结束呢?
  202. 一个流操作的程序能够改动输入的分隔符(用于将键与值从输入文件里分开而且传入mapper) 。默认情况下是Tab ,可是假设输入的键或值中本身有Tab 分隔符的话,最好将分隔符改动成其它符号。
  203. 类似地,当map reduc e 将结果输出的时候, 也须要一个能够配置的分隔符选项。更进一步, 键能够不仅仅是每一条记录的第1 个字段,它能够是一条记录的前个字段(能够在stream.num.map.output.key.fieldsstream.num.reduce.output.key.fields 中进行设置) 。而剩下的字段就是值。比方有一条记录是, C  且用逗号分隔,假设设为2 ,那么键就是。而值就是
  204. 流分隔符:

  205. Table 8-3. Streaming separator properties
  206. Property
  207. name
  208. Type
  209. Default
  210. value
  211. Description
  212. stream.map.input.field.separator
  213. String
  214. \t
  215. The
  216. separator to use when passing the input key and value strings to the stream map process as a stream of bytes
  217. stream.map.output.field.separator
  218. String
  219. \t
  220. The
  221. separator to use when splitting the output from the stream map process into key and value strings for the map output
  222. stream.num.map.output.key.fields
  223. int
  224. 1
  225. The
  226. number of fields separated bystream.map.output.field.separator to
  227. treat as the map output key
  228. stream.reduce.input.field.separator
  229. String
  230. \t
  231. The separator
  232. to use when passing the input key and value strings to the stream reduce process as a stream of bytes
  233. stream.reduce.output.field.separator
  234. String
  235. \t
  236. The
  237. separator to use when splitting the output from the stream reduce process into key and value strings for the final reduce output
  238. stream.num.reduce.output.key.fields
  239. int
  240. 1
  241. The
  242. number of fields separated bystream.reduce.output.field.separatorto
  243. treat as the reduce output key

  244. mapreduce中分隔符使用的地方。在标准输入输出和map-reducer之间。
  245.  

MapReduce 的类型与格式【编写最简单的mapreduce】(1)的更多相关文章

  1. MapReduce的类型与格式

    MapReduce的类型 默认的MR作业 默认的mapper是Mapper类,它将输入的键和值原封不动地写到输出中 默认的partitioner是HashPartitioner,它对每条记录的键进行哈 ...

  2. MapReduce输入输出类型、格式及实例

    输入格式 1.输入分片与记录 2.文件输入 3.文本输入 4.二进制输入 5.多文件输入 6.数据库格式输入 1.输入分片与记录 1.JobClient通过指定的输入文件的格式来生成数据分片Input ...

  3. 编写简单的Mapreduce程序并部署在Hadoop2.2.0上运行

    今天主要来说说怎么在Hadoop2.2.0分布式上面运行写好的 Mapreduce 程序. 可以在eclipse写好程序,export或用fatjar打包成jar文件. 先给出这个程序所依赖的Mave ...

  4. MapReduce实例-NASA博客数据频度简单分析

    环境: Hadoop1.x,CentOS6.5,三台虚拟机搭建的模拟分布式环境,gnuplot, 数据:http://ita.ee.lbl.gov/html/contrib/NASA-HTTP.htm ...

  5. 编写一个简单的C++程序

    编写一个简单的C++程序 每个C++程序都包含一个或多个函数(function),其中一个必须命名为main.操作系统通过调用main来运行C++程序.下面是一个非常简单的main函数,它什么也不干, ...

  6. XHTML 是以 XML 格式编写的 HTML

    什么是 XHTML? XHTML 指的是可扩展超文本标记语言 XHTML 与 HTML 4.01 几乎是相同的 XHTML 是更严格更纯净的 HTML 版本 XHTML 是以 XML 应用的方式定义的 ...

  7. javascript编写一个简单的编译器(理解抽象语法树AST)

    javascript编写一个简单的编译器(理解抽象语法树AST) 编译器 是一种接收一段代码,然后把它转成一些其他一种机制.我们现在来做一个在一张纸上画出一条线,那么我们画出一条线需要定义的条件如下: ...

  8. Azkaban各种类型的Job编写

    一.概述 原生的 Azkaban 支持的plugin类型有以下这些: command:Linux shell命令行任务 gobblin:通用数据采集工具 hadoopJava:运行hadoopMR任务 ...

  9. 用C语言编写一个简单的词法分析程序

    问题描述: 用C或C++语言编写一个简单的词法分析程序,扫描C语言小子集的源程序,根据给定的词法规则,识别单词,填写相应的表.如果产生词法错误,则显示错误信息.位置,并试图从错误中恢复.简单的恢复方法 ...

随机推荐

  1. 2019-03-18 使用Request POST获取CNABS网站上JSON格式的表格数据,并解析出来用pymssql写到SQL Server中

    import requests import pymssql url = 'https://v1.cn-abs.com/ajax/ChartMarketHandler.ashx' headers = ...

  2. java有参无参构造器的的执行顺序

    这里拿了用数组构造栈的一段代码说明一下 public class StackArray<E> { private Object[] data = null; private int max ...

  3. yqj2065经典语录

    在上课时.博客中和<编程导论(Java)>书中,yqj2065说过一些简短的话.列举一些玩玩. 假设您在我的博客中看见好玩的,最好还是推荐一下. 持续加入中... 1. "噢姐姐 ...

  4. node11---相册

    app.js /* littleAlbum --.idea --controller(控制层相当于action层) --package.json --router.js --models(做事的是mo ...

  5. MongoDB基本概念和安装配置

    基本概念 MongoDB直接存储JSON. 有了NoSQL数据库之后,可以直接在业务层将数据按照指定的结构进行存储. NO SQL NoSQL 1 数据库 数据库 2 表 集合 3 行 文档 4 列 ...

  6. nyoj--55--懒省事的小明(STL优先队列)

    懒省事的小明 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述       小明很想吃果子,正好果园果子熟了.在果园里,小明已经将所有的果子打了下来,而且按果子的不同种类分 ...

  7. Vmware Workstation及Centos6.8 的安装

    转自:http://www.mamicode.com/info-detail-1462939.html 一.什么是Vmware Workstation Vmware Workstation是Vmwar ...

  8. VM虚拟机上的CentOS 7系统重置root用户密码

    1.开机在进入CentOS系统时(还未进入系统内)的系统选择页面时按E键进入系统编辑模式 2.找到Linux16开头的这行代码,用方向键将光标移动至这行代码的结尾,键入一个空格和rd.break,然后 ...

  9. Windows常见软件故障及解决方案

    HM NIS Edit: HM NIS Edit 新建程序向导无效,提示“Please specify the setup lang” 说明 NSIS 安装不对.解决方案有二种: 1. 重装 NSIS ...

  10. 一个php处理图片裁剪,压缩,水印的小代码

    插件地址:https://github.com/cigua/imagefilter