Spark/ScalaをJupyterで使うときの小さなつまずきメモ

<font color="gold">**※筆者のような初心者レベルの記事です**</font>

SparkをJupyterで使いたい。
が、なんか環境構築がうまくいかない。最近の記事もない。
というかインストールはできたけどロクに動いてない。
環境変数も多分合ってる気がするんだけど、、、、これわっかんねー:rolling_eyes:
となってしまった人向け。


# スタート地点

- Jupyter、Python3、Spark(2.2.0)、Scala(2.11.8)、Sbt、JDK8、Dockerをインストール済み
- 非Anaconda
- JupyterでPython3が調子よく動いている
- spark-shellが調子よく動いている
- **筆者は怠け者の上、エンジニアリング力が低く、環境構築でよくギブアップしそうになる（する）<重要>**


# Notebookの選択肢

- Jupyter + Pyspark
- Zeppelin
- Jupyter + Toree 

他にもありますがこの3つをやりました。

 
# Jupyter + Pyspark

pip install pysparkで終わったはず。
MacとかPythonのきっちり動くパッケージマネージャは自分のようなザコにとって神に等しい存在です。

実務的にはこれで全然いいのですが、pysparkは、

- 今教科書にしたいと思っている本がscalaで書かれている
- **scala使えるとなんかかっこいい気がする**

という**いかにもザコっぽい動機**から一旦保留しました。
最終的はpyspark使う予定なんですが、scala触りたいので回り道をします。


# Zeppelin

ここからだんだん本題です。
↓公式の記事まんまでよかったのですが、しょうもないところで時間を食いました。

https://zeppelin.apache.org/docs/0.7.0/install/install.html#installation

### つまずいたところ
localhost:8080をChromeで開いたとき、ERR_CONNECTION_REFUSEDになってZeppelinが表示されない。
（**画面をきちんと見ていなかったため**、CONNECTION_REFUSEDの文字に気づかず、「あ゛あ゛！？:imp:」ってなって、あれこれいじくり回していた）

InstallがSuccessで終わって、startとstopのときに、

```shell:
Zeppelin start [ OK ]
Zeppelin stop [ OK ]
```

ってだけ出るようになったら知る限りちゃんと動いてます。
逆に環境変数とか下手にいじって怪我したときは、変なログがちょろっと出た。

### 解決策
Safariで開いたら動きました（ニッコリ
ザコなのでCONNECTION_REFUSEDに対応するという発想にはなりません。

ただ、Jupyterに比べてUIが使いづらいのと、**foreach{println()}がなぜか出力されない**ので、Jupyter+Toreeに鞍替えしてみることにしました。


# Jupyter + Toree

記事を書くことにした理由。
これですごく時間がかかってしまった。

### つまずいたところ

記事を探すと、pip install toreeして、sudo jupyter toree install --replace --spark_home="xxx"しろってのがちょこちょこ見つかる。

その通りインストールするととりあえずJupyter上にscalaカーネルが登録されて、ノートブックが作れるようになる。
ノートブックを起動すると、kernel呼び出してます→Trustedってとりあえず出るんだけど、そのまま応答しないで以下のエラー。

- Java NoSuchMethodError（Hashset的なやつが見つからないらしい）
- からのワーニング： waiting timeout

で、オプション変えてみたり、環境変数変えてみたり、あれこれやって全然うまくいかず。:sob:


### 解決策

↓これが答えでした。自分でビルドしろとのこと。

https://medium.com/@faizanahemad/machine-learning-with-jupyter-using-scala-spark-and-python-the-setup-62d05b0c7f56

記事内で紹介されているバグ報告
https://issues.apache.org/jira/browse/TOREE-336


pipで配布されるファイルが最新のspark/scalaに対応してないらしく、それを使う場合は今でも自分でmakeしないとダメだそうで。
というわけで、記事の通りにgitでクローンを持ってきて、Makefileを編集して自分でmakeします。

```
git clone git@github.com:apache/incubator-toree.git
```

ただ、Makefileはすでにspark/scalaの最新版に合わせて編集されていたので、やることなし。
（使用中のバージョンは、spark: 2.2.0、scala: 2.11.8）

```shell:Makefile
APACHE_SPARK_VERSION?=2.2.0
SCALA_VERSION?=2.11
```

```shell:
make release
```

makeの途中で「Jitpack.ioがないよエラー」が出ますが、これは無視してもうまいこと処理してくれました。

次に「Dockerのデーモンがいないよエラー」が出たので、これは出ないようにあらかじめDockerを起動してネットに繋いでから実行してください。

最後に「jovyanの権限がねーと必要なディレクトリにアクセスできんぞエラー」と「お前んとこのpipのバージョン古いんじゃねーのエラー」が出ます（多分Docker側の話だと思う）。
最後の最後でエラーかい:dizzy_face:という気持ちと、ｼﾞｮﾌﾞﾔﾝ誰:thinking:という気持ちをひとまず抑えて、インストール用ファイル dist/toree-pip/toree-x.x.x.dev1.tar.gz が生成されていることを確認すると、問題なく生成されていると思うので、これをインストールして終わりです。

```
pip install dist/toree-pip/toree-x.x.x.dev1.tar.gz
```

Jupyterを起動するとscalaカーネルが登録されています。
適当にval作ってprintlnしたり、テキストデータをRDDにしたり、DataFrameにしたり、filterしたりmapしたりという操作ができることを確認しました。
（クラスタ云々については確認していません。）


# 微妙なところ

こうしてひとまず使える状態になったのですが、やっぱりZeppelinと同じで、**foreach{println()}がなぜか出力されませんでした**。
（対処法をご存知の方がいたら、コメントをいただけるとうれしいです :wink:）

<font color="Orange">*後日追記*
*printはコンソール側に出力されることがわかりました。*</font>

↓あと、ここらへんが微妙にうまくいってませんでした。起動直後に「sc」を実行したときの出力とか。

https://support.datastax.com/hc/en-us/articles/207356773-FAQ-Warning-message-java-net-BindException-Address-already-in-use-when-launching-Spark-shell

こっちは困るまでは放置かなー。


# おわりに

というわけで自分はJupyter+Toreeを動かすのにやたらと苦戦したので、（内容的には恥ずかしいレベルだと思いますが）同じような面倒に合う人が減ればいいなと思いメモを残しました。
それではみなさま快適な Spark/Jupyter 生活をお送りください。