请简述mapreduce计算的主要流程

请简述mapreduce计算的主要流程,第1张

1.输入:输入数据分为键/值对,由集群中的每个节点处理。2.映射函数:使用输入数据中的每个键/值对来调用用户定义的映射函数,以生成一组中间键/值对。3.Shuffle:将中间的键/值对分组,并将其发送到正确的节点。4.Reduce函数:将同一个键的中间值赋给reduce函数并聚合它们。5.输出:将最终的键/值对发送到输出文件。1)输入数据接口:InputFormat。默认的实现类是:TextInputFormat。TextInputFormat的功能逻辑是:一次读取一行文本,然后以该行的起始偏移量为键,将行内容作为值返回。CombineTextInputFormat可以将多个小文件合并成一个切片,提高处理效率。(2)逻辑处理接口:映射器用户根据业务需求实现三种方法:map() setup() cleanup()。(3)划分器划分HashPartitioner有一个默认实现,逻辑是根据key和numReduces的哈希值返回一个分区号;key.hashCode()&Integer。最大值% numReduces如果业务上有特殊需求,可以定制分区。(4)厘米平行排序当我们使用自定义对象作为输出的键时,必须实现WritableComparable接口,并在其中重写compareTo()方法。部分排序:每个最终输出文件的内部排序。全排序:对所有数据进行排序,通常只减少一次。二次排序:排序有两个条件。(5)合并者合并合并器合并可以提高程序执行的效率,减少IO传输。但使用时不得影响原业务处理结果。(6)逻辑处理接口:减速器用户根据业务需求实现三种方法:reduce() setup() cleanup()。(7)输出数据接口:OutputFormat默认的实现类是TextOutputFormat,功能逻辑是:为每个KV对输出一行到目标文本文件。用户还可以自定义输出格式。

Mapreduce简介

Hadoop MapReduce 源于Google发表的 MapReduce论文。Hadoop MapReduce 其实就是Google MapReduce的一个克隆版本。Hadoop 2.0即第二代Hadoop系统,其框架最核心的设计是HDFS、MapReduce和YARN。其中,HDFS为海量数据提供存储,MapReduce用于分布式计算,YARN用于进行资源管理。

其实,一次mapreduce过程就包括上图的6个步骤,input、splitting、mapping、shuffling、redecing、final redult。

文件要存储在HDFS中,每个文件被切分成多个一定大小的块也就是Block,(Hadoop1.0默认为64M,Hadoop2.0默认为128M),并且默认3个备份存储在多个的节点中。

MR通过Inputformat将数据文件从HDFS中读入取,读取完后会对数据进行split切片,切片的数量根据Block的大小所决定,然后每一个split的个数又决定map的个数,即一个split会分配一个maptask并行实例处理。

如何确定切分的文件大小?

数据进入到map函数中,然后开始按照一定的规则切分。其实这就是我们自定义的计算逻辑,我们编写mr程序的map函数的逻辑一般就在这个阶段执行。企业应用为了追求开发效率,一般都使用hive sql代替繁琐的mr程序了,这里附上一个经典的wordcount的map函数重温一下吧。

Shuffle是我们不需要编写的模块,但却是十分关键的模块。

在map中,每个 map 函数会输出一组 key/value对, Shuffle 阶段需要从所有 map主机上把相同的 key 的 key value对组合在一起,(也就是这里省去的Combiner阶段)组合后传给 reduce主机, 作为输入进入 reduce函数里。

Partitioner组件 负责计算哪些 key 应当被放到同一个 reduce 里

HashPartitioner类,它会把 key 放进一个 hash函数里,然后得到结果。如果两个 key 的哈希值 一样,他们的 key/value对 就被放到同一个 reduce 函数里。我们也把分配到同一个 reduce函数里的 key /value对 叫做一个reduce partition.

我们看到 hash 函数最终产生多少不同的结果, 这个 Hadoop job 就会有多少个 reduce partition/reduce 函数,这些 reduce函数最终被JobTracker 分配到负责 reduce 的主机上,进行处理。

Map方法之后,数据首先进入到分区方法,把数据标记好分区,然后把数据发送到环形缓冲区;环形缓冲区默认大小100m,环形缓冲区达到80%时,进行溢写; 溢写前对数据进行排序 ,排序按照对key的索引进行字典顺序排序,排序的手段快排;溢写产生大量溢写文件,需要 对溢写文件进行归并排序 ;对溢写的文件也可以进行Combiner *** 作,前提是汇总 *** 作,求平均值不行。最后将文件按照分区存储到磁盘,等待Reduce端拉取。每个Reduce拉取Map端对应分区的数据。拉取数据后先存储到内存中,内存不够了,再存储到磁盘。拉取完所有数据后, 采用归并排序将内存和磁盘中的数据都进行排序 。在进入Reduce方法前,可以对数据进行分组 *** 作。值得注意的是, 整个shuffle *** 作是有3次排序的。

reduce() 函数以 key 及对应的 value 列表作为输入,按照用户自己的程序逻辑,经合并 key 相同的 value 值后,产 生另外一系列 key/value 对作为最终输出写入 HDFS。

一、 首先要知道此前提 转载

若在windows的Eclipse工程中直接启动mapreduc程序,需要先把hadoop集群的配置目录下的xml都拷贝到src目录下,让程序自动读取集群的地址后去进行分布式运行(您也可以自己写java代码去设置job的configuration属性)。

若不拷贝,工程中bin目录没有完整的xml配置文件,则windows执行的mapreduce程序全部通过本机的jvm执行,作业名也是带有“local"字眼的作业,如 job_local2062122004_0001。 这不是真正的分布式运行mapreduce程序。

估计得研究org.apache.hadoop.conf.Configuration的源码,反正xml配置文件会影响执行mapreduce使用的文件系统是本机的windows文件系统还是远程的hdfs系统还有影响执行mapreduce的mapper和reducer的是本机的jvm还是集群里面机器的jvm

二、 本文的结论

第一点就是: windows上执行mapreduce,必须打jar包到所有slave节点才能正确分布式运行mapreduce程序。(我有个需求是要windows上触发一个mapreduce分布式运行)

第二点就是: Linux上,只需拷贝jar文件到集群master上,执行命令hadoop jarPackage.jar MainClassName即可分布式运行mapreduce程序。

第三点就是: 推荐使用附一,实现了自动打jar包并上传,分布式执行的mapreduce程序。

附一、 推荐使用此方法:实现了自动打jar包并上传,分布式执行的mapreduce程序:

请先参考博文五篇:

Hadoop作业提交分析(一)~~(五)

引用博文的附件中EJob.java到你的工程中,然后main中添加如下方法和代码。

public static File createPack() throws IOException {

File jarFile = EJob.createTempJar("bin")

ClassLoader classLoader = EJob.getClassLoader()

Thread.currentThread().setContextClassLoader(classLoader)

return jarFile

}

在作业启动代码中使用打包:

Job job = Job.getInstance(conf, "testAnaAction")

添加:

String jarPath = createPack().getPath()

job.setJar(jarPath)

即可实现直接run as java application 在windows跑分布式的mapreduce程序,不用手工上传jar文件。

附二、得出结论的测试过程

(未有空看书,只能通过愚笨的测试方法得出结论了)

一. 直接通过windows上Eclipse右击main程序的java文件,然后"run as application"或选择hadoop插件"run on hadoop"来触发执行MapReduce程序的测试。

1,如果不打jar包到进集群任意linux机器上,它报错如下:

[work] 2012-06-25 15:42:47,360 - org.apache.hadoop.mapreduce.Job -10244 [main] INFO org.apache.hadoop.mapreduce.Job - map 0% reduce 0%

[work] 2012-06-25 15:42:52,223 - org.apache.hadoop.mapreduce.Job -15107 [main] INFO org.apache.hadoop.mapreduce.Job - Task Id : attempt_1403517983686_0056_m_000000_0, Status : FAILED

Error: java.lang.RuntimeException: java.lang.ClassNotFoundException: Class bookCount.BookCount$BookCountMapper not found

at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:1720)

at org.apache.hadoop.mapreduce.task.JobContextImpl.getMapperClass(JobContextImpl.java:186)

at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:721)

at org.apache.hadoop.mapred.MapTask.run(MapTask.java:339)

at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:162)

at java.security.AccessController.doPrivileged(Native Method)

at javax.security.auth.Subject.doAs(Subject.java:415)

at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1491)

at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:157)

Caused by: java.lang.ClassNotFoundException: Class bookCount.BookCount$BookCountMapper not found

at org.apache.hadoop.conf.Configuration.getClassByName(Configuration.java:1626)

at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:1718)

... 8 more

# Error:后重复三次

2012-06-25 15:44:53,234 - org.apache.hadoop.mapreduce.Job -37813 [main] INFO org.apache.hadoop.mapreduce.Job - map 100% reduce 100%

现象就是:报错,无进度,无运行结果。

2,拷贝jar包到“只是”集群master的$HADOOP_HOME/share/hadoop/mapreduce/目录上,直接通过windows的eclipse "run as application"和通过hadoop插件"run on hadoop"来触发执行,它报错同上。

现象就是:报错,无进度,无运行结果。

3,拷贝jar包到集群某些slave的$HADOOP_HOME/share/hadoop/mapreduce/目录上,直接通过windows的eclipse "run as application"和通过hadoop插件"run on hadoop"来触发执行

和报错:

Error: java.lang.RuntimeException: java.lang.ClassNotFoundException: Class bookCount.BookCount$BookCountMapper not found

at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:1720)

at org.apache.hadoop.mapreduce.task.JobContextImpl.getMapperClass(JobContextImpl.java:186)

和报错:

Error: java.lang.RuntimeException: java.lang.ClassNotFoundException: Class bookCount.BookCount$BookCountReducer not found

现象就是:有报错,但仍然有进度,有运行结果。

4,拷贝jar包到集群所有slave的$HADOOP_HOME/share/hadoop/mapreduce/目录上,直接通过windows的eclipse "run as application"和通过hadoop插件"run on hadoop"来触发执行:

现象就是:无报错,有进度,有运行结果。

第一点结论就是: windows上执行mapreduce,必须打jar包到所有slave节点才能正确分布式运行mapreduce程序。

二 在Linux上的通过以下命令触发MapReduce程序的测试。

hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/bookCount.jar bookCount.BookCount

1,只拷贝到master,在master上执行。

现象就是:无报错,有进度,有运行结果。

2,拷贝随便一个slave节点,在slave上执行。

现象就是:无报错,有进度,有运行结果。

但某些节点上运行会报错如下,且运行结果。:

14/06/25 16:44:02 INFO mapreduce.JobSubmitter: Cleaning up the staging area /tmp/hadoop-yarn/staging/hduser/.staging/job_1403517983686_0071

Exception in thread "main" java.lang.NoSuchFieldError: DEFAULT_MAPREDUCE_APPLICATION_CLASSPATH

at org.apache.hadoop.mapreduce.v2.util.MRApps.setMRFrameworkClasspath(MRApps.java:157)

at org.apache.hadoop.mapreduce.v2.util.MRApps.setClasspath(MRApps.java:198)

at org.apache.hadoop.mapred.YARNRunner.createApplicationSubmissionContext(YARNRunner.java:443)

at org.apache.hadoop.mapred.YARNRunner.submitJob(YARNRunner.java:283)

at org.apache.hadoop.mapreduce.JobSubmitter.submitJobInternal(JobSubmitter.java:415)

at org.apache.hadoop.mapreduce.Job$10.run(Job.java:1268)

at org.apache.hadoop.mapreduce.Job$10.run(Job.java:1265)

at java.security.AccessController.doPrivileged(Native Method)

at javax.security.auth.Subject.doAs(Subject.java:415)

at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1491)

at org.apache.hadoop.mapreduce.Job.submit(Job.java:1265)

at org.apache.hadoop.mapreduce.Job.waitForCompletion(Job.java:1286)

at com.etrans.anaSpeed.AnaActionMr.run(AnaActionMr.java:207)

at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:70)

at com.etrans.anaSpeed.AnaActionMr.main(AnaActionMr.java:44)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:606)

at org.apache.hadoop.util.RunJar.main(RunJar.java:212)

第二点结论就是: Linux上,只需拷贝jar文件到集群master上,执行命令hadoop jarPackage.jar MainClassName即可分布式运行mapreduce程序。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12101201.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-21
下一篇 2023-05-21

发表评论

登录后才能评论

评论列表(0条)

保存