这是一个Hadoop中极为常见的丢包少类的问题,希望能帮到大家
问题描述
命令:hadoop jar 运行包 主函数 参数-1 参数-2
运行产生异常
异常一:
Exit code: 1 Stack trace: ExitCodeException exitCode=1: at org.apache.hadoop.util.Shell.runCommand(Shell.java:604) at org.apache.hadoop.util.Shell.run(Shell.java:507)
异常二:
org.apache.hadoop.yarn.exceptions.YarnRuntimeException: java.lang.RuntimeException: java.lang.ClassNotFoundException: Class org.apache.orc.mapreduce.OrcOutputFormat not found
解决思路
MR程序运行少包有二种: 1.程序运行当前环境少包 2.Yarn运行环境Executor少包
如果刚运行命令,还任务甚至还未提交Yarn产生了异常,可以理解为当前环境少包
通过导入环境变量即可运行:
注意多个Jar包使用 : 隔开
export HADOOP_CLASSPATH=${HADOOP_CLASSPATH}:lib/orc-mapreduce-1.1.0.jar
如果程序已经提交Yarn了,注意观察资源管理界面,查看运行日志
方法一:
hadoop jar 运行包 主函数-libjars lib/*.jar
参数-1 参数-2
可将依赖包提交Executor运行环境,注意位置不可变,多个lib使用,隔开
但是需要使用Tools工具类运行任务,否则无法识别参数-libjars, 会被识别为Main的参数,具体请看后面补充
方法二
程序中使用分布式缓存,缓存Jar文件,具体看补充
补充 : 方法一
//通过实现工具类,Run方法执行Job,-libjars才可被识别
public class MapredOrcFileConvert extends Configured implements Tool {
static Logger logger = LoggerFactory.getLogger("MapredOrcFileConvert");
@Override
public int run(String[] strings) throws Exception {
// 重要: 必须要用:父类方法getConf() .
Configuration conf = getConf();
Job job = Job.getInstance(conf, "NAME");
/*JAR*/
job.setJarByClass(MapredOrcFileConvert.class);
/*Format*/
...
/*Map*/
...
/*Reduce*/
...
/*Param*/
...
FileInputFormat.addInputPath(job, new Path(strings[1]));
FileOutputFormat.setOutputPath(job, new Path(strings[2]));
return job.waitForCompletion(true) ? 0 : 1;
}
public static void main(String args[]) throws Exception {
//工具类运行
int status = ToolRunner.run(new Configuration(), new MapredOrcFileConvert(), args);
System.exit(status);
}
补充 : 方法二
//分布式缓存,依赖包需要上传HDFS,指定文件路径,导入缓存,即可解决依赖
Configuration conf = new Configuration();
FileSystem fileSystem = FileSystem.get(conf);
FileStatus[] status = fileSystem.listStatus("HDFS JAR Lib PATH");
for (FileStatus statu : status) {
System.out.println("+" + statu.getPath().toString());
DistributedCache.addArchiveToClassPath(statu.getPath(), conf);
}