Amazon EMR - 如何设置步骤的超时

时间:2017-04-21 10:41:56

标签: apache-spark yarn emr amazon-emr

有没有办法为Amazon Aws EMR 中的步骤设置超时

我正在EMR上运行批处理Apache Spark作业,如果它在3小时内没有结束,我希望该作业能够暂停。

我找不到在Spark中设置超时的方法,在电子邮件配置中的纱线

感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

好吧,正如许多人已经回答的那样,此时无法通过API调用杀死/停止/终止EMR步骤。

但是为了实现目标,您可以将超时作为应用程序代码本身的一部分。当您提交EMR步骤时,会创建一个子进程来运行您的应用程序 - 无论是MapReduce应用程序,Spark应用程序等,并且步骤完成由此子进程(这是您的应用程序)返回的退出代码确定。

例如,如果您要提交MapReduce应用程序,则可以使用以下内容:

FileInputFormat.addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));

final Runnable stuffToDo = new Thread() {
  @Override 
  public void run() { 
    job.submit();
  }
};

final ExecutorService executor = Executors.newSingleThreadExecutor();
final Future future = executor.submit(stuffToDo);
executor.shutdown(); // This does not cancel the already-scheduled task.

try { 
  future.get(180, TimeUnit.MINUTES); 
}
catch (InterruptedException ie) { 
  /* Handle the interruption. Or ignore it. */ 
}
catch (ExecutionException ee) { 
  /* Handle the error. Or ignore it. */ 
}
catch (TimeoutException te) { 
  /* Handle the timeout. Or ignore it. */ 
}
System.exit(job.waitForCompletion(true) ? 0 : 1);

参考 - Java: set timeout on a certain block of code?

希望这有帮助。

答案 1 :(得分:0)

我想提供一种替代方法,没有任何超时/关闭逻辑,使应用程序本身比所需的更加复杂-尽管我显然晚了。也许将来对某人有用。

您可以:

  • 编写Python脚本并将其用作常规Yarn命令的包装器
  • 通过子进程lib执行这些Yarn命令
  • 根据您的意愿解析其输出
  • 确定应终止哪些纱线应用

有关我正在谈论的内容的更多详细信息……

Python包装器脚本并通过子进程lib运行Yarn命令

import subprocess

running_apps = subprocess.check_output(['yarn', 'application', '--list', '--appStates', 'RUNNING'], universal_newlines=True)

此代码段将为您提供类似于以下内容的输出:

Total number of applications (application-types: [] and states: [RUNNING]):1
                Application-Id      Application-Name                                Application-Type          User       Queue               State         Final-State         Progress                        Tracking-URL
application_1554703852869_0066      HIVE-645b9a64-cb51-471b-9a98-85649ee4b86f       TEZ                       hadoop     default             RUNNING       UNDEFINED           0%                              http://ip-xx-xxx-xxx-xx.eu-west-1.compute.internal:45941/ui/

然后您可以解析此输出(请注意可能正在运行多个应用程序)并提取应用程序ID值。

然后,对于每个应用程序ID,您可以调用另一个yarn命令来获取有关特定应用程序的更多详细信息:

app_status_string = subprocess.check_output(['yarn', 'application', '--status', app_id], universal_newlines=True)

此命令的输出应如下所示:

Application Report :
  Application-Id : application_1554703852869_0070
  Application-Name : com.organization.YourApp
  Application-Type : HIVE
  User : hadoop
  Queue : default
  Application Priority : 0
  Start-Time : 1554718311926
  Finish-Time : 0
  Progress : 10%
  State : RUNNING
  Final-State : UNDEFINED
  Tracking-URL : http://ip-xx-xxx-xxx-xx.eu-west-1.compute.internal:40817
  RPC Port : 36203
  AM Host : ip-xx-xxx-xxx-xx.eu-west-1.compute.internal
  Aggregate Resource Allocation : 51134436 MB-seconds, 9284 vcore-seconds
  Aggregate Resource Preempted : 0 MB-seconds, 0 vcore-seconds
  Log Aggregation Status : NOT_START
  Diagnostics :
  Unmanaged Application : false
  Application Node Label Expression : <Not set>
  AM container Node Label Expression : CORE

有了这个,您还可以提取应用程序的开始时间,将其与当前时间进行比较,并查看其运行了多长时间。 例如,如果运行时间超过某个阈值分钟数,则将其杀死。

您如何杀死它? 容易。

kill_output = subprocess.check_output(['yarn', 'application', '--kill', app_id], universal_newlines=True)

从杀死步骤/应用程序的角度来看,应该就是这样。

自动化方法

AWS EMR具有一个很棒的功能,称为“引导动作”。 它会在创建EMR群集时执行一系列操作,可用于自动执行此方法。

将bash脚本添加到引导操作,该操作将执行以下操作:

  • 下载您刚刚写入集群(主节点)的python脚本
  • 将python脚本添加到crontab

应该的。

P.S。 我以为我们可以使用Python3。