Scala spark停止时如何清理其他资源
在我的spark应用程序中,有一个Scala spark停止时如何清理其他资源,scala,apache-spark,akka,Scala,Apache Spark,Akka,在我的spark应用程序中,有一个对象ResourceFactory,其中包含一个akkaActorSystem,用于提供资源客户端。因此,当我运行这个spark应用程序时,每个工作节点都将创建一个ActorSystem。问题是,当spark应用程序完成其工作并关闭时。ActorSystem在每个工作节点上仍然保持活动状态,并防止整个应用程序终止,它只是挂起 有没有办法将一些侦听器注册到SparkContext,这样当sc关闭时,每个工作节点上的ActorSystem都会收到关闭自己的通知 更
对象ResourceFactory
,其中包含一个akkaActorSystem
,用于提供资源客户端。因此,当我运行这个spark应用程序时,每个工作节点都将创建一个ActorSystem
。问题是,当spark应用程序完成其工作并关闭时。ActorSystem
在每个工作节点上仍然保持活动状态,并防止整个应用程序终止,它只是挂起
有没有办法将一些侦听器注册到SparkContext
,这样当sc
关闭时,每个工作节点上的ActorSystem
都会收到关闭自己的通知
更新: 以下是简化的框架: 有一个
资源工厂
,它是一个对象
,它包含一个参与者系统
。它还提供了一个fetchData
方法
object ResourceFactory{
val actorSystem = ActorSystem("resource-akka-system")
def fetchData(): SomeData = ...
}
然后,有一个用户定义的RDD
类,在它的计算
方法中,它需要从资源工厂
获取数据
class MyRDD extends RDD[SomeClass] {
override def compute(...) {
...
ResourceFactory.fetchData()
...
someIterator
}
}
因此,在每个节点上都会有一个名为“resource akka system”的ActorSystem
,分布在这些工作节点上的MyRDD
实例可以从“resource akka system”获取数据
问题是,当SparkContext
关闭时,不需要那些“资源akka系统”,但我不知道如何通知ResourceFactory
在SparkContext
关闭时关闭“资源akka系统”。所以现在,“资源akka系统”在每个工作节点上保持活动状态,并阻止整个程序退出
更新2: 通过更多的实验,我发现在本地模式下程序被挂起,但在
纱线簇
模式下,程序将成功退出。这可能是因为当sc
关闭时,warn
将终止工作节点上的线程
更新3: 为了检查每个节点是否都包含一个
ActorSystem
,我将代码更改如下(下面是真实的框架,因为我添加了另一个类定义):
在添加了那些println
s之后,我在spark on Thread cluster模式下运行代码。我发现在司机身上有以下指纹:
creating my rdd
creating resource factory
creating my rdd
...
creating rdd iterator
creating resource factory
在一些工人身上,我有以下照片:
creating my rdd
creating resource factory
creating my rdd
...
creating rdd iterator
creating resource factory
而一些工人,它什么也不打印(而且他们都没有被分配任何任务)
基于上述情况,我认为对象
是在驱动程序中急切地初始化的,因为它在驱动程序上打印创建资源工厂
,即使没有任何东西引用它,而对象
在worker中被惰性地初始化,因为它在打印创建rdd迭代器
后打印创建资源工厂
,因为资源工厂被第一个创建的rdd迭代器惰性地引用
我发现在我的用例中,MyRDD
类只在驱动程序中创建
我不太确定在驱动程序和工作程序上初始化
对象
的惰性,这是我的猜测,因为可能是程序的其他部分造成的。但我认为,在必要时,每个工作节点上都有一个参与者系统应该是正确的。我认为没有办法进入每个工作节点的生命周期
此外,我对您的实施有一些疑问:
如果您有一个包含val
的对象,它是从worker上运行的函数中使用的,我的理解是这个val
被序列化并广播给worker。您能否确认每个工人都有一个ActorSystem运行
若并没有显式地等待Actor系统的终止,它通常会立即终止。您是在调用类似于系统的东西。等待终止
还是在系统上阻塞。何时终止
无论如何,还有另一种方法,可以关闭远程工作者上的actor系统:
使您的ActorSystem位于akka集群的每个节点上。如何以编程方式实现这一点
将“协调”参与者在驱动程序节点上的地址(您的sc
所在位置)广播给每个工作人员。简单地说,只需将val
与该地址关联即可
在每个工作人员上启动akka系统时,使用该“协调”参与者地址注册该特定参与者系统(向协调参与者发送相应消息)
协调参与者跟踪所有注册的“工人”参与者
当您的计算完成并且希望关闭每个工作程序上的Akka系统时,从驱动程序节点上的协调参与者向所有注册的参与者发送消息
收到“关机”消息时,工人Akka系统关机
对于第一个问题,我需要几天后确认每个worker节点都有一个ActorSystem。现在从理论上讲,我认为在启动spark时,所有字节码都将被发送到每台机器,因此当我在RDD代码中引用一个对象时,它将引用本地发送和类加载的对象实例。基于此,我认为每个节点都有一个ActorSystem。如果是错误的,那么我认为我误解了spark,请指出并纠正我。对于第二个问题,请参见问题中的更新2,我认为这是相关的。回到问题上来,我不会调用任何类似于system.aWritermination
的东西。我认为Actor系统不会终止,除非我调用类似于System.shutdown的东西。也许我又错了@宇宙人, 根据编程指南,您的代码被发送到驱动程序节点,然后驱动程序节点将字节码和序列化的“封闭范围”一起分发给工作人员。检查该部分。但我不能100%确定你的情况会怎样