在亚马逊弹性mapreduce中启动mapreduce工作

时间:2013-12-05 06:37:35

标签: elastic-map-reduce

我正在尝试在亚马逊地图减少群集中启动地图减少作业。我的地图reduce job在生成map / reduce任务之前会做一些预处理。此预处理需要第三方库,例如javacv,opencv。按照亚马逊的文档,我将这些库包含在HADOOP_CLASSPATH中,这样我在主节点的/ home / hadoop / conf /位置的hadoop-user-env.sh中有一行HADOOP_CLASSPATH =。根据文档,此脚本中的条目应包含在hadoop-env.sh中。因此,我假设HADOOP_CLASSPATH现在在类路径中有我的libs。我在引导操作中这样做了。但是,当我启动作业时,它仍然会抱怨类找不到异常,指向jar中应该在类路径中的类。 谁能告诉我哪里出错了? bbtw,我正在使用hadoop 2.2.0。在我的本地基础架构中,我有一个小的bash脚本,它导出HADOOP_CLASSPATH及其中包含的所有库,并调用hadoop jar -libjars。

2 个答案:

答案 0 :(得分:1)

我通过AWS EMR引导任务解决了这个问题,将jar添加到hadoop类路径中:

  1. 将我的jar上传到S3
  2. 创建了一个引导脚本,将jar从S3复制到EMR实例,并将jar添加到类路径中:

    #!/bin/bash
    hadoop fs -copyToLocal s3://my-bucket/libthrift-0.9.2.jar /home/hadoop/lib/
    echo 'export HADOOP_CLASSPATH="$HADOOP_CLASSPATH:/home/hadoop/lib/libthrift-0.9.2.jar"' >> /home/hadoop/conf/hadoop-user-env.sh
    
  3. 将该脚本保存为" add-jar-to-hadoop-classpath.sh"并将其上传到S3。

  4. 我的" aws emr create-cluster" command使用以下参数添加bootstrap脚本: - bootstrap-actions Path = s3://my-bucket/add-jar-to-hadoop-classpath.sh
  5. 当EMR旋转时,实例将创建文件/home/hadoop/conf/hadoop-user-env.sh,并且我的MR作业能够在jar中实例化thrift类。

    UPDATE :我能够从MASTER节点实例化thrift类,但不能从CORE节点实例化。我进入了CORE节点并将lib正确复制到/ home / hadoop / lib并且我的HADOOP_CLASSPATH设置就在那里,但是当映射器试图使用thrift时,我仍然在运行时找不到类。

    解决方案最终成为maven-shade-plugin并嵌入了节俭jar:

            <plugin>
                <!-- Use the maven shade plugin to embed the thrift classes in our jar.
                  Couldn't get the HADOOP_CLASSPATH on AWS EMR to load these classes even
                  with the jar copied to /home/hadoop/lib and the proper env var in
                  /home/hadoop/conf/hadoop-user-env.sh -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>2.3</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <artifactSet>
                                <includes>
                                    <include>org.apache.thrift:libthrift</include>
                                </includes>
                            </artifactSet>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
    

答案 1 :(得分:0)

执行作业时,“controller”日志文件包含实际执行的命令行。这看起来像是:

2014-06-02T15:37:47.863Z INFO Fetching jar file.
2014-06-02T15:37:54.943Z INFO Working dir /mnt/var/lib/hadoop/steps/13
2014-06-02T15:37:54.944Z INFO Executing /usr/java/latest/bin/java -cp /home/hadoop/conf:/usr/java/latest/lib/tools.jar:/home/hadoop:/home/hadoop/hadoop-tools.jar:/home/hadoop/hadoop-tools-1.0.3.jar:/home/hadoop/hadoop-core-1.0.3.jar:/home/hadoop/hadoop-core.jar:/home/hadoop/lib/*:/home/hadoop/lib/jetty-ext/* -Xmx1000m -Dhadoop.log.dir=/mnt/var/log/hadoop/steps/13 -Dhadoop.log.file=syslog -Dhadoop.home.dir=/home/hadoop -Dhadoop.id.str=hadoop -Dhadoop.root.logger=INFO,DRFA -Djava.io.tmpdir=/mnt/var/lib/hadoop/steps/13/tmp -Djava.library.path=/home/hadoop/native/Linux-amd64-64 org.apache.hadoop.util.RunJar <YOUR_JAR> <YOUR_ARGS>

日志位于/ mnt / var / lib / hadoop / steps /中的主节点上 - 当您进入主节点时,它很容易访问(需要在创建集群时指定密钥对)。

我从来没有真正使用过HADOOP_CLASSPATH中的内容,但是如果你定义一个引导操作来将你的库复制到/ home / hadoop / lib中,那么应该解决这个问题。