问题描述
写MR程序往往需要依赖第三方依赖库,或者需要读取自己的配置文件,本文就的目的就是为了用靠谱的方法解决这两个问题!
解决方案
步骤
- 在 Driver 端添加依赖
export HADOOP_CLASSPATH="thirdpartlib_1.jar,thirdpartlib_2.jar ..."
- 在 Task 端添加依赖(或配置文件)
hadoop jar application.jar \
-libjars "thirdpartlib_1.jar,thirdpartlib_2.jar ..." \
-files "file1, file2 ..." \
userparam1, userparam2 ...
注意1: 必须保证 “-libjars” 和 “-files” 在 “hadoop jar application.jar” 后面 并且在 “userparam1, userparam2 …” 前面!如果在 “userparam1, userparam2 …” 后面,则会被当做 userparam 处理
注意2: 此种方法会配置文件放到application.jar的同级目录
代码
方法1
Configuration conf = new Configuration(); String[] userparams = new GenericOptionsParser(conf, args).getRemainingArgs(); Job job = Job.getInstance(conf); //process business logic ... System.exit(job.waitForCompletion(true) ? 0 : 1)方法2
public class ApplicationDriver extends Configured implements Tool { //设定并读取应用程序相关的,自己定义的一些参数 public int run(String[] args) throws Exception { if(args.length < 2) { printUsage(); return 2; } Job job = new Job(getConf()); //process business logic ... return job.waitForCompletion(true) ? 0 : 1; } //真正的main函数 public static void main(String[] args) throws Exception{ int res = ToolRunner.run(new Configuration(), new ApplicationDriver(), args); System.exit(res); } }
注意:必须使用 “方法1” 或者 “方法2” 才能使 “1” 和 “2” 生效!
原理
-files:Hadoop 将指定的本地/hdfs上的文件通过HDFS分发到各个Task的工作目录下,不对文件进行任何处理
-libjars:Hadoop 将指定的本地/hdfs上的jar包通过HDFS分发到各个Task的工作目录下,并将其自动添加到任务的CLASSPATH环境变量中
原理是基于 Hadoop 的 DistributedCache,详解见如下链接: http://dongxicheng.org/mapreduce-nextgen/hadoop-distributedcache-details/
常见问题
- 增加了 “export HADOOP_CLASSPATH” 环境变量, Driver 端仍然找不到类
原因a: 在 "hadoop jar application.jar ..." 后面用了 sudo,导致环境变量不能传递给子进程
解决:"sudo" 替换为 "sodu -E",使父进程的环境变量不被抹除
- 增加了 -libjars 操作, 但是 Task 端仍然找不到类
原因a: 没有使用 "步骤3" 的两种方法使 "-libjars" 生效
解决: 使用 "步骤3" 中的两种方法的任意一个
原因b: "-libjars" 放在了 "userparam1, userparam2 ..." 的后面
解决: 将 "-libjars" 在 "hadoop jar application.jar" 后面 并且在 "userparam1, userparam2 ..." 前面!
本文介绍如何在Hadoop MapReduce程序中正确引入第三方依赖库及配置文件,确保Driver端和Task端均可正常使用。文中详细解释了使用-libjars和-files参数的步骤,并提供了代码示例。
7988

被折叠的 条评论
为什么被折叠?



