Hadoop 键值对的MapReduce过程剖析

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

Hadoop的Mapreduce是一个分布并行处理大数据的程序框架,一个Map/Reduce 作业(job) 通常会把输入的数据集切分为若干独立的数据块,由 map任务(task)以完全并行的方式处理它们。框架会对map的输出先进行排序, 然后把结果输入给reduce任务。通常作业的输入和输出都会被存储在文件系统中。

MapReduce程序是通过键值对来操作数据的,其单个输入输出形式如下:

map: key1,value1 ----> list(key2,value2)

reduce: (key2,list(value2))----> key3,value3

一、Mapreduce操作的数据也是保存在文件系统HDFS上,InputFormat接口定义的就是如何读取文件和分割文件提供分片给mapper,TextInputFormat文本格式输入 是InputFormat的默认实现类

它主要负责:

1. 把输入文件切分成多个逻辑InputSplit实例, 并把每一实例分别分发给一个 Mapper.

2.提供RecordReader的实现,这个RecordReader从逻辑InputSplit中获得输入记录, 这些记录将由Mapper处理

二、在input输入的进来的(key1,value1)经过mapper处理变成list(key2,value2),可由combiner进行进行一次本地聚合,减少mapper输出的list(key2,value2)的数量

三、对于mapper的的结果,然后在经过shuffle阶段由partitioner定义如何分配(key,value)给reducer作为输入(key2,list(value2))进行最后的合并,得到输出结果(key3,value3)

四、与InputFormat对应,如何将mapreduce的结果输出是由OutputFormat接口来定义的,每个reducer将自己的输入写入自己的文件中,而RecordWriter对象将输出结果进行格式化的

摘自官方文档上的WordCount数据示例部分来分析下mapreduce中(key,value)是如果分解合并的 
文件file0:  Hello World Bye World 
  file1:  Hello Hadoop Goodbye Hadoop 
 
第一个输入,默认的采用TextInputFormat的map输入 (key:一行的字节偏移 value:就是这行的内容) 
输出是: 
< Hello, 1> 
< World, 1> 
< Bye, 1> 
< World, 1> 
第二个输入,map输出是: 
< Hello, 1> 
< Hadoop, 1> 
< Goodbye, 1> 
< Hadoop, 1> 
 
Map运行之后,会对输出按照key进行排序,然后把输出传递给本地的combiner(按照作业的配置与Reducer一样),进行本地聚合,数据不会在节点上传输的 
所以第一个map的输出会变成: 
< Bye, 1> 
< Hello, 1> 
< World, 2> 
第二个map的输出会变成: 
< Goodbye, 1> 
< Hadoop, 2> 
< Hello, 1> 
然后在经过shuffle阶段把map的结果传给Reducer,将每个key(本例中就是单词)出现的次数求和,节点间的 
数据交换就是在shuffle阶段的,至于每个(key,value)是如何分配给不同的reduce是通过Partitioner指定的,默认采用的是HashPartitioner。 
最后这个作业的输出就是: 
< Bye, 1> 
< Goodbye, 1> 
< Hadoop, 2> 
< Hello, 2> 
< World, 2> 

相关问答

更多
  • 它们被分离出来,因为这两个包都代表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中,您处理输入拆分而不是块。 输入拆分是完整的数据集。 您希望避免一个映射器超过两个拆分的情况,因为这会降低性能并创建流量。 在文本世界中,假设您在block1中并且您有一个句子,例如“我是一个哈”,而block2继续“doop developer”,那么这会创建网络流量,因为我们始终必须在一个完整的节点上工作输入拆分和一些数据必须转移到另一个节点。 In Hadoop you work on input splits and not on blocks. An input split is ...
  • 做了一个全新安装的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 ...