从本地 jupyter notebook 连接到 spark 集群

Posted

技术标签:

【中文标题】从本地 jupyter notebook 连接到 spark 集群【英文标题】:Connect to spark cluster from local jupyter notebook 【发布时间】:2020-08-10 22:02:39 【问题描述】:

我尝试从本地计算机上的笔记本连接到远程 spark master。

当我尝试创建 sparkContext 时

sc = pyspark.SparkContext(master = "spark://remote-spark-master-hostname:7077", 
                          appName="jupyter notebook_test"),

我得到以下异常:

/opt/.venv/lib/python3.7/site-packages/pyspark/context.py in __init__(self, master, appName, sparkHome, pyFiles, environment, batchSize, serializer, conf, gateway, jsc, profiler_cls)
    134         try:
    135             self._do_init(master, appName, sparkHome, pyFiles, environment, batchSize, serializer,
--> 136                           conf, jsc, profiler_cls)
    137         except:
    138             # If an error occurs, clean up in order to allow future SparkContext creation:

/opt/.venv/lib/python3.7/site-packages/pyspark/context.py in _do_init(self, master, appName, sparkHome, pyFiles, environment, batchSize, serializer, conf, jsc, profiler_cls)
    196 
    197         # Create the Java SparkContext through Py4J
--> 198         self._jsc = jsc or self._initialize_context(self._conf._jconf)
    199         # Reset the SparkConf to the one actually used by the SparkContext in JVM.
    200         self._conf = SparkConf(_jconf=self._jsc.sc().conf())

/opt/.venv/lib/python3.7/site-packages/pyspark/context.py in _initialize_context(self, jconf)
    304         Initialize SparkContext in function to allow subclass specific initialization
    305         """
--> 306         return self._jvm.JavaSparkContext(jconf)
    307 
    308     @classmethod

/opt/.venv/lib/python3.7/site-packages/py4j/java_gateway.py in __call__(self, *args)
   1523         answer = self._gateway_client.send_command(command)
   1524         return_value = get_return_value(
-> 1525             answer, self._gateway_client, None, self._fqn)
   1526 
   1527         for temp_arg in temp_args:

/opt/.venv/lib/python3.7/site-packages/py4j/protocol.py in get_return_value(answer, gateway_client, target_id, name)
    326                 raise Py4JJavaError(
    327                     "An error occurred while calling 012.\n".
--> 328                     format(target_id, ".", name), value)
    329             else:
    330                 raise Py4JError(

Py4JJavaError: An error occurred while calling None.org.apache.spark.api.java.JavaSparkContext.
: java.lang.IllegalArgumentException: requirement failed: Can only call getServletHandlers on a running MetricsSystem
    at scala.Predef$.require(Predef.scala:224)
    at org.apache.spark.metrics.MetricsSystem.getServletHandlers(MetricsSystem.scala:91)
    at org.apache.spark.SparkContext.<init>(SparkContext.scala:516)
    at org.apache.spark.api.java.JavaSparkContext.<init>(JavaSparkContext.scala:58)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at py4j.reflection.MethodInvoker.invoke(MethodInvoker.java:247)
    at py4j.reflection.ReflectionEngine.invoke(ReflectionEngine.java:357)
    at py4j.Gateway.invoke(Gateway.java:238)
    at py4j.commands.ConstructorCommand.invokeConstructor(ConstructorCommand.java:80)
    at py4j.commands.ConstructorCommand.execute(ConstructorCommand.java:69)
    at py4j.GatewayConnection.run(GatewayConnection.java:238)
    at java.lang.Thread.run(Thread.java:745)

同时,我可以在交互模式下使用同一个解释器创建火花上下文。

我应该怎么做才能从我的本地 jupyter notebook 连接到远程 spark master?

【问题讨论】:

如果 PySpark 无法与主服务器通信,通常会发生这种情况。确保主机名正确,并且您在环境中正确设置了SPARK_HOMEPYSPARK_PYHON。本地和远程 Spark 版本不匹配也会导致该错误。 我的工作站和集群 (2.4.5) 上有相同的火花。我已经设置了 PYSPARK_PYTHON 和 SPARK_HOME。它可以帮助我使用 python 连接到集群,但我不能使用笔记本@HristoIliev 来做到这一点也许我应该为 jupyter 设置特殊设置? 在独立的python 和您的笔记本中打印os.environ 的值并查找差异。 非常感谢!我笔记本的环境不包含 SPARK_HOME。 您可以使用findspark 来简化流程 - 它会为您设置所有环境变量。 【参考方案1】:

我使用@HristoIliev 的建议解决了我的问题。 就我而言,PYSPARK_PYTHON 未在 jupyter 环境中设置。简单的解决方案:

import os
os.environ["PYSPARK_PYTHON"] = '/opt/.venv/bin/python'
os.environ["SPARK_HOME"] = '/opt/spark'

您也可以为此使用findspark,但我没有测试。

【讨论】:

以上是关于从本地 jupyter notebook 连接到 spark 集群的主要内容,如果未能解决你的问题,请参考以下文章

连接到远程服务器上的 docker 中运行的 jupyter notebook

如何从 Jupyter Notebook 中的 PySpark 远程连接到 Greenplum 数据库?

如何从 Watson Studio 中的 Jupyter Notebook 连接到 DashDB?

Jupyter Notebook 连接到远程配置单元

远程访问 WSL2 Jupyter notebook

如何连接到在 docker 容器上运行的远程 Jupyter Notebook?