Spark 驱动程序进程未在 Kubernetes 上终止

问题描述 投票:0回答:1

问题:在 main 方法完成执行且 Spark 上下文停止后,Kubernetes 上的 Spark 驱动程序进程不会终止。我正在尝试将当前在纱线上的 Spark 作业迁移到 Kubernetes。

JVM 进程的终止由 JVM 关闭序列启动,该序列通过以下两种方式之一触发:

  • 所有非守护线程完成执行。
  • System.exit 方法被显式调用。

为了识别导致问题的潜在线程,我打印了在 main 方法末尾运行的非守护线程列表。

Kubernetes 上的发现:main 方法末尾处 Kubernetes Spark 驱动程序上运行的非守护线程列表包括:

  • 主要
  • OkHttp kubernetes.default.svc(由 K8s 运行,停止 Spark 上下文后终止)
  • OkHttp kubernetes.default.svc Writer(由 K8s 运行,停止 Spark 上下文后终止)
  • 几个用户线程

YARN 上的发现:YARN Spark 驱动程序中 main 方法末尾运行的非守护线程列表包括:

  • 主要
  • 驱动程序(这是应用程序主线程)
  • 多个用户线程(与 K8s 相同)。

有趣的是,尽管这两种环境中都存在这些用户线程,YARN JVM 都会终止,而 Kubernetes 则不会。

在 YARN 上:当我们在 YARN 上以集群模式运行 Spark 时,Spark 使用 ApplicationMaster 类的实例启动驱动程序 JVM。然后,ApplicationMaster 在单独的线程中调用您的 Main 类(随后可能会创建其他线程)。但是,ApplicationMaster 仅等待主线程完成。这可以在 ApplicationMaster 类的以下代码片段中看到:

https://github.com/apache/spark/blob/8212d6f87c658ade3a87a12dbbb10e9c212fe4e7/resource-managers/yarn/src/main/scala/org/apache/spark/deploy/yarn/ApplicationMaster.scala#L934

ugi.doAs(new PrivilegedExceptionAction[Unit]() { override def run(): Unit = System.exit(master.run()) })

这里,master.run() 调用主类并等待它完成,然后调用 System.exit,这会触发 JVM 关闭序列。

我找不到 Kubernetes 上发生的任何类似情况。

我想知道这是否是 YARN 上的预期行为? 我们应该在用户主类中执行 system.exit() 还是优雅地关闭所有用户线程?

apache-spark kubernetes hadoop-yarn
1个回答
0
投票

哪里可以解决?有类似问题/

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