【问题标题】:Specifying additional jars in AWS EMR custom jar application在 AWS EMR 自定义 jar 应用程序中指定其他 jar
【发布时间】:2017-07-30 17:56:11
【问题描述】:

我正在尝试在 EMR 集群上运行 hadoop 作业。它作为我使用jar-with-dependencies 的Java 命令运行。该作业从 Teradata 提取数据,我假设与 Teradata 相关的 jar 也包含在 jar-with-dependencies 中。但是,我仍然遇到异常:

Exception in thread "main" java.lang.RuntimeException: java.lang.RuntimeException: java.lang.ClassNotFoundException: com.teradata.jdbc.TeraDriver
at org.apache.hadoop.mapreduce.lib.db.DBInputFormat.setConf(DBInputFormat.java:171)

我的pom有以下相关依赖:

<dependency>
  <groupId>teradata</groupId>
  <artifactId>terajdbc4</artifactId>
  <version>14.10.00.17</version>
</dependency>

<dependency>
  <groupId>teradata</groupId>
  <artifactId>tdgssconfig</artifactId>
  <version>14.10.00.17</version>
</dependency>

我将完整的罐子包装如下:

  <build>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.1</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
          <compilerArgument>-Xlint:-deprecation</compilerArgument>
        </configuration>
      </plugin>

      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>2.2.1</version>

        <configuration>
          <descriptors>
          </descriptors>
          <archive>
            <manifest>
            </manifest>
          </archive>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
        </configuration>

        <executions>
          <execution>
            <id>make-assembly</id>
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
          </execution>
        </executions>
      </plugin>

    </plugins>
  </build>

assembly.xml文件:

<assembly>
    <id>aws-emr</id>
    <formats>
        <format>jar</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <dependencySets>
        <dependencySet>
            <unpack>false</unpack>
            <includes>
            </includes>
            <scope>runtime</scope>
            <outputDirectory>lib</outputDirectory>
        </dependencySet>
        <dependencySet>
            <unpack>true</unpack>
            <includes>
                <include>${groupId}:${artifactId}</include>
            </includes>
        </dependencySet>
    </dependencySets>
</assembly>

运行 EMR 命令为:

aws emr create-cluster --release-label emr-5.3.1 \
--instance-groups \
    InstanceGroupType=MASTER,InstanceCount=1,InstanceType=m3.xlarge \
    InstanceGroupType=CORE,InstanceCount=5,BidPrice=0.1,InstanceType=m3.xlarge \
--service-role EMR_DefaultRole --log-uri s3://my-bucket/logs \
--applications Name=Hadoop --name TeradataPullerTest \
--ec2-attributes <ec2-attributes> \

--steps Type=CUSTOM_JAR,Name=EventsPuller,Jar=s3://path-to-jar-with-dependencies.jar,\
Args=[com.my.package.EventsPullerMR],ActionOnFailure=TERMINATE_CLUSTER \
--auto-terminate

有没有一种方法可以指定 Teradata jar,以便在执行 map-reduce 作业时将它们添加到类路径中?

编辑:我验证了缺少的类被打包在 jar-with-dependencies 中。

aws-emr$ jar tf target/aws-emr-0.0.1-SNAPSHOT-jar-with-dependencies.jar | grep TeraDriver
com/ncr/teradata/TeraDriver.class
com/teradata/jdbc/TeraDriver.class

【问题讨论】:

    标签: java mapreduce teradata classnotfoundexception elastic-map-reduce


    【解决方案1】:

    我还没有完全解决这个问题,但找到了一种方法来解决这个问题。理想的解决方案应该将 teradata jar 包装在 uber jar 中。这种情况仍在发生,但这些罐子不知何故没有被添加到类路径中。我不知道为什么会这样。

    我通过创建 2 个单独的 jar 来解决这个问题 - 一个用于我的代码包,另一个用于所需的所有依赖项。我将这两个 jar 都上传到 S3,然后编写了一个执行以下操作的脚本(伪代码):

    # download main jar
    aws s3 cp <s3-path-to-myjar.jar> .
    
    # download dependency jar in a temp directory
    aws s3 cp <s3-path-to-dependency-jar> temp
    
    # unzip the dependencies jar into another directory (say `jars`)
    unzip -j temp/dependencies.jar <path-within-jar-to-unzip>/* -d jars
    
    LIBJARS=`find jars/*.jar | tr -s '\n' ','`
    
    HADOOP_CLASSPATH=`echo ${LIBJARS} | sed s/,/:/g`
    
    CLASSPATH=$HADOOP_CLASSPATH
    
    export CLASSPATH HADOOP_CLASSPATH
    
    # run via hadoop command
    hadoop jar myjar.jar com.my.package.EventsPullerMR -libjars ${LIBJARS} <arguments to the job>
    

    这就开始了工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-03-14
      • 1970-01-01
      • 2016-08-19
      • 1970-01-01
      • 2018-08-24
      • 2019-05-24
      • 1970-01-01
      相关资源
      最近更新 更多