Scala
Spark
docker
Jupyter
docker-compose

本記事はJupyter 上で Scala で書いたアプリを動かすようにすることを目的としています。

なぜ、Scala?

Jupyter を使うなら、Python で良いじゃないか!と思われる方も多いかと思います。
しかし、すでにある Scala で書かれた資産(コード)があって、
そのアプリに追加することを前提にした何らかのコードを書きたいとか、
Scala が好きなんだ!とか、
Scala を始めてみたいとか、
人生色々、会社理由も色々あると思います。
(まぁ、単純に筆者が Scala が好きで、Spark-Shell辛いけど、わざわざ、pyspark のAPIを覚えるの面倒だからという理由だったります。)

環境

以下の環境が事前に整っている前提です。

必須

Python

3系

sbt

1.0.3
(試してはいませんが、0.13系でも大丈夫じゃないかと)

Scala

2.12.2
(何で2.12系にしたのやら・・・2.11系で動くはずです)

Jupyter Scala

0.4.2(2017/11/14 時点での最新)

Jupyter kernel

0.4.1(2017/11/14 時点での最新)

Java

OpenJDK 8
(Java 8なら、Oracle JDK8 でも良いはず。今回はAmazon EMRに近付けたいため、EMRデフォルトのOpen JDKをyum installしています)

任意

OS

Amazon Linux 2017.03 の Docker image
(別に Python と JVMM が動くなら何でも良いです。Windows の場合は適宜、パスやコマンドをWindows のものに読み替えてください)

Spark

2.2.0
※ Jupyter 上で Scala を動かすだけであれば不要です。Spark アプリを動かすために構築した際の手順のため、Spark を動かすための設定を行っていたりします。

Docker周り

Jupyter 上で Scala を動かすだけであれば不要です。
今回は Amazon EMR に近い環境としたかったため、docker-compose を使って、
Spark クラスターを構築し、master ノード上で Jupyter を建てて、ホストからアクセスするようにしています。

  • Docker CE 17.09.0 (多分、docker-ceならどのバージョンでも大丈夫かと)
  • docker-compose

構築手順

Jupyter をインストールする

JupyterLab とかはお好みでと言ったところでしょうか
Spark を使わなければ、jupyter, notebook(or jupyterlab), py4j あたりがあれば良いのかお知れません(py4jも必須かは怪しいかも)

pip install jupyter
pip install notebook
pip install jupyterlab
pip --no-cache-dir install pandas pyspark
pip install py4j jupyter-spark lxml
pip install --upgrade beautifulsoup4 html5lib
jupyter nbextension install --py jupyter_spark
jupyter serverextension enable --py jupyter_spark
jupyter nbextension enable --py jupyter_spark
jupyter nbextension enable --py widgetsnbextension
jupyter serverextension enable --py jupyterlab --sys-prefix

pip install scipy scikit-learn pygments && \
pip3 install scipy scikit-learn pygments pandas pyspark ipykernel ipython

sbt をインストールする

今回のは、Dockerfile で Docker Image を構築しているため、sudo なり doas を行っていませんが、必要に応じて適宜、sudo なり doas を行なってください。

##
# Dockerfile では
# ENV SBT_HOME /usr/local/sbt
# ENV PATH ${PATH}:${SBT_HOME}/bin
# と記述
##

echo "export SBT_HOME=/usr/local/sbt" >> .bashrc
echo "export PATH=${PATH}:${SBT_HOME}/bin" >> .bashrc


export SBT_VERSION=1.0.3
curl -sL "https://github.com/sbt/sbt/releases/download/v${SBT_VERSION}/sbt-${SBT_VERSION}.tgz" | tar -xz -C /usr/local

Jupyter kernel/Jupyter Scala をインストールする

# Jupyter Scala のインストール
curl -sL "https://github.com/jupyter-scala/jupyter-scala/archive/v0.4.2.tar.gz" | tar -xz -C /usr/local && \
cd /usr/local/ && \
ln -s jupyter-scala-0.4.2 jupyter-scala && \
cd jupyter-scala && \
sbt publishLocal

# Jupyter Kernel のインストール
curl -sL "https://github.com/jupyter-scala/jupyter-kernel/archive/v0.4.1.tar.gz" | tar -xz -C /usr/local &&\
cd /usr/local/ && \
ln -s jupyter-kernel-0.4.1 jupyter-kernel && \
cd jupyter-kernel && \
sbt publishLocal

# 仕上げ
# Windows の場合は https://github.com/jupyter-scala/jupyter-scala/blob/master/jupyter-scala.ps1 を使えば良さそう

# /root 配下じゃ無くても良さそう
curl -sL "https://raw.githubusercontent.com/alexarchambault/jupyter-scala/master/jupyter-scala" -o /root/jupyter-scala.sh && \
chmod 744 /root/jupyter-scala.sh && \
sed -e "s/2.11.11/2.12.4/gi" /root/jupyter-scala.sh && \
/root/jupyter-scala.sh && \
rm -f /root/jupyter-scala.sh

これで Jupyter を起動すると以下のように、Jupyter 上で Scala が使えるようになります。
※ JupyterLab の起動画面
スクリーンショット 2017-11-15 22.46.48.png

動かしてみる

それぞれのセルに、以下のようなコードを記述してみました。

import $ivy.`org.apache.spark::spark-sql:2.2.0`
import $ivy.`org.apache.hadoop:hadoop-aws:2.7.3`
import $ivy.`org.jupyter-scala::spark:0.4.2`
import org.apache.spark.sql.SparkSession
import org.apache.spark.{SparkConf, SparkContext}
//Configuration
import jupyter.spark.session._

val spark = JupyterSparkSession
  .builder() // important - call this rather than SparkSession.builder()
  .jupyter()
  .master("local[*]")
  .config("spark.driver.memory","2g")
  .config("spark.memory.useLegacyMode", "true")
  .appName("notebook")
  .getOrCreate()
spark
  .sparkContext
  .parallelize(Array("Hello", "World", "!"))
  .foreach(System.err.println)
spark.stop()

スクリーンショット 2017-11-17 0.42.31.png

依存ライブラリの参照

以下のように記述する

$ivy.`group::artifact:version`

参考:https://github.com/jupyter-scala/jupyter-scala#spark

まとめ

sbt と Jupyter kernel/Jupyter Scala をインストールすればよい。

余談

職場などで、proxy を通す場合
https://github.com/jupyter-scala/jupyter-scala/issues/21
のとおり実施したら動作せず。

以下のように、argv セクションに追加したら動作しました

{
  "language" : "scala",
  "display_name" : "Scala",
  "argv" : [
    "java",
    "-noverify",
    "-Dhttp.proxyHost=...",
    "-Dhttp.proxyPort=...",
    "-Dhttps.proxyHost=...",
    "-Dhttps.proxyPort=...",
    "-jar",
    "/root/.local/share/jupyter/kernels/scala/launcher.jar",
    "launch",
    "-r",
    "sonatype:releases",
    "-r",
    "sonatype:snapshots",
    "-i",
    "ammonite",
    "-I",
    "ammonite:org.jupyter-scala:ammonite-runtime_2.11.11:0.8.3-1",
    "-I",
    "ammonite:org.jupyter-scala:scala-api_2.11.11:0.4.2",
    "org.jupyter-scala:scala-cli_2.11.11:0.4.2",
    "--",
    "--id",
    "scala",
    "--name",
    "Scala",
    "--quiet",
    "--connection-file",
    "{connection_file}"
  ]
}