从本地 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_HOME
和PYSPARK_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 数据库?