MR添加第三方依赖和文件

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/littlerobot/article/details/79962097

问题描述

    写MR程序往往需要依赖第三方依赖库,或者需要读取自己的配置文件,本文就的目的就是为了用靠谱的方法解决这两个问题!

解决方案

步骤

  1. 在 Driver 端添加依赖
export HADOOP_CLASSPATH="thirdpartlib_1.jar,thirdpartlib_2.jar ..."
  1. 在 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. 代码

    • 方法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/

常见问题

  1. 增加了 “export HADOOP_CLASSPATH” 环境变量, Driver 端仍然找不到类
原因a: 在 "hadoop jar application.jar ..." 后面用了 sudo,导致环境变量不能传递给子进程
解决:"sudo" 替换为 "sodu -E",使父进程的环境变量不被抹除
  1. 增加了 -libjars 操作, 但是 Task 端仍然找不到类
原因a: 没有使用 "步骤3" 的两种方法使 "-libjars" 生效
解决: 使用 "步骤3" 中的两种方法的任意一个
原因b: "-libjars" 放在了 "userparam1, userparam2 ..." 的后面
解决: 将 "-libjars""hadoop jar application.jar" 后面 并且在 "userparam1, userparam2 ..." 前面!
阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页