6.2.2 辅助类GenericOptionsParser,Tool和ToolRunner深入解析
辅助类GenericOptionsParser,Tool和ToolRunner
(1)为什么要用ToolRunner
将MapReduce Job配置参数写到java代码里,一旦变更意味着修改java文件源码、编译、打包、部署一连串事情。当MapReduce 依赖配置文件的时候,你需要手工编写java代码使用DistributedCache将其上传到HDFS中,以便map和reduce函数可以读取。:当你的map或reduce 函数依赖第三方jar文件时,你在命令行中使用”-libjars”参数指定依赖jar包时,但根本没生效。Hadoop有个可以GenericOptionsParser是一个类,用来解释常用的Hadoop命令行选项,通过简单的命令行参数来实现这样的功能,为Configuration对象设置相应的取值。通常不直接使用GenericOptionsParser,更方便的方式是:实现Tool接口,通过ToolRunner来运行应用程序,ToolRunner内部调用GenericOptionsParser来解析命令行。设置Configuration对象。
(2)使用ToolRunner步骤
自定义一个ToolRunner类ToolRunnerDemo类,继承Configured类,实现Tool接口,实现Tool的run(String [] args)方法,并在main函数中调用ToolRunner. run(Tool tool, String[] args)静态方法。Run方法内部创建GenericOptionsParser parser = new GenericOptionsParser(conf, args);调用GenericOptionsParser解析命令行参数,解析完之后将参数设置到Configuration对象中。
1)创建ToolRunnerDemo对象

package org.jediael.hadoopdemo.toolrunnerdemo;
import java.util.Map.Entry;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
public class ToolRunnerDemo extends Configured implements Tool {
static {
//Configuration.addDefaultResource("hdfs-default.xml");
//Configuration.addDefaultResource("hdfs-site.xml");
//Configuration.addDefaultResource("mapred-default.xml");
//Configuration.addDefaultResource("mapred-site.xml");
}
@Override
public int run(String[] args) throws Exception {
Configuration conf = getConf();
for (Entry<String, String> entry : conf) {
System.out.printf("%s=%s\n", entry.getKey(), entry.getValue());
}
return 0;
}
public static void main(String[] args) throws Exception {
int exitCode = ToolRunner.run(new ToolRunnerDemo(), args);//ToolRunnerDemo对象实现了Tool接口,形参传入对象引用,在调用tool.run()方法,实际是调用ToolRunner重写的run方法。
System.exit(exitCode);
}
}
Configurable接口只有两个函数,获取设置Configuration对象
package org.apache.hadoop.conf;
public interface Configurable {
void setConf(Configuration conf);
Configuration getConf();
}
Configred类实现了Configurable接口
package org.apache.hadoop.conf;
public class Configured implements Configurable {
private Configuration conf;
public Configured() {
this(null);
}
public Configured(Configuration conf) {
setConf(conf);
}
public void setConf(Configuration conf) {
this.conf = conf;
}
public Configuration getConf() {
return conf;
}
}
2)ToolRunner.run()函数内部创建GenericOptionsParser对象
public static int run(Configuration conf, Tool tool, String[] args) throws Exception {
if (conf == null) {
conf = new Configuration();
}
GenericOptionsParser parser = new GenericOptionsParser(conf, args);
tool.setConf(conf);
String[] toolArgs = parser.getRemainingArgs();
return tool.run(toolArgs);
}
3)GenericOptionsParser构造函数1调用构造函数2,构造函数2调用解析函数parseGeneralOptions
public GenericOptionsParser(Options opts, String[] args) throws IOException {
this(new Configuration(), opts, args);
}//构造函数1
public GenericOptionsParser(Configuration conf, Options options, String[] args) throws IOException {
this.parseGeneralOptions(options, conf, args);
this.conf = conf;
}//构造函数2
4)parseGeneralOptions先调用解析函数parser.parse解析命令行,然后再用函数this.processGeneralOptions()执行命令。
private void parseGeneralOptions(Options opts, Configuration conf, String[] args) throws IOException {
opts = buildGeneralOptions(opts);
GnuParser parser = new GnuParser();
try {
this.commandLine = parser.parse(opts, this.preProcessForWindows(args), true);
this.processGeneralOptions(conf, this.commandLine);
} catch (ParseException var7) {
LOG.warn("options parsing failed: " + var7.getMessage());
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp("general options are: ", opts);
}
}
5)processGeneralOptions函数内部会根据不同的命令选项:fs、jt、conf、libjars、files、archives进行设置。
private void processGeneralOptions(Configuration conf, CommandLine line) throws IOException {
//设置默认的文件系统
if (line.hasOption("fs")) {
FileSystem.setDefaultUri(conf, line.getOptionValue("fs"));
}
//设置jobtracker服务ip地址和端口,用于监听并接收来自各个TaskTracker发送的心跳信息,包括资源使用情况和任务运行情况等信息。
String fileName;
if (line.hasOption("jt")) {
fileName = line.getOptionValue("jt");
if (fileName.equalsIgnoreCase("local")) {
conf.set("mapreduce.framework.name", fileName);
}
conf.set("yarn.resourcemanager.address", fileName, "from -jt command line option");
}
//添加新的配置文件
String[] arr$;
int len$;
int i$;
String prop;
String[] property;
if (line.hasOption("conf")) {
property = line.getOptionValues("conf");
arr$ = property;
len$ = property.length;
for(i$ = 0; i$ < len$; ++i$) {
prop = arr$[i$];
conf.addResource(new Path(prop));
}
}
//从本地文件系统中复制指定的jar包到jobtracker使用的共享文件系统中,添加到mapreduce任务路径,这个选项是一个很有用放入方法来添加任务的依赖jar包。
if (line.hasOption("libjars")) {
conf.set("tmpjars", this.validateFiles(line.getOptionValue("libjars"), conf), "from -libjars command line option");
URL[] libjars = getLibJars(conf);
if (libjars != null && libjars.length > 0) {
conf.setClassLoader(new URLClassLoader(libjars, conf.getClassLoader()));
Thread.currentThread().setContextClassLoader(new URLClassLoader(libjars, Thread.currentThread().getContextClassLoader()));
}
}
//从本地文件系统中复制指定的文件到jobtracker使用的共享文件系统中,使他们能够被mapreduce任务使用
if (line.hasOption("files")) {
conf.set("tmpfiles", this.validateFiles(line.getOptionValue("files"), conf), "from -files command line option");
}
//从本地文件系统中复制指定的档案到jobtracker使用的共享文件系统中,使他们能够被mapreduce任务使用。
if (line.hasOption("archives")) {
conf.set("tmparchives", this.validateFiles(line.getOptionValue("archives"), conf), "from -archives command line option");
}
//给属性设置属性值
if (line.hasOption('D')) {
property = line.getOptionValues('D');
arr$ = property;
len$ = property.length;
for(i$ = 0; i$ < len$; ++i$) {
prop = arr$[i$];
String[] keyval = prop.split("=", 2);
if (keyval.length == 2) {
conf.set(keyval[0], keyval[1], "from command line");
}
}
}
conf.setBoolean("mapreduce.client.genericoptionsparser.used", true);
if (line.hasOption("tokenCacheFile")) {
fileName = line.getOptionValue("tokenCacheFile");
FileSystem localFs = FileSystem.getLocal(conf);
Path p = localFs.makeQualified(new Path(fileName));
if (!localFs.exists(p)) {
throw new FileNotFoundException("File " + fileName + " does not exist.");
}
if (LOG.isDebugEnabled()) {
LOG.debug("setting conf tokensFile: " + fileName);
}
UserGroupInformation.getCurrentUser().addCredentials(Credentials.readTokenStorageFile(p, conf));
conf.set("mapreduce.job.credentials.json", p.toString(), "from -tokenCacheFile command line option");
}
}
6)设置好配置之后,所有的命令行都解析执行,参数都添加到了Configuration对象之中,接下来就可以获取这些参数。
在第2)步的ToolRunner的run函数中
public static int run(Configuration conf, Tool tool, String[] args) throws Exception {
if (conf == null) {
conf = new Configuration();
}
GenericOptionsParser parser = new GenericOptionsParser(conf, args);
tool.setConf(conf);
String[] toolArgs = parser.getRemainingArgs();
return tool.run(toolArgs);
}
parser.getRemainingArgs();获取的实际上是第4)步中解析的命令行参数
public String[] getRemainingArgs() {
return this.commandLine == null ? new String[0] : this.commandLine.getArgs();
}
7)调用tool接口的run方法,实际是调用ToolRunnerDemo重写的run方法。因为ToolRunnerDemo对象实现了Tool接口,ToolRunner.run函数形参传入ToolRunnerDemo对象引用,在调用tool.run()方法, 实际是调用ToolRunnerDemo重写的run方法。
@Override
public int run(String[] args) throws Exception {
Configuration conf = getConf();
for (Entry<String, String> entry : conf) {//输出所有的属性值
System.out.printf("%s=%s\n", entry.getKey(), entry.getValue());
}
return 0;
}
(3)使用ToolRunnerDemo设置hadoop参数调用实例
1)使用ToolRunnerDemo输出所有配置属性
[root@jediael project]#hadoop jar toolrunnerdemo.jar org.jediael.hadoopdemo.toolrunnerdemo.ToolRunnerDemo
io.seqfile.compress.blocksize=1000000
keep.failed.task.files=false
mapred.disk.healthChecker.interval=60000
dfs.df.interval=60000
dfs.datanode.failed.volumes.tolerated=0
mapreduce.reduce.input.limit=-1
mapred.task.tracker.http.address=0.0.0.0:50060
mapred.used.genericoptionsparser=true
mapred.userlog.retain.hours=24
dfs.max.objects=0
mapred.jobtracker.jobSchedulable=org.apache.hadoop.mapred.JobSchedulable
mapred.local.dir.minspacestart=0
hadoop.native.lib=true
2)通过-D指定新的参数,-D设置参数color为yello,grep查看设置属性
[root@jediael project]# hadoop org.jediael.hadoopdemo.toolrunnerdemo.ToolRunnerDemo -D color=yello | grep color
color=yello
3)通过-conf增加新的配置文件,-conf用于添加配置文件,wc命令用于查看配置数量。
hadoop jar toolrunnerdemo.jar org.jediael.hadoopdemo.toolrunnerdemo.ToolRunnerDemo-conf /opt/jediael/hadoop-1.2.0/conf/mapred-site.xml | wc
68 68 3028
其中mapred-site.xml的内容如下:
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>mapred.job.tracker</name>
<value>localhost:9001</value>
</property>
</configuration>
(4)ToolRunner使用汇总
|
-D color=yello |
-D设置参数color为yello,grep查看设置属性 |
|
-conf conf/mapred-site.xml |
-conf用于添加配置文件 |
|
-fs uri |
//设置文件系统为uri指定的路径,等同-D fs.default.FS=url |
|
-jt 10.21.34.11:3800 |
//hadoop1中用于设置jobtracker的ip地址和端口,用于监听并接收来自各个TaskTracker发送的心跳信息,包括资源使用情况和任务运行情况等信息。hadoop2中用于指定YARN资源管理器地址。等同-D yarn.resourcemanager.address= 10.21.34.11:3800. |
|
-files file1,file2 |
从本地文件系统中复制指定的文件到jobtracker使用的共享文件系统中,使他们能够被mapreduce任务使用 |
|
-libjars jars1,jars2 |
从本地文件系统中复制指定的jar包到jobtracker使用的共享文件系统中,添加到mapreduce任务路径,这个选项是一个很有用放入方法来添加任务的依赖jar包。 |
|
-archives archive1,archive2 |
从本地文件系统中复制指定的档案到jobtracker使用的共享文件系统中,使他们能够被mapreduce任务使用。 |
参考文献:
https://blog.csdn.net/xin15200793067/article/details/12623797
https://blog.csdn.net/jediael_lu/article/details/38751885
https://blog.csdn.net/tototuzuoquan/article/details/72856761
自己开发了一个股票智能分析软件,功能很强大,需要的点击下面的链接获取:
https://www.cnblogs.com/bclshuai/p/11380657.html
6.2.2 辅助类GenericOptionsParser,Tool和ToolRunner深入解析的更多相关文章
- 关于Tool接口--------hadoop接口:extends Configured implements Tool 和 ToolRunner.run
我们在写Hadoop--map/reduce程序时,遇到使用按文件url来分析文件----------多表连接的DistributedCache方式,看不懂使用extends Configured i ...
- MapReduce编程实战之“调试”和"调优"
本篇内容 在上一篇的"初识"环节,我们已经在本地和Hadoop集群中,成功的执行了几个MapReduce程序,对MapReduce编程,已经有了最初的理解. 在本篇文章中,我们对M ...
- 使用ToolRunner运行Hadoop程序基本原理分析
为了简化命令行方式运行作业,Hadoop自带了一些辅助类.GenericOptionsParser是一个类,用来解释常用的Hadoop命令行选项,并根据需要,为Configuration对象设置相应的 ...
- 采用ToolRunner执行Hadoop基本面分析程序
为了简化执行作业的命令行.Hadoop它配备了一些辅助类.GenericOptionsParser它是一类.经常用来解释Hadoop命令行选项,并根据需要.至Configuration采取相应的对象设 ...
- 使用ToolRunner运行Hadoop程序基本原理分析 分类: A1_HADOOP 2014-08-22 11:03 3462人阅读 评论(1) 收藏
为了简化命令行方式运行作业,Hadoop自带了一些辅助类.GenericOptionsParser是一个类,用来解释常用的Hadoop命令行选项,并根据需要,为Configuration对象设置相应的 ...
- 解析GenericOptionsParser
hadoop源代码分析(4)-org.apache.hadoop.util包-GenericOptionsParser类[原创] 一 准备 hadoop版本:1.0.3,GenericOptio ...
- hadoop MapReduce 笔记
1. MapReduce程序开发步骤 编写map 和 reduce 程序–> 单元测试 -> 编写驱动程序进行验证-> 本地数据集调试 -> 部署到集群运行 用 ...
- Nutch源码阅读进程1---inject
最近在Ubuntu下配置好了nutch和solr的环境,也用nutch爬取了一些网页,通过solr界面呈现,也过了一把自己建立小搜索引擎的瘾,现在该静下心来好好看看nutch的源码了,先从Inject ...
- 《Hadoop权威》学习笔记五:MapReduce应用程序
一.API的配置---Configuration类 API的配置:Hadoop提供了专门的API对资源进行配置,Configuration类的实例(在org.apache.hadoop.conf包)包 ...
随机推荐
- PMBOK(第六版) PMP笔记——《十一》第十一章(项目风险管理)
PMBOK(第六版) PMP笔记——<十一>第十一章(项目风险管理) 第十一章 风险管理: 项目的独特性导致项目充满风险,项目风险是一种不确定的事件或条件,可能发生.将 要发生,也可能不发 ...
- macbook使用美化工具在屏幕展示出常查信息
磕叨 凭本人自己的经验,写代码过程中要经常查看内存使用网络流量下等,所以经常用到命令去查,而且mac上的命令跟linux上又有些不一样,经常打错. 多年前还没用mac前我用的是ubnutu,那时还是1 ...
- 04jmeter-Concurrency Thread Group
1.下载插件Custom Thread Groups:参照:00jmeter安装相关 2.添加并发线程组 场景举例: 10个线程2分钟的加速时间5个加速步骤持有目标速率2分钟: 即: 2分钟除以5步, ...
- HTTP协议详解(二)—— HTTP响应
HTTP响应(Response) 响应与请求一样分成三个部分:响应行.响应头.响应体. 1.响应行: 格式 - HTTP/1.1 200 OK 2.响应头: 部分头属性解释 - Location:这个 ...
- 百万年薪python之路 -- socket粘包问题解决
socket粘包问题解决 1. 高大上版解决粘包方式(自定制包头) 整体的流程解释 整个流程的大致解释: 我们可以把报头做成字典,字典里包含将要发送的真实数据的描述信息(大小啊之类的),然后json序 ...
- 轻量级CNN模型mobilenet v1
mobilenet v1 论文解读 论文地址:https://arxiv.org/abs/1704.04861 核心思想就是通过depthwise conv替代普通conv. 有关depthwise ...
- java面试官:兄弟简单谈谈Static、final、Static final各种用法吧
前言 对Static.final.Static final这几个关键词熟悉又陌生?想说却又不知怎么准确说出口?好的,本篇博客文章将简短概要出他们之间的各自的使用,希望各位要是被你的面试官问到了,也能从 ...
- LeetCode刷题笔记(1)常用知识点
1.Integer.parseInt(String s, int radix)方法的作用是:将radix进制的字符串s转化成10进制的int型数字并返回. Integer.valueof(String ...
- Java多线程编程(六)单例模式与多线程
在使用多线程技术的单例模式时会出现一些意想不到的情况,这样的代码如果在生产环境中出现异常,有可能造成灾难性的后果. 一.立即加载/“饿汉模式” 立即加载就是使用类的时候已经将对象创建完毕,常见的实现方 ...
- 小白初入Python人工智能
想要了解人工智能首先要知道“百度大脑”(https://ai.baidu.com/?track=cp:aipinzhuan|pf:pc|pp:AIpingtai|pu:title|ci:|kw:100 ...