PySpark環境構築 ~PySparkをJupyter notebookで動かすところまで~

# PySpark用の環境を作ってみた

SparkをPythonから使うPySparkの設定記事です。
Java8やpyenv, pyenv-virtualenvがインストールされていることを前提としています。
Sparkのインストールから、pysparkをjupyter notebookで起動するところまで。

## 環境
### OS

```
[koutaru@ktr-server ~]$ cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)
```

### Javaのバージョン
Java9で環境構築を試みましたがダメだった(20171201現在)のでJava8で構築しました。

```
[koutaru@ktr-server ~]$ java -version
openjdk version "1.8.0_151"
OpenJDK Runtime Environment (build 1.8.0_151-b12)
OpenJDK 64-Bit Server VM (build 25.151-b12, mixed mode)
```

## Sparkをインストール
Sparkのダウンロードと展開、そしてインストール

```
[koutaru@ktr-server ~]$ cd Downloads/
[koutaru@ktr-server Downloads]$ wget http://ftp.meisei-u.ac.jp/mirror/apache/dist/spark/spark-2.2.0/spark-2.2.0-bin-hadoop2.7.tgz # ミラーサーバからSparkをダウンロード
[koutaru@ktr-server Downloads]$ tar xvf spark-2.2.0-bin-hadoop2.7.tgz
[koutaru@ktr-server Downloads]$ sudo mv spark-2.2.0-bin-hadoop2.7 /opt/
[koutaru@ktr-server Downloads]$ cd /opt/
[koutaru@ktr-server opt]$ sudo ln -s /opt/spark-2.2.0-bin-hadoop2.7 /opt/spark  # シンボリックリンクの作成
[koutaru@ktr-server opt]$ ls
rh  spark  spark-2.2.0-bin-hadoop2.7
[koutaru@ktr-server opt]$ file /opt/spark # シンボリックリンクの確認
/opt/spark: symbolic link to `/opt/spark-2.2.0-bin-hadoop2.7'
[koutaru@ktr-server opt]$ vim ~/.bash_profile # パスの設定
[koutaru@ktr-server opt]$ cat ~/.bash_profile | tail -n 3
# Spark
export SPARK_HOME=/opt/spark
export PATH=$PATH:$SPARK_HOME/bin
[koutaru@ktr-server opt]$ source ~/.bash_profile
[koutaru@ktr-server opt]$ which spark-shell # 確認
/opt/spark/bin/spark-shell
```

## Python環境構築
自分はpyenv-virtualenvという物を使って環境を分けています。
これはディレクトリごとにPython環境を分離することができるものです。
今回はこれを使ってPySpark用の環境をつくってみました。

https://github.com/pyenv/pyenv-virtualenv

```
[koutaru@ktr-server spark]$ pwd
/home/kotaro/project/spark
[koutaru@ktr-server spark]$ pyenv virtualenv 3.6.3 pyspark # pyspark用の環境を作成 (pythonのバージョンは3.6.3)
[koutaru@ktr-server spark]$ pyenv versions
  system
* 3.6.3 (set by /home/kotaro/.pyenv/version)
  3.6.3/envs/estimator_project
  3.6.3/envs/extract_geo
  3.6.3/envs/pyspark
  estimator_project
  extract_geo
  pyspark
[koutaru@ktr-server spark]$ pyenv local pyspark # 現在いるディレクトリのpythonをpyspark専用のものにする
(pyspark) [koutaru@ktr-server spark]$ pyenv version # Pythonのバージョン確認
pyspark (set by /home/kotaro/project/spark/.python-version)
(pyspark) [koutaru@ktr-server spark]$ pip install jupyter
(pyspark) [koutaru@ktr-server spark]$ which python # pythonのパスを確認
~/.pyenv/shims/python
(pyspark) [koutaru@ktr-server spark]$ vim ~/.bash_profile # 下記のように4行追加
(pyspark) [koutaru@ktr-server spark]$ cat ~/.bash_profile | tail -n 4
# PySpark
export PYSPARK_PYTHON=${HOME}/.pyenv/shims/python
export PYSPARK_DRIVER_PYTHON=jupyter
export PYSPARK_DRIVER_PYTHON_OPTS='notebook' pyspark
(pyspark) [koutaru@ktr-server spark]$ source ~/.bash_profile
(pyspark) [koutaru@ktr-server spark]$ pyspark # jupyter notebookが立ち上がる
```

はい！ここまでうまくできたでしょうか。
立ち上がったjupyter notebookでpython3カーネルを選んで起動し、セルにscと入力してみてください。
私の環境では下記のように出力されました。

SparkContext

Spark UI

Version
    v2.2.0
Master
    local[*]
AppName
    PySparkShell


完成です。

# .bash_profileの設定のまとめ
```
[koutaru@ktr-server ~]$ cat ~/.bash_profile | tail -n 11
# Java8
export PATH=$PATH:/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.151-1.b12.el7_4.x86_64/jre/bin/java

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

# PySpark
export PYSPARK_PYTHON=${HOME}/.pyenv/shims/python
export PYSPARK_DRIVER_PYTHON=jupyter
export PYSPARK_DRIVER_PYTHON_OPTS='notebook' pyspark
```

```
$ cowsay -f ghostbusters "pysparkの環境構築完了"
 ________________
< pysparkの環境構築完了 >
 ----------------
          \
           \
            \          __---__
                    _-       /--______
               __--( /     \ )XXXXXXXXXXX\v.
             .-XXX(   O   O  )XXXXXXXXXXXXXXX-
            /XXX(       U     )        XXXXXXX\
          /XXXXX(              )--_  XXXXXXXXXXX\
         /XXXXX/ (      O     )   XXXXXX   \XXXXX\
         XXXXX/   /            XXXXXX   \__ \XXXXX
         XXXXXX__/          XXXXXX         \__---->
 ---___  XXX__/          XXXXXX      \__         /
   \-  --__/   ___/\  XXXXXX            /  ___--/=
    \-\    ___/    XXXXXX              '--- XXXXXX
       \-\/XXX\ XXXXXX                      /XXXXX
         \XXXXXXXXX   \                    /XXXXX/
          \XXXXXX      >                 _/XXXXX/
            \XXXXX--__/              __-- XXXX/
             -XXXXXXXX---------------  XXXXXX-
                \XXXXXXXXXXXXXXXXXXXXXXXXXX/
                  ""VXXXXXXXXXXXXXXXXXXV""

```