有没有办法为Amazon Aws EMR中的步骤设置超时?
我正在EMR上运行一个批量Apache Spark作业,如果它在3小时内没有结束,我希望该作业停止超时。
我找不到一种方法来设置超时,不是在Spark中,也不是在Yarn中,也不是在EMR配置中。
谢谢你的帮助!
好吧,正如许多人已经回答的那样,此时不能通过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?。
希望这可以帮助。
我想提供一种替代方法,没有任何超时/关闭逻辑,使应用程序本身比需要更复杂 - 尽管我显然已经很晚了。也许这证明对未来的人有用。
您可以:
关于我正在谈论的内容的更多细节如下......
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脚本来引导将要执行的操作:
那应该是它。
附:我认为Python3可以用于此目的。