配置 Spark 以使用 Jupyter Notebook 和 Anaconda
Posted
技术标签:
【中文标题】配置 Spark 以使用 Jupyter Notebook 和 Anaconda【英文标题】:Configuring Spark to work with Jupyter Notebook and Anaconda 【发布时间】:2017-12-15 00:23:36 【问题描述】:我花了几天时间尝试让 Spark 与我的 Jupyter Notebook 和 Anaconda 一起工作。这是我的 .bash_profile 的样子:
PATH="/my/path/to/anaconda3/bin:$PATH"
export JAVA_HOME="/my/path/to/jdk"
export PYTHON_PATH="/my/path/to/anaconda3/bin/python"
export PYSPARK_PYTHON="/my/path/to/anaconda3/bin/python"
export PATH=$PATH:/my/path/to/spark-2.1.0-bin-hadoop2.7/bin
export PYSPARK_DRIVER_PYTHON=jupyter
export PYSPARK_DRIVER_PYTHON_OPTS="notebook" pyspark
export SPARK_HOME=/my/path/to/spark-2.1.0-bin-hadoop2.7
alias pyspark="pyspark --conf spark.local.dir=/home/puifais --num-executors 30 --driver-memory 128g --executor-memory 6g --packages com.databricks:spark-csv_2.11:1.5.0"
当我输入 /my/path/to/spark-2.1.0-bin-hadoop2.7/bin/spark-shell
时,我可以在命令行 shell 中正常启动 Spark。并且输出sc
不为空。它似乎工作正常。
当我输入 pyspark
时,它会启动我的 Jupyter Notebook。当我创建一个新的 Python3 笔记本时,会出现这个错误:
[IPKernelApp] WARNING | Unknown error in handling PYTHONSTARTUP file /my/path/to/spark-2.1.0-bin-hadoop2.7/python/pyspark/shell.py:
我的 Jupyter Notebook 中的 sc
是空的。
谁能帮忙解决这个问题?
只是想澄清一下:错误末尾的冒号后面没有任何内容。我还尝试使用这个post 创建我自己的启动文件,我在这里引用,所以你不必去那里看:
我创建了一个简短的初始化脚本 init_spark.py,如下所示:
from pyspark import SparkConf, SparkContext conf = SparkConf().setMaster("yarn-client") sc = SparkContext(conf = conf)
并将其放在 ~/.ipython/profile_default/startup/ 目录中
当我这样做时,错误就变成了:
[IPKernelApp] WARNING | Unknown error in handling PYTHONSTARTUP file /my/path/to/spark-2.1.0-bin-hadoop2.7/python/pyspark/shell.py:
[IPKernelApp] WARNING | Unknown error in handling startup files:
【问题讨论】:
警告文本的其余部分是什么?那行末尾有一个冒号,后面有什么吗? 不!它是空的。逗号后没有任何内容。 如果删除alias
行,或者尝试删除其中的一些选项怎么办?错误有变化吗?
刚刚尝试删除别名。没有不同。还是一样的错误:(
这是一个相关链接,可能对***.com/questions/33908156/… 有所帮助。将 pyspark-shell 添加到 PYSPARK_SUBMIT_ARGS 是关键。
【参考方案1】:
好吧,看到像设置PYSPARK_DRIVER_PYTHON=jupyter
这样的蹩脚黑客如何被提升为“解决方案”并且现在趋于成为标准做法,这真的让我很痛苦,尽管它们显然会导致丑陋 结果,例如输入 pyspark
并最终使用 Jupyter notebook 而不是 PySpark shell,以及潜伏在下游的尚未发现的问题,例如当您 try to use spark-submit
with the above settings... :(
(不要误会我的意思,这不是你的错,我也没有责怪你;我在 SO 看到了几十个帖子,其中这个“解决方案”已经被提出、接受和赞成......)。
在撰写本文时(2017 年 12 月),定制 Jupyter 笔记本以使用其他语言(此处为 PySpark)只有一种正确的方法,这就是 Jupyter kernels 的使用。
首先要做的是运行jupyter kernelspec list
命令,以获取您机器中所有可用内核的列表;这是我的情况(Ubuntu)的结果:
$ jupyter kernelspec list
Available kernels:
python2 /usr/lib/python2.7/site-packages/ipykernel/resources
caffe /usr/local/share/jupyter/kernels/caffe
ir /usr/local/share/jupyter/kernels/ir
pyspark /usr/local/share/jupyter/kernels/pyspark
pyspark2 /usr/local/share/jupyter/kernels/pyspark2
tensorflow /usr/local/share/jupyter/kernels/tensorflow
第一个内核 python2
是 IPython 附带的“默认”内核(很有可能这是您系统中唯一存在的内核);至于其余的,我还有 2 个 Python 内核 (caffe
& tensorflow
)、一个 R 内核 (ir
) 和两个分别用于 Spark 1.6 和 Spark 2.0 的 PySpark 内核。
上面列表中的条目是目录,每个条目都包含一个文件,名为kernel.json
。让我们看看我的pyspark2
内核的这个文件的内容:
"display_name": "PySpark (Spark 2.0)",
"language": "python",
"argv": [
"/opt/intel/intelpython27/bin/python2",
"-m",
"ipykernel",
"-f",
"connection_file"
],
"env":
"SPARK_HOME": "/home/ctsats/spark-2.0.0-bin-hadoop2.6",
"PYTHONPATH": "/home/ctsats/spark-2.0.0-bin-hadoop2.6/python:/home/ctsats/spark-2.0.0-bin-hadoop2.6/python/lib/py4j-0.10.1-src.zip",
"PYTHONSTARTUP": "/home/ctsats/spark-2.0.0-bin-hadoop2.6/python/pyspark/shell.py",
"PYSPARK_PYTHON": "/opt/intel/intelpython27/bin/python2"
我没有费心将我的详细信息更改为/my/path/to
等,您已经可以看到我们的案例之间存在一些差异(我使用的是 Intel Python 2.7,而不是 Anaconda Python 3),但希望您能得到想法(顺便说一句,不要担心connection_file
- 我也不使用)。
现在,对您来说最简单的方法是手动对上面显示的内核进行必要的更改(仅限路径)并将其保存在 .../jupyter/kernels
目录的新子文件夹中(这样,如果您再次运行jupyter kernelspec list
命令)。如果您认为这种方法也是一种 hack,那么我同意您的看法,但这是 Jupyter documentation(第 12 页)中推荐的方法:
但是,没有很好的方法来修改内核规范。一种方法使用
jupyter kernelspec list
查找kernel.json
文件,然后对其进行修改,例如kernels/python3/kernel.json
,手工制作。
如果您还没有.../jupyter/kernels
文件夹,您仍然可以使用jupyter kernelspec install
安装新内核 - 尚未尝试过,但请查看this SO answer。
最后,不要忘记从 bash 配置文件中删除所有与 PySpark 相关的环境变量(只留下 SPARK_HOME
应该没问题)。并确认,当您键入 pyspark
时,您会发现自己使用的是 PySpark shell,它应该是,而不是 Jupyter 笔记本......
更新(注释后):如果你想将命令行参数传递给 PySpark,你应该在env
下添加PYSPARK_SUBMIT_ARGS
设置;例如,这里是我各自的 Spark 1.6.0 内核文件的最后一行,我们仍然必须使用外部 spark-csv 包来读取 CSV 文件:
"PYSPARK_SUBMIT_ARGS": "--master local --packages com.databricks:spark-csv_2.10:1.4.0 pyspark-shell"
【讨论】:
使用 Apache Toree 项目可以让这一切变得“更轻松” @desertnaut 我跟着你的例子,用Saprk 2.2.1
和Python 3.6
设置了pyspark 内核。你能告诉我从终端启动 jupyter notebook 时如何指定 pyspark 内核吗
@KhurramMajeed 无需从命令行指定任何内容;在运行jupyter notebook
并进入笔记本仪表板后,在选择新时,您可以获得所有现有内核的下拉菜单,您可以在其中指定要使用的内核(内核显示它们各自的display_name
field kernel.json
文件如上所示)。见example here
@cricket_007 自 Toree 0.3.0 起对 PySpark(和 SparkR)内核的支持已停止,以下 github 提交:[TOREE-487][TOREE-488] Remove PySpark and SparkR interpreters Instead, please use a supported kernel such IPython or IRKernel
这篇文章是救命稻草。
这真的很有帮助。我唯一要补充的是locate spark
可用于识别正确的路径。这花了我一些时间,但是一旦我能够找到正确的路径,我就会将它们与@desertnaut 所说的相匹配。非常感谢您!【参考方案2】:
Conda 可以帮助正确管理大量依赖项...
安装火花。假设 spark 安装在 /opt/spark 中,请将其包含在您的 ~/.bashrc 中:
export SPARK_HOME=/opt/spark
export PATH=$SPARK_HOME/bin:$PATH
创建一个 conda 环境,其中包含除 spark 之外的所有所需依赖项:
conda create -n findspark-jupyter-openjdk8-py3 -c conda-forge python=3.5 jupyter=1.0 notebook=5.0 openjdk=8.0.144 findspark=1.1.0
激活环境
$ source activate findspark-jupyter-openjdk8-py3
启动 Jupyter Notebook 服务器:
$ jupyter notebook
在您的浏览器中,创建一个新的 Python3 笔记本
尝试使用以下脚本计算 PI(借用自 this)
import findspark
findspark.init()
import pyspark
import random
sc = pyspark.SparkContext(appName="Pi")
num_samples = 100000000
def inside(p):
x, y = random.random(), random.random()
return x*x + y*y < 1
count = sc.parallelize(range(0, num_samples)).filter(inside).count()
pi = 4 * count / num_samples
print(pi)
sc.stop()
【讨论】:
我已经设置了这里提到的所有三种方法,并且可以选择我觉得没有任何冲突的任何方法......至少现在是这样。注意:我使用了 bash 函数,而不是对环境变量进行硬编码。【参考方案3】:我刚刚 conda 安装了 sparkmagic(在重新安装了新版本的 Spark 之后)。
我认为仅此一项就可以了,而且比手动摆弄配置文件要简单得多。
【讨论】:
以上是关于配置 Spark 以使用 Jupyter Notebook 和 Anaconda的主要内容,如果未能解决你的问题,请参考以下文章
linux下jupyter 配置spark,出现jupyter notebook requires javascript怎么处理
Spark:如何从其他用户以“yarn_client”模式远程启动 Jupyter