You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spark Worker进程OOM后JVM挂起相关问题咨询

Spark Worker节点OOM与SIGTERM信号相关问题解答

问题背景

Spark Worker节点出现如下OOM异常:

Exception in thread "dispatcher-event-loop-14" java.lang.OutOfMemoryError: GC overhead limit exceeded
    at java.util.HashMap.newNode(HashMap.java:1747)
    at java.util.HashMap.putVal(HashMap.java:631)
    at java.util.HashMap.put(HashMap.java:612)
    at java.util.HashSet.add(HashSet.java:220)
    at java.io.ObjectStreamClass.getClassDataLayout0(ObjectStreamClass.java:1317)
    at java.io.ObjectStreamClass.getClassDataLayout(ObjectStreamClass.java:1295)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1480)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
    at org.apache.spark.serializer.JavaSerializationStream.writeObject(JavaSerializer.scala:43)
    at org.apache.spark.rpc.netty.RequestMessage.serialize(NettyRpcEnv.scala:557)
    at org.apache.spark.rpc.netty.NettyRpcEnv.send(NettyRpcEnv.scala:192)
    at org.apache.spark.rpc.netty.NettyRpcEndpointRef.send(NettyRpcEnv.scala:520)
    at org.apache.spark.deploy.worker.Worker.org$apache$spark$deploy$worker$Worker$$sendToMaster(Worker.scala:638)
    at org.apache.spark.deploy.worker.Worker$$anonfun$receive$1.applyOrElse(Worker.scala:524)
    at org.apache.spark.rpc.netty.Inbox$$anonfun$process$1.apply$mcV$sp(Inbox.scala:117)
    at org.apache.spark.rpc.netty.Inbox.safelyCall(Inbox.scala:205)
    at org.apache.spark.rpc.netty.Inbox.process(Inbox.scala:101)
    at org.apache.spark.rpc.netty.Dispatcher$MessageLoop.run(Dispatcher.scala:216)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Java HotSpot(TM) 64-Bit Server VM warning: Exception java.lang.OutOfMemoryError occurred dispatching signal SIGTERM to handler- the VM may need to be forcibly terminated.

异常发生前,Worker因Executor反复退出(退出码Code 1、exitStatus 1)而不断重启Executor。相关配置如下:

  • Worker进程-Xmx=1GB
  • 节点总内存=100GB
  • Java 8
  • Spark 2.2.1

异常发生时系统内存90%处于空闲状态,但Worker进程仍存活,却已与Master断开关联且停止处理任务。推测是反复提交Executor导致Worker进程OOM,此时有进程向Worker JVM发送了SIGTERM信号,JVM处理该信号时再次触发OOM。

问题解答

1. 哪个进程可能发送了SIGTERM信号?

最可能的发送方有两个:

  • Spark Master进程:当Worker因OOM导致心跳中断、无法响应Master的状态请求时,Master会判定Worker失联,主动发送SIGTERM信号尝试清理无效进程。
  • 系统OOM Killer:如果Worker所在的资源隔离组(如cgroup)内存配额耗尽,或系统出现临时内存波动,OOM Killer可能误判并发送信号。但结合节点90%内存空闲的情况,Spark Master发送信号的概率更高。

2. 系统内存充足的情况下,为何该进程会发送该信号?OOM时JVM难道不会自行退出吗?

  • 系统总内存充足,但Worker自身堆内存仅配置1GB,反复重启Executor会导致Worker内部积累大量状态数据(如启动请求、失败记录、RPC消息队列),触发GC overhead limit exceeded——这种OOM属于JVM软限制,默认不会直接终止进程,仅抛出异常,此时Worker已无法正常处理任务和心跳。
  • Master长时间收不到Worker心跳,会认定Worker故障,因此发送SIGTERM信号尝试终止进程、重新分配资源。

3. JVM处理SIGTERM信号时为何会出现OOM?

JVM收到SIGTERM后会触发优雅关闭流程:停止新任务、清理资源、关闭线程池,甚至可能需要序列化状态向Master发送最后报告。此时Worker堆内存已极度紧张,GC无法释放足够空间,而优雅关闭中的序列化操作(如栈日志中的ObjectOutputStream.writeObject)需要分配新内存,因此再次触发OOM。

4. 为何Worker进程仍处于运行状态?

  • GC overhead limit exceeded属于非致命OOM,JVM不会立刻终止进程,仅持续抛出异常,允许线程尝试继续执行。
  • 处理SIGTERM的线程触发OOM后,优雅关闭流程被中断,JVM的终止逻辑未执行完成,导致Worker卡在“半死不活”状态:无法处理任务和心跳,但进程本身未完全退出。

内容的提问来源于stack exchange,提问作者Calypso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 00:47:02