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

问题描述 投票:8回答:2

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

我正在EMR上运行一个批量Apache Spark作业,如果它在3小时内没有结束,我希望该作业停止超时。

我找不到一种方法来设置超时,不是在Spark中,也不是在Yarn中,也不是在EMR配置中。

谢谢你的帮助!

apache-spark yarn emr amazon-emr
2个回答
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?

希望这可以帮助。


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/

您可以解析此输出(注意可能有多个应用程序正在运行)并提取application-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

那应该是它。

附:我认为Python3可以用于此目的。

© www.soinside.com 2019 - 2024. All rights reserved.