Scala 如果SparkSession未关闭,会发生什么情况?
以下两个之间有什么区别Scala 如果SparkSession未关闭,会发生什么情况?,scala,apache-spark,apache-spark-sql,Scala,Apache Spark,Apache Spark Sql,以下两个之间有什么区别 object Example1 { def main(args: Array[String]): Unit = { try { val spark = SparkSession.builder.getOrCreate // spark code here } finally { spark.close } } } object Exam
object Example1 {
def main(args: Array[String]): Unit = {
try {
val spark = SparkSession.builder.getOrCreate
// spark code here
} finally {
spark.close
}
}
}
object Example2 {
val spark = SparkSession.builder.getOrCreate
def main(args: Array[String]): Unit = {
// spark code here
}
}
我知道SparkSession实现了Closeable,它暗示需要关闭它。但是,如果SparkSession只是像示例2中那样创建,并且从未直接关闭,我想不出任何问题
如果Spark应用程序成功或失败(并退出主方法),JVM将终止,SparkSession将随之消失。这是正确的吗
IMO:SparkSession是一个单身的事实也不会有太大的区别。当你完成SparkSession的使用时,你应该总是关闭你的
SparkSession
(即使最终结果只是为了遵循一个良好的实践,即归还你所得到的东西)
关闭SparkSession
可能会触发释放可提供给其他应用程序的群集资源
SparkSession
是一个会话,因此维护一些消耗JVM内存的资源。您可以拥有任意数量的SparkSessions(请参见重新创建会话),但您不希望它们使用内存,如果您不使用内存,则它们不应该使用内存,因此关闭
您不再需要的内存
SparkSession
是Spark SQL对Spark Core的包装,因此在封面下(就像在任何Spark应用程序中一样),您将拥有群集资源,即vCore和内存,分配给您的SparkSession
(通过SparkContext
)。这意味着,只要您的SparkContext
正在使用(使用SparkSession
),集群资源就不会分配给其他任务(不一定是Spark任务,也不一定是提交到集群的其他非Spark应用程序)。这些集群资源是您的,直到您说“我完成了”,这意味着…close
但是,如果在close
之后,您只需退出Spark应用程序,就不必考虑执行close
,因为资源将自动关闭。驱动程序和执行程序的JVM终止,与群集的(心跳)连接也终止,因此最终资源将返回群集管理器,以便它可以提供给其他应用程序使用。两者都是相同的
Spark会话的停止
/关闭
最终调用Spark上下文的停止
def stop(): Unit = {
sparkContext.stop()
}
override def close(): Unit = stop()
Spark上下文在退出JVM之前已运行时关闭Spark上下文。请在下面找到创建上下文时添加关机挂钩的spark代码
ShutdownHookManager.addShutdownHook(
_shutdownHookRef = ShutdownHookManager.SPARK_CONTEXT_SHUTDOWN_PRIORITY) { () =>
logInfo("Invoking stop() from shutdown hook")
stop()
}
因此,无论JVM如何退出,都将调用该函数。如果您手动stop()
,此关闭挂钩将被取消以避免重复
def stop(): Unit = {
if (LiveListenerBus.withinListenerThread.value) {
throw new SparkException(
s"Cannot stop SparkContext within listener thread of ${LiveListenerBus.name}")
}
// Use the stopping variable to ensure no contention for the stop scenario.
// Still track the stopped variable for use elsewhere in the code.
if (!stopped.compareAndSet(false, true)) {
logInfo("SparkContext already stopped.")
return
}
if (_shutdownHookRef != null) {
ShutdownHookManager.removeShutdownHook(_shutdownHookRef)
}
如果我错了,请纠正我,但是Spark应用程序可能成功或失败。无论哪种情况,Spark应用程序都会终止,与之关联的JVM也会终止。一旦JVM终止,所有资源都被释放(无论我是否调用close)。另外,如果我使用
getOrCreate()
,SparkSession不是一个单例吗?你说“你想玩多少次就玩多少次”是什么意思?谢谢这里有两个问题:1)无论最终结果是失败还是成功,vcores和内存最终将被释放并在集群上可用;2)SparkSession
可能是单例,因此您可以继承特定于会话的设置,但您也可以使用spark.newSession将其与其他会话隔离。ShutdownHookManager.addShutdownHook(…)
可以在没有仔细分析的实际观察中找到:如果IntelliJ Scala工作表中未关闭SparkSession
,则重复的代码执行将失败,并出现无效链接错误。