最近几天一直在纠结hadoop作业提交的问题,对于命令行提交作业以及在集群中提交作业这里不再赘述,不会就去Google吧!
我们在客户机提交作业的时候总是发现出错,eclipse总是报jar file not found 的错误!我们知道客户端提交任务的时候,使用方法job.setWaitForCompletion(true)的时候,这个方法会调用job的submit()方法,submit()方法又会调用jobclient的submitJobInternal(conf)方法向master提交一个任务,这个方法会向hadoop文件系统提交三个文件job.jar,job.split,和job.xml那么它报那个错误就是因为job.jar文件没有提交上去,也就是说我们像在伪分布下那样提交任务的话我们的jar包并没有打好,所以就需要我们想办法将jar包提交上去,为此我们实践出的三种客户端提交作业的方法。
一、安装插件法
将hadoop中的contrib/eclipse-plugin中的eclipse插件拷贝到eclipse插件文件夹下然后重启eclipse就可以了,然后配置集群参数就可以实现。这里也不再赘述。
如果我们安装了插件的话那么就可以直接像在伪分布中运行的那样写如下类似代码,然后设置配置参数,最后提交运行。
public void runPageRank(String inputPath, String outputPath)
Throws IOException,InterruptedException, ClassNotFoundException {
Configuration conf = new Configuration();
conf.set("fs.default.name", "hdfs://master:9000");
conf.set("hadoop.job.user", "hadoop");
conf.set("mapred.job.tracker", "master:9001");
Job job = new Job(conf, "PageRank");
job.setJarByClass(PageRankV3.class);
job.setMapOutputValueClass(Text.class);
job.setMapperClass(PRMapper.class);
job.setReducerClass(cn.luliang.pageRank.PRReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);
FileInputFormat.addInputPath(job, new Path(inputPath));
FileOutputFormat.setOutputPath(job, new Path(outputPath));
job.waitForCompletion(true);
}
任务提交成功,很明显插件为我们打好了包,所以程序运行成功!
二、不安装插件法
在纠结很多次jar file not found 的错误之后我们根据eclipse中报的那个错误后面提示的那段jobClient.setJar(str),我们找到了一种解决方案,就是手动将我们的程序打成jar包,然后在代码中做如下改变:
public void runPageRank(String inputPath, String outputPath)
throws IOException, InterruptedException, ClassNotFoundException {
Configuration conf = new Configuration();
conf.set("fs.default.name", "hdfs://master:9000");
conf.set("hadoop.job.user", "hadoop");
conf.set("mapred.job.tracker", "master:9001");
Job job = new Job(conf, "PageRank");
((JobConf) job.getConfiguration()).setJar("pr.jar");
job.setJarByClass(PageRankV3.class);
job.setMapOutputValueClass(Text.class);
job.setMapperClass(PRMapper.class);
job.setReducerClass(cn.luliang.pageRank.PRReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);
FileInputFormat.addInputPath(job, new Path(inputPath));
FileOutputFormat.setOutputPath(job, new Path(outputPath));
job.waitForCompletion(true);
}
三、程序打包的方法
我们总觉得这个解决方案太过繁琐能不能找到一种更好的解决方案,不用手动打jar包!在查阅了大量资料之后我们终于找到了方法!
就是我们其实原来我们可以在程序中添加代码让程序为我们打jar包!这个世界真是太神奇啦!
看如下代码:
public static File createTempJar(String root) throws IOException {
if (!new File(root).exists()) {
return null;
}
//创建manifest文件
Manifest manifest = new Manifest();
//设置主属性
manifest.getMainAttributes().putValue("Manifest-Version", "1.0");
//创建临时文件
final File jarFile = File.createTempFile("EJar-", ".jar", new File(System
.getProperty("java.io.tmpdir")));
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
jarFile.delete();
}
});
//创建Jar文件输出流
JarOutputStream out = new JarOutputStream(new FileOutputStream(jarFile), manifest);
createTempJarInner(out, new File(root), "");
out.flush();
out.close();
return jarFile;
}
//遍历目录下文件
private static void createTempJarInner(JarOutputStream out, File f,
String base) throws IOException {
if (f.isDirectory()) {
File[] fl = f.listFiles();
if (base.length() > 0) {
base = base + "/";
}
for (int i = 0; i < fl.length; i++) {
createTempJarInner(out, fl[i], base + fl[i].getName());
}
} else {
out.putNextEntry(new JarEntry(base));
FileInputStream in = new FileInputStream(f);
byte[] buffer = new byte[1024];
int n = in.read(buffer);
while (n != -1) {
out.write(buffer, 0, n);
n = in.read(buffer);
}
in.close();
}
}
这里我们通过递归遍历目录的方法将一个目录下所有的文件进行打包。然后我们提供java打包路径就可以得到File对象!
最后在在主程序里添加代码:
File jarFile = EJar.createTempJar("bin");
EJar.addClasspath("/usr/lib/hadoop-0.20/conf");
ClassLoader classLoader = EJar.getClassLoader();
Thread.currentThread().setContextClassLoader(classLoader);
介绍一下addClasspath方法:
public static void addClasspath(String component) {
if ((component != null) && (component.length() > 0)) {
try {
File f = new File(component);
if (f.exists()) {
URL key = f.getCanonicalFile().toURL();
if (!classPath.contains(key)) {
classPath.add(key);
}
}
} catch (IOException e) {}
}
}
在这里我们创建一个class路径,以上方法可以参考一下java的源码;
然后设置jar文件
((JobConf) job.getConfiguration()).setJar(jarFile.toString());这样就可以实现打包了,提交任务我们发现没有报jar File not found的错误了,并且提交任务成功!
<!--EndFragment-->
分享到:
相关推荐
本篇文章将详细阐述如何利用Eclipse有效地调试Hadoop作业,以及与之相关的源码分析和工具使用技巧。 首先,调试Hadoop作业的准备工作至关重要。你需要确保已经安装并配置好Eclipse,同时在本地或远程服务器上安装了...
标题《Hive及Hadoop作业调优》与描述《阿里巴巴内部hive优化经验文档》指明了本文档的核心内容,它涉及到了在大数据处理领域内,如何针对Hive以及Hadoop作业进行优化的详细方法和经验分享。标签“hive”, “hadoop”...
【Hadoop 作业提交流程详解】 在Hadoop生态系统中,提交一个MapReduce作业通常通过执行类似`bin/hadoop jar xxx.jar mainclass args`的命令来完成。这个过程看似简单,实际上涉及到了多个步骤和组件的交互。下面...
这种调度器按照作业提交的时间顺序来执行作业,简单易用,但在处理不同类型和优先级的作业时可能会导致资源浪费和不公平的问题。 随着Hadoop的应用场景越来越复杂,社区开发了更加复杂的调度算法来满足多样化的需求...
三、Hadoop作业 作业通常涉及解决特定的问题或实现特定的功能,可能涵盖以下内容: 1. 数据分析:使用Hadoop处理大规模数据,进行数据清洗、统计分析或挖掘。 2. 实时流处理:可能涉及到使用Hadoop的实时处理框架...
这些日志可以帮助我们追踪作业的状态,如作业提交、任务分配、任务执行进度等。对于故障排查,日志尤为重要,因为它们通常包含错误原因和堆栈跟踪。 2. **日志聚合**:为了便于管理和分析,Hadoop提供了日志聚合...
在Windows 7环境下提交Hadoop作业(Job)是一项技术性的任务,涉及到多个步骤和概念。首先,我们需要了解Hadoop的基本架构。Hadoop是由Apache软件基金会开发的一个开源分布式计算框架,它允许在廉价硬件上处理和存储...
hadoop作业调度的原理和使用流程 hdfs的原理 mapreduce编程
"Hadoop 使用常见问题以及解决方法" Hadoop 作为一个大数据处理的开源框架,广泛应用于数据存储、处理和分析等领域。但是在使用 Hadoop 时,经常会遇到一些常见的问题,本文将对这些问题进行总结和解决。 Shuffle ...
hadoop常见问题及解决方法 Hadoop是大数据处理的重要工具,但是在安装和使用Hadoop时,可能会出现一些常见的问题,这些问题可能会导致Hadoop无法正常工作,或者无法达到预期的性能。下面是Hadoop常见的问题及解决...
Hadoop常见问题及解决办法汇总 Hadoop是一个基于Apache的开源大数据处理框架,广泛应用于大数据处理、数据分析和机器学习等领域。然而,在使用Hadoop时,经常会遇到一些常见的问题,这些问题可能会导致Hadoop集群...
"Hadoop作业" Hadoop 是一个由 Apache 基金会所开发的分布式系统基础架构。用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力进行高速运算和存储。Hadoop 实现了一个分布式文件系统,...
6. **JobSubmitter**:`LinuxS.java`可能是一个JobSubmitter类,负责将Mapper和Reducer组合成一个完整的Hadoop作业,并提交到集群进行执行。JobSubmitter会设置作业参数,如输入输出路径、分区函数、排序规则等,...
国科大Hadoop作业.pdf
hadoop使用distcp问题解决 然后用distcp从1.0.3的集群拷数据到2.0.1的集群中。 遇到问题处理
### Hadoop作业调度知识点 #### 一、Hadoop概述及应用背景 Hadoop是一个由Apache基金会维护的开源软件框架,用于分布式存储和处理大规模数据集。Hadoop的设计灵感源自Google的MapReduce和Google File System (GFS)...