大数据学习之路11-mapreduce编程案例job提交器开发及启动测试

这个mapreduce要想正常的而运行起来,我们就需要将MR程序的jar包提交给yarn运行,关键的关键是依靠MrAppMaster,而MrAppMaster要想启动正确数量的maptask和正确数量的reducetask它就必须知道该启动几个。它还得知道输入数据在哪。而jar包中不包含这些信息。我们就没告诉他数据要处理哪里,输入目录在哪,输出目录在哪。数据到底要分几片。reduce那边到底有几个?还有maptask根本就不知道要调用哪个Mapper类中的map方法。所以我们不是将jar包丢给yarn就完事了,我们还需要配置很多信息。并且将信息和jar包一起交给yarn。yarn就把MrAppMaster启动起来了。MrAppMaster就开始读那些信息,读到那些信息之后,它自然就知道该如何启动maptask和reducetask了。在程序中要配置这些信息我们可以使用Job类。

package com.test.wordcount;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

import org.apache.hadoop.io.Text;

/**
 *本程序的功能是提交我的MR程序给yarn集群。 
 * @author 刘峰瑞
 *
 * 2018年8月10日下午5:54:01
 */
public class Driver {
         public static void main(String[] args) throws Exception {
        	 Configuration conf = new Configuration();
        	 //不设置这个就不会提交给yarn,只会在本地模拟执行
        	 //(如果我们不想再这里设置,我们也可以在hdfs的配置文件中写)
        	 //因为我们执行jar包的时候会加载所有需要的配置文件,
        	 //这个配置文件只对mapreduce程序有用
        	 //我们可以配置在mapred-site.xml.template中
        	 //但是后缀名为template是不会读的我们需要进行改名
        	 //mv mapred-site.xml.template  mapred-site.xml
        	// conf.set("mapreduce.framework.name", "yarn");
			 Job job = Job.getInstance(conf);
			 //设置程序jar包文件所在的路径---用类加载器动态获取
			 job.setJarByClass(Driver.class);
			 
			 //设置maptask和reducetask分别要调用的mapper类和reducer类
			 job.setMapperClass(WordCountMapper.class);
			 job.setReducerClass(WordCountReducer.class);
			 
			 //设置maptask产生的kv数据类型
			 job.setMapOutputKeyClass(Text.class);
			 job.setMapOutputValueClass(IntWritable.class);
			 
			 //设置reducetask产生的kv数据类型
			 job.setOutputKeyClass(Text.class);
			 job.setOutputValueClass(IntWritable.class);
			 
			 //设置输入数据所在的路径
			 /**
			  * 这里导FileInputFormat包的时候导包名长的那个,包名短的那个是旧版的。
			  * 已经没人用了
			  * 写路径的时候我们只需要指定到目录位置,哪怕目录中有多个文件也会一起处理了。
			  */
			 FileInputFormat.setInputPaths(job,new Path("/wordcount/input/"));
			 
			 //设置输出结果所在路径
			 FileOutputFormat.setOutputPath(job, new Path("/wordcount/output/"));
			 
			 //设置reducetask的并行实例数
			 job.setNumReduceTasks(3);
			 
			 /**
			  * 我们把该设置的东西都设置之后我们就该将这个东西提交给yarn了。
			  * 提交的时候也不需要我们自己去交互请求,他将这些操作全封装在方法中了
			  * 这个方法会将这些信息全部写成文件加上jar包文件一起发给Yarn,然后
			  * yarn就会启动MrAppMaster,这时MrAppMaster就可以看见我们设置的参数文件。
			  * 
			  */
			//但是这种方法执行完就结束了,它不知道你的mapreduce程序跑的结果是什么样
			// job.submit();
			 
			 //这种方法会与mapreduce程序进行交互
			 //这里的参数的意思是要不要将从resource manager拿到的汇报信息打印到控制台
			 //返回值是程序是否成功执行
			boolean res = job.waitForCompletion(true);
			System.out.println(res?"mr程序已经成功执行完毕":"mr程序好像被外星人抓走了");
		}
}

我们在执行jar包的时候需要将/wordcount/output/下面的文件提前删除,否则它会认为操作会破坏你的文件,会报错。

这里贴出我执行jar包时遇到的错误:

Error: java.io.IOException: Initialization of all the collectors failed.
Error in last collector was :class com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$Text

这里是因为我在程序中导错Text的jar包了。

正确的jar包应该为:import org.apache.hadoop.io.Text;

还有就是位置主机名的错误导致reduce过程错误。这个错误的原因是,我在marshal主机的hosts文件中设置了其他机器的ip但是其他主机中的hosts文件中没有设置别的主机的ip。

这个程序和我们之前写过的唯一的区别就是我们的程序map的中间结果放在hdfs中。而它的中间结果放在自己的本地磁盘。那么放在自己的本地磁盘,reducetask是怎么拿到的呢?其实就是通过http下载。那就意味着在这些机器上都必须有web服务器。那么有没有呢?答案是有的。这些maptask是运行在node manager上面的。而node manager集群是一个服务。它就有web。所以我们才需要在yarn-site.xml中配置yarn.nodemanager.aux-services为mapreduce_shuffle。这个就会提供一个文件下载的辅助功能。

接下来我们来梳理一下整个mapreduce流程。

我们需要写的东西只有三个:map逻辑,reduce逻辑,和yarn客户端去提交job。

扫描二维码关注公众号,回复: 2852581 查看本文章

猜你喜欢

转载自blog.csdn.net/qq_37050372/article/details/81625506