首页 > 解决方案 > 为什么 pyspark 的实现使得退出会话会停止底层的 spark 上下文?

问题描述

我只是通过编写像这样的“pythonic”火花代码来大量拍摄我的脚:

# spark = ... getOrCreate() # essentially provided by the environment (Databricks)
with spark.newSession() as session:
     session.catalog.setCurrentDatabase("foo_test")
     do_something_within_database_scope(session)

assert spark.currentDatabase() == "default"

哦,我很惊讶在执行这个笔记本单元时,集群以某种方式终止了。

我通读了这个答案,它告诉我,只能有一个火花上下文。那也行。但是为什么退出会话会终止底层上下文?对此是否有一些要求,或者这只是 pyspark 中的设计缺陷?

我也明白会话的__exit__调用调用context.stop()- 我想知道为什么它是这样实现的!

我一直认为是session一些用户发起的事情,比如我可以根据自己的意愿创建和丢弃的数据库或 http 客户端。如果会话提供__enter____exit__然后我尝试在with上下文中使用它,以确保在完成后进行清理。

我的理解是错误的,或者为什么 pyspark 会偏离这个概念?

编辑:我databricks-connect与它自己的pyspark python模块一起测试了它,但正如pri在下面指出的那样,它似乎在标准pyspark中以相同的方式实现。

标签: apache-sparkpyspark

解决方案


我查看了代码,它调用了以下方法:

@since(2.0)
def __exit__(
    self,
    exc_type: Optional[Type[BaseException]],
    exc_val: Optional[BaseException],
    exc_tb: Optional[TracebackType],
) -> None:
    """
    Enable 'with SparkSession.builder.(...).getOrCreate() as session: app' syntax.

    Specifically stop the SparkSession on exit of the with block.
    """
    self.stop()

stop方法是:

@since(2.0)
def stop(self) -> None:
    """Stop the underlying :class:`SparkContext`."""
    from pyspark.sql.context import SQLContext

    self._sc.stop()
    # We should clean the default session up. See SPARK-23228.
    self._jvm.SparkSession.clearDefaultSession()
    self._jvm.SparkSession.clearActiveSession()
    SparkSession._instantiatedSession = None
    SparkSession._activeSession = None
    SQLContext._instantiatedContext = None

所以我认为你不能只停止 SparkSession。每当 Spark Session 停止时(无论以何种方式,在这种情况下,当它从 'with' 块中出来时,__exit__被调用),它都会连同它一起杀死底层的 SparkContext。

链接到下面的相关 Apache Spark 代码:

https://github.com/apache/spark/blob/master/python/pyspark/sql/session.py#L1029


推荐阅读