我在本地环境中使用 Airflow,在使用以下代码块创建集群后在 EMR 中添加一个步骤。
def add_step(cluster_id,jar_file,step_args):
print("The cluster id : {}".format(cluster_id))
print("The step to be added : {}".format(step_args))
response=client.add_job_flow_steps(
JobFlowId=cluster_id,
Steps=[
{
'Name':'Test',
'ActionOnFailure':'CONTINUE',
'HadoopJarStep':{
'Jar':jar_file,
'Args':step_args
}
},
]
)
print('EMR Step is added')
return response['StepIds'][0]
dag=DAG(
dag_id="EMR_START_DAG",
description="Trial for EMR start",
start_date=days_ago(1)
)
EMR_STEP_1=PythonOperator(
task_id='EMR_STEP_1',
python_callable=add_step,
op_kwargs={'cluster_id':'{{ti.xcom_pull("EMR_START")["JobFlowId"]}}',
'jar_file':'command-runner.jar',
'step_args':['s3://shell script path']},
dag=dag
)
该步骤已成功添加到 EMR,但失败并出现以下错误。
Exception in thread "main" java.lang.RuntimeException: java.io.IOException: Cannot run program "s3://shell script path" (in directory "."): error=2, No such file or directory
at com.amazonaws.emr.command.runner.ProcessRunner.exec(ProcessRunner.java:140)
at com.amazonaws.emr.command.runner.CommandRunner.main(CommandRunner.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.hadoop.util.RunJar.run(RunJar.java:244)
at org.apache.hadoop.util.RunJar.main(RunJar.java:158)
Caused by: java.io.IOException: Cannot run program "s3://shell script path" (in directory "."): error=2, No such file or directory
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
at com.amazonaws.emr.command.runner.ProcessRunner.exec(ProcessRunner.java:93)
... 7 more
Caused by: java.io.IOException: error=2, No such file or directory
at java.lang.UNIXProcess.forkAndExec(Native Method)
at java.lang.UNIXProcess.<init>(UNIXProcess.java:247)
at java.lang.ProcessImpl.start(ProcessImpl.java:134)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
... 8 more
文件存在于该路径中。 EMR 实例配置文件和服务角色对 S3 具有完全访问权限。我不确定出了什么问题。
Shell脚本有以下代码
wget -O - https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data | aws s3 cp - s3path
当您运行 shell 脚本时,请使用 script-runner.jar 而不是 command-runner.jar。
请参阅页面在 Amazon EMR 集群上运行命令和脚本了解更多信息。
示例:使用 script-runner.jar 在集群上运行脚本
使用 script-runner.jar 时,您可以在步骤的参数列表中指定要运行的脚本。
以下 AWS CLI 示例向正在运行的集群提交一个调用 script-runner.jar 的步骤。在本例中,名为 my-script.sh 的脚本存储在 Amazon S3 上。您还可以指定存储在集群主节点上的本地脚本。
aws emr add-steps \ --cluster-id j-2AXXXXXXGAPLF \ --steps Type=CUSTOM_JAR,Name="Run a script from S3 with script->runner.jar",ActionOnFailure=CONTINUE,Jar=s3://us-west->2.elasticmapreduce/libs/script-runner/script-runner.jar,Args=[s3://EXAMPLE-DOC-BUCKET/my-script.sh]