4

我一直在使用 Amazon Elastic MapReduce 和 Hive 开发数据处理应用程序。现在我的 Hive 脚本在我 SSH 并使用交互模式作业流运行它们时工作,我正在尝试使用 AWS Java API 创建一个作业流。

使用http://docs.amazonwebservices.com/ElasticMapReduce/latest/DeveloperGuide/calling-emr-with-java-sdk.html作为我的起点,我创建了一个这样的步骤配置

StepConfig runScript = new StepConfig().withName("Prepare Admin")
.withActionOnFailure("TERMINATE_JOB_FLOW")
.withHadoopJarStep(oStepFactory.newRunHiveScriptStep(scriptPath, args));

我假设/希望 scriptPath 可以是我的 Hive 脚本的 s3 url,例如:s3://bucketName/hive-script。我发现的唯一文档讨论了使用主节点文件系统中的脚本。但是,如果主节点是为此作业流程而启动的实例,我不明白如何将任何脚本(Hive 或其他)放到文件系统上。

当我尝试我的想法时(将 s3 位置传递给 stepFactory 方法),runScript 步骤失败。

我已经通过 AWS 控制台检查了日志。标准输出日志以

2012-11-19 19:28:33 GMT - 错误执行 cmd 错误:/home/hadoop/.versions/hive-0.7.1/bin/hive '-f' 's3://anet-emr/scripts/admin .q''-d rawDataLocation=s3://anet-emr/raw -d year=2010 -d cycle=1'

stderr 日志以

java.lang.NoSuchMethodError: org.apache.commons.cli.CommandLine.getOptionProperties(Ljava/lang/String;)Ljava/util/Properties; 在 org.apache.hadoop.hive.cli.OptionsProcessor.process_stage1(OptionsProcessor.java:115) 在 org.apache.hadoop.hive.cli.CliDriver.main(CliDriver.java:399) 在 sun.reflect.NativeMethodAccessorImpl.invoke0 (本机方法)在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 在 java.lang.reflect.Method.invoke(Method.java:597 ) 在 org.apache.hadoop.util.ToolRunner 的 org.apache.hadoop.mapred.JobShell.run(JobShell.java:54) 的 org.apache.hadoop.util.RunJar.main(RunJar.java:155)。在 org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:79) 在 org.apache 运行(ToolRunner.java:65)。

控制器日志有

2012-11-19T19:28:27.406Z 信息执行 /usr/lib/jvm/java-6-sun/bin/java -cp /home/hadoop/conf:/usr/lib/jvm/java-6-sun/ lib/tools.jar:/home/hadoop:/home/hadoop/hadoop-0.18-core.jar:/home/hadoop/hadoop-0.18-tools.jar:/home/hadoop/lib/ :/home/hadoop/ lib/jetty-ext/-Xmx1000m -Dhadoop.log.dir=/mnt/var/log/hadoop/steps/3 -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/3/tmp -Djava.library.path=/home/hadoop/lib/native/Linux-i386-32 org.apache.hadoop.mapred.JobShell /mnt/var/lib/hadoop/steps/3/script-runner.jar s3://us-east-1.elasticmapreduce/libs/hive/hive-script --base-路径 s3://us-east-1.elasticmapreduce/libs/hive/ --hive-versions latest --run-hive-script --args -f s3://anet-emr/scripts/admin.q -d rawDataLocation=s3://anet-emr/raw -d year=2010 -d cycle=1 2012-11-19T19:28:34.143Z INFO 执行以 ret val 255 结束 2012-11-19T19:28:34.143Z WARN 步骤因错误的 retval 而失败

问题似乎在于我通过 Amazon 的 API 传递给 Hive 对 Apache CLI 库的调用的参数...我尝试使用“-d arg1=val1 -d arg2=val2”传递单个字符串,我我尝试过“-d,arg1=val1 等..”,并且尝试过各种分割成字符串数组的方法 - 即 {“-d”、“arg1=val1”...}。找不到任何有关执行此操作的正确方法的文档!

任何帮助表示赞赏,谢谢科尔曼

4

1 回答 1

1

嗨,这段代码对我有用:

String accessKey = "";
String secretKey = "";
 AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
   AmazonElasticMapReduceClient emr = new AmazonElasticMapReduceClient(credentials);

   StepFactory stepFactory = new StepFactory();

   StepConfig enabledebugging = new StepConfig()
       .withName("Enable debugging")
       .withActionOnFailure("TERMINATE_JOB_FLOW")
       .withHadoopJarStep(stepFactory.newEnableDebuggingStep());

   StepConfig installHive = new StepConfig()
       .withName("Install Hive")
       .withActionOnFailure("TERMINATE_JOB_FLOW")
       .withHadoopJarStep(stepFactory.newInstallHiveStep());

   StepConfig runScript = new StepConfig()
        .withName("Run Script")
        .withActionOnFailure("TERMINATE_JOB_FLOW")
        .withHadoopJarStep(stepFactory.newRunHiveScriptStep("s3://dummy/dummy.hive"));


   RunJobFlowRequest request = new RunJobFlowRequest()
       .withName("Hive Interactive")
       .withSteps(enabledebugging, installHive, runScript)
       .withLogUri("s3://dummy/")
       .withInstances(new JobFlowInstancesConfig()
           .withHadoopVersion("0.20.205")
           .withInstanceCount(1)
           .withKeepJobFlowAliveWhenNoSteps(false)
           .withMasterInstanceType("m1.small")
           .withSlaveInstanceType("m1.small"));

   RunJobFlowResult result = emr.runJobFlow(request);

希望这可以帮助 :)

于 2013-05-14T15:39:40.183 回答