如何在Hadoop YARN容器退出时运行自定义代码 适配Spark等多场景
YARN容器终止信号检测与自定义逻辑注入方案
通用YARN作业适配方案(支持MR、Hive on Tez等所有基于YARN运行的服务)
- 方案一:NodeManager全局钩子封装(无业务侵入)
利用YARN NodeManager的容器启动前置钩子能力,将所有容器进程用自定义信号监听脚本封装一层,统一处理SIGTERM信号。
操作步骤:
- 修改所有NodeManager节点的
yarn-site.xml配置,添加如下参数:
<property> <name>yarn.nodemanager.container-executor.class</name> <value>org.apache.hadoop.yarn.server.nodemanager.LinuxContainerExecutor</value> </property> <property> <name>yarn.nodemanager.linux-container-executor.launch-command-prefix</name> <value>/opt/yarn/scripts/sigterm-handler-wrapper.sh</value> </property>
- 编写信号监听脚本
sigterm-handler-wrapper.sh,示例如下:
#!/bin/bash # 自定义终止逻辑 run_custom_cleanup() { echo "容器捕获到SIGTERM信号,执行自定义清理逻辑" >&2 # 此处替换为你的业务逻辑,比如日志归档、状态上报、临时资源清理等 /opt/yarn/scripts/custom-cleanup.sh # 转发信号给实际业务进程 kill -TERM $business_pid wait $business_pid exit $? } # 注册SIGTERM信号监听 trap run_custom_cleanup SIGTERM # 启动YARN下发的实际业务进程 "$@" & business_pid=$! wait $business_pid
- 给脚本添加可执行权限,同步到所有NodeManager节点的对应路径,重启NodeManager服务生效。该方案不需要修改任何业务代码,所有YARN上运行的作业都会自动生效。
- 方案二:业务代码层面注册JVM关闭钩子
所有基于JVM运行的YARN作业(MR、Tez、Spark等)都可以通过Runtime.getRuntime().addShutdownHook()方法注册关闭钩子,JVM收到SIGTERM信号准备退出时会自动执行钩子中定义的逻辑。注意需要调整YARN参数yarn.nodemanager.sleep-delay-before-sigkill.ms(默认250ms),给钩子留足够的执行时间,否则进程会被NodeManager提前用SIGKILL强制终止,导致逻辑执行不完整。
Spark on YARN针对性方案
针对Spark作业可以使用作业级别的配置,无需修改集群全局配置:
- 方案一:代码层面注册Spark关闭钩子
使用Spark内置的ShutdownHookManager注册自定义逻辑,可以自定义优先级确保逻辑在Spark默认清理动作之前执行,示例Scala代码:import org.apache.spark.util.ShutdownHookManager // 优先级数值越小执行顺序越靠前,Spark默认清理钩子优先级为100 ShutdownHookManager.addShutdownHook(50) { () => // 自定义终止逻辑,比如中间结果持久化、作业状态上报等 println("Spark executor即将终止,执行自定义清理") } - 方案二:作业启动参数注入逻辑,无代码侵入
提交Spark作业时通过环境变量参数注入Java Agent或者信号处理逻辑,示例提交参数:
如果不需要Agent,也可以直接通过spark-submit \ --conf spark.executorEnv.JAVA_TOOL_OPTIONS="-javaagent:/path/to/your/sigterm-handler-agent.jar" \ --conf spark.driverEnv.JAVA_TOOL_OPTIONS="-javaagent:/path/to/your/sigterm-handler-agent.jar" \ # 其他作业参数spark.executor.extraJavaOptions参数注入JVM关闭钩子的注册逻辑。 - 额外适配:如果开启了Spark动态资源分配,还可以监听Spark的
ExecutorLost事件做兜底逻辑,覆盖Executor空闲被回收的场景。
注意事项
- 自定义终止逻辑的执行时长不能超过YARN配置的终止等待时间,建议控制在数秒以内,只执行必要的轻量操作。
- SIGKILL信号无法被捕获,只有SIGTERM信号可以触发自定义逻辑,因此务必根据业务逻辑执行时长调整
yarn.nodemanager.sigkill-delay-ms参数,避免容器被强制杀死。
内容的提问来源于stack exchange,提问作者FRG96
相关产品推荐
相关产品推荐

