Hadoop mapreduce核心功能描述

2019-03-28 13:45|来源: 网络

核心功能描述
应用程序通常会通过提供map和reduce来实现 Mapper和Reducer接口,它们组成作业的核心。

Mapper
Mapper将输入键值对(key/value pair)映射到一组中间格式的键值对集合。

Map是一类将输入记录集转换为中间格式记录集的独立任务。 这种转换的中间格式记录集不需要与输入记录集的类型一致。一个给定的输入键值对可以映射成0个或多个输出键值对。

Hadoop Map/Reduce框架为每一个InputSplit产生一个map任务,而每个InputSplit是由该作业的InputFormat产生的。

概括地说,对Mapper的实现者需要重写 JobConfigurable.configure(JobConf)方法,这个方法需要传递一个JobConf参数,目的是完成Mapper的初始化工作。然后,框架为这个任务的InputSplit中每个键值对调用一次 map(WritableComparable, Writable, OutputCollector, Reporter)操作。应用程序可以通过重写Closeable.close()方法来执行相应的清理工作。

输出键值对不需要与输入键值对的类型一致。一个给定的输入键值对可以映射成0个或多个输出键值对。通过调用 OutputCollector.collect(WritableComparable,Writable)可以收集输出的键值对。

应用程序可以使用Reporter报告进度,设定应用级别的状态消息,更新Counters(计数器),或者仅是表明自己运行正常。

框架随后会把与一个特定key关联的所有中间过程的值(value)分成组,然后把它们传给Reducer以产出最终的结果。用户可以通过 JobConf.setOutputKeyComparatorClass(Class)来指定具体负责分组的 Comparator。

Mapper的输出被排序后,就被划分给每个Reducer。分块的总数目和一个作业的reduce任务的数目是一样的。用户可以通过实现自定义的 Partitioner来控制哪个key被分配给哪个 Reducer。

用户可选择通过 JobConf.setCombinerClass(Class)指定一个combiner,它负责对中间过程的输出进行本地的聚集,这会有助于降低从Mapper到 Reducer数据传输量。

这些被排好序的中间过程的输出结果保存的格式是(key-len, key, value-len, value),应用程序可以通过JobConf控制对这些中间结果是否进行压缩以及怎么压缩,使用哪种 CompressionCodec。

需要多少个Map?
Map的数目通常是由输入数据的大小决定的,一般就是所有输入文件的总块(block)数。

Map正常的并行规模大致是每个节点(node)大约10到100个map,对于CPU 消耗较小的map任务可以设到300个左右。由于每个任务初始化需要一定的时间,因此,比较合理的情况是map执行的时间至少超过1分钟。

这样,如果你输入10TB的数据,每个块(block)的大小是128MB,你将需要大约82,000个map来完成任务,除非使用 setNumMapTasks(int)(注意:这里仅仅是对框架进行了一个提示(hint),实际决定因素见这里)将这个数值设置得更高。

Reducer
Reducer将与一个key关联的一组中间数值集归约(reduce)为一个更小的数值集。

用户可以通过 JobConf.setNumReduceTasks(int)设定一个作业中reduce任务的数目。

概括地说,对Reducer的实现者需要重写 JobConfigurable.configure(JobConf)方法,这个方法需要传递一个JobConf参数,目的是完成Reducer的初始化工作。然后,框架为成组的输入数据中的每个<key, (list of values)>对调用一次 reduce(WritableComparable, Iterator, OutputCollector, Reporter)方法。之后,应用程序可以通过重写Closeable.close()来执行相应的清理工作。

Reducer有3个主要阶段:shuffle、sort和reduce。

Shuffle
Reducer的输入就是Mapper已经排好序的输出。在这个阶段,框架通过HTTP为每个Reducer获得所有Mapper输出中与之相关的分块。

Sort
这个阶段,框架将按照key的值对Reducer的输入进行分组 (因为不同mapper的输出中可能会有相同的key)。

Shuffle和Sort两个阶段是同时进行的;map的输出也是一边被取回一边被合并的。

Secondary Sort
如果需要中间过程对key的分组规则和reduce前对key的分组规则不同,那么可以通过 JobConf.setOutputValueGroupingComparator(Class)来指定一个Comparator。再加上 JobConf.setOutputKeyComparatorClass(Class)可用于控制中间过程的key如何被分组,所以结合两者可以实现按值的二次排序。

Reduce
在这个阶段,框架为已分组的输入数据中的每个 <key, (list of values)>对调用一次 reduce(WritableComparable, Iterator, OutputCollector, Reporter)方法。

Reduce任务的输出通常是通过调用 OutputCollector.collect(WritableComparable, Writable)写入 文件系统的。

应用程序可以使用Reporter报告进度,设定应用程序级别的状态消息,更新Counters(计数器),或者仅是表明自己运行正常。

相关问答

更多
  • 它们被分离出来,因为这两个包都代表2个不同的API。 org.apache.hadoop.mapred是旧的API, org.apache.hadoop.mapreduce是新的。 这样做是为了让程序员以更方便,更简单和复杂的方式编写MapReduce作业。 您可能会发现此演示文稿很有用,其中详细讨论了不同之处。 希望这回答你的问题。 They are separated out because both of these packages represent 2 different APIs. org.a ...
  • 本教程提到: 下载Hadoop-core-1.2.1.jar,用于编译和执行MapReduce程序。 访问以下链接http://mvnrepository.com/artifact/org.apache.hadoop/hadoop-core/1.2.1下载jar。 所以在这里你可以找到不同版本的所有罐子 This tutorial mentions : Download Hadoop-core-1.2.1.jar, which is used to compile and execute the MapRe ...
  • 它是实现正确的接口还是为reducer实现扩展正确的类。 例外情况表明实现方法中的包差异与使用相比(新旧vso hadoop api) Is it implementing the correct interface or extending the correct class for the reducer implementation. The exception says a package difference in the implementation method required vs the ...
  • 做了一个全新安装的hadoop并用同一个罐子运行工作,问题就消失了。 似乎是一个错误,而不是编程错误。 Did a fresh installation of hadoop and ran the job with the same jar, the problem disappeared. Seems to be a bug rather than programming errors.
  • Hadoop有asm 3.2而我使用的是ASM 5.在ASM5中,ClassVisitor是一个超类,而在3.2中它是一个接口。 出于某种原因,错误是Throwable(信任Shevek),catch块只捕获异常。 任何hadoop日志都没有捕获throwable错误。 因此,调试非常困难。 使用jar jar链接修复asm版本问题,现在一切正常。 如果你正在使用Hadoop并且某些东西不起作用并且没有日志显示任何错误,那么请尝试抓住Throwable。 阿伦 Hadoop had asm 3.2 and ...
  • 您应该添加/usr/lib/hadoop-0.xx/lib找到的所有jar以避免这种类路径问题。 为了给你一个想法,你可以输入hadoop classpath ,它将打印出获取Hadoop jar和所需库所需的类路径。 在你的情况下,你错过了hadoop-common-0.xx.jar ,所以你应该把它添加到classpath中,你应该很好。 You should add all the jars found in /usr/lib/hadoop-0.xx/lib to avoid this kind of ...
  • 假设zipIn是java.util.zip.ZipInputStream ,你不应该迭代地调用getNextEntry而不是读取字节吗? I resolved this issue after doing some changes in my code. In the first part of code, I was trying to unzip all the zip files whereas I should have access the spilts. Hadoop basic, which ...
  • mapper的输出键和值类型应该是reducer的输入类型,因此在你的情况下,reducer必须继承自 Reducer setOutputKeyClass和setOutputValueClass设置作业输出的类型,即map和reduce。 如果要为映射器指定其他类型,则应使用方法setMapOutputKeyClass和setMapOutputValueClass 。 作为旁注,当您不希望输出中的真值时,为什么要从 ...
  • Mapper接口按以下顺序需要4个类型参数:Map输入键,Map输入值,Map输出键和Map输出值。 在您的情况下,由于您正在处理4个整数,其中3个构成您的值,1个是您的密钥,因此使用IntWritable作为Map输入键并且应该使用Text而错误。 此外,您在MapClass定义中指定的类型与传递给Map函数的类型不匹配。 鉴于您正在处理文本文件,您的MapClass应定义如下: public static class MapClass extends MapReduceBase implements M ...
  • 我按原样使用了您的代码,并在进行了3次修改后进行了编译: 在以下语句中,将filename更改为fileName ( fileName 'N'大写) 更改: word.set(itr.nextToken().toLowerCase().replaceAll("[^a-z]+","") +" "+ filename); 至: word.set(itr.nextToken().toLowerCase().replaceAll("[^a-z]+","") +" "+ fileName); 导入的包Gene ...