配置Spark以使用Jupyter Notebook和Anaconda

时间:2017-12-15 00:23:36

标签: python pyspark anaconda jupyter-notebook jupyter

我花了几天时间试图让Spark与我的Jupyter笔记本和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笔记本电脑。当我创建一个新的Python3笔记本时,会出现此错误:

[IPKernelApp] WARNING | Unknown error in handling PYTHONSTARTUP file /my/path/to/spark-2.1.0-bin-hadoop2.7/python/pyspark/shell.py: 

我的Jupyter笔记本中的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:

2 个答案:

答案 0 :(得分:34)

嗯,真的让我感到很痛苦,看看糟糕的黑客,如设置PYSPARK_DRIVER_PYTHON=jupyter,已被提升为“解决方案”,现在倾向于成为标准做法,尽管它们显然导致了丑陋的结果,比如键入pyspark并最终使用Jupyter笔记本而不是PySpark shell,以及潜伏在下游的尚未见到的问题,例如当你try to use spark-submit with the above settings ...:(< / p>

(不要误会我的意思,这不是你的错,我不是在责怪你;我在SO那里看过几十个帖子,这个“解决方案”已被提议,接受和赞成......)。

只有一种正确的方法可以自定义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&amp; tensorflow),一个R(ir)和两个PySpark内核,分别用于Spark 1.6和Spark 2.0

上面列表的条目是目录,每个条目包含一个名为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命令)。如果你认为这种方法也是一种黑客攻击,那么,我会同意你的观点,但这是Jupyter documentation(第12页)中推荐的方法:

  

但是,没有很好的方法来修改kernelspecs。一种方法使用jupyter kernelspec list来查找kernel.json文件,然后对其进行修改,例如kernels/python3/kernel.json,手工制作。

如果您还没有.../jupyter/kernels文件夹,仍然可以使用jupyter kernelspec install安装新内核 - 尚未尝试过,但请查看this SO answer。< / p>

最后,不要忘记从bash配置文件中删除所有与PySpark相关的环境变量(只留下SPARK_HOME应该没问题)。并确认,当您键入pyspark时,您会发现自己应该使用PySpark shell,而不是使用Jupyter笔记本...

UPDATE (评论后):如果要将命令行参数传递给PySpark,则应在PYSPARK_SUBMIT_ARGS下添加env设置;例如,这是我的Spark 1.6.0各自内核文件的最后一行,我们仍然需要使用外部spark-csv包来读取CSV文件:

"PYSPARK_SUBMIT_ARGS": "--master local --packages com.databricks:spark-csv_2.10:1.4.0 pyspark-shell"

答案 1 :(得分:6)

Conda可以帮助正确管理很多依赖...

安装火花。假设在/ opt / spark中安装了spark,请将其包含在〜/ .bashrc中:

export SPARK_HOME=/opt/spark
export PATH=$SPARK_HOME/bin:$PATH

创建一个除了spark之外还包含所有必需依赖项的conda环境:

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()