Scala
Windows
Spark
python3
Anaconda

windowsでspark(scala+python)+jupyter環境構築

はじめに

機械学習/ディープラーニングの検証環境一式をWindowsで構成してみた。
理由は自宅で触れる最速環境が、GPUも搭載しているWindowsゲーム機だったため。

先人記事のトレースでほぼ導入できたものの、toree周りで問題が発生したため、記録も兼ねて記事とした。
回避策であり、解決策ではありません。参考程度で参照ください。

導入コンポーネント

導入したコンポーネントと、参照させていただいた先人皆様の各記事を感謝/敬意をこめてリンクさせていただく。

Windows固有対応

各種環境変数

あまりにもメジャーなことで固有とはおこがましいが一応記載
サンプルは下記

set JAVA_HOME=C:\program files\Java\xxx
set HADOOP_HOME=D:\programs\spark-2.2.1-bin-hadoop2.7
set SPARK_HOME=D:\programs\spark-2.2.1-bin-hadoop2.7
set PYTHONPATH=%PY4J%;%SPARK_HOME%\python
set PYSPARK_SUBMIT_ARGS="pyspark-shell"

参考までにpyspark関連をセットするバッチ(これでjupyterからpysparkが使える)

@echo off

set TARGET_DIR=%SPARK_HOME%\python\lib

set KEYWORD=py4j-*-src.zip

for /F "usebackq" %%i in (`powershell "(get-childitem '%TARGET_DIR%' | where-Object { $_.Name -like '%KEYWORD%' } | sort-object LastWriteTime | Select-Object -last 1).Name"`) do set LATEST=%%i

set PY4J=%TARGET_DIR%\%LATEST%

set PYTHONPATH=%PY4J%;%SPARK_HOME%\python;%PYTHONPATH%
set PYSPARK_SUBMIT_ARGS="pyspark-shell"

当たり前ですが、anaconda promptで上記環境変数をセットしてからjupyter notebook起動の順序で。

toree公式パッケージのWindows非対応

試してみて初めて知ったのだが、根本的な問題を抱えていた。
ひとまず回避できたので、最短手順を最初に記載する。

pipのアップグレード

toreeアップグレードの前提

conda install pip

toreeのアップグレード(0.1.0→0.2.0)

spark-submit実行時NosuckMethodError回避

pip install --upgrade https://dist.apache.org/repos/dist/dev/incubator/toree/0.2.0-incubating-rc2/toree-pip/toree-0.2.0.tar.gz
jupyter toree install --spark_home=%SPARK_HOME%

 

toreeシェルのWindowsバッチ化

spark-submit実行失敗の回避

  • run.batの配置(入手先)
  • kernel.jsonの修正
C:\ProgramData\jupyter\kernels\apache_toree_scala>diff kernel.json kernel.json.org
3c3
<     "C:\\ProgramData\\jupyter\\kernels\\apache_toree_scala\\bin\\run.bat",
---
>     "C:\\ProgramData\\jupyter\\kernels\\apache_toree_scala\\bin\\run.sh",

C:\ProgramData\jupyter\kernels\apache_toree_scala>

 
 

下記は試行錯誤の思い出


  • toree kernel実行時のエラー→シェルインタープリター(busybox)を入れてラップ(kernel.json修正)
[E 13:59:08.740 NotebookApp] Failed to run command:
    ['C:\\ProgramData\\jupyter\\kernels\\apache_toree_scala\\bin\\run.sh', '--profile', 'C:\\Users\\xxxx\\AppData\\Roaming\\jupyter\\runtime\\kernel-c2f63e0d-506a-4ed3-a4ee-a674fd112c19.json']
(略)
    OSError: [WinError 193] %1 は有効な Win32 アプリケーションではありません。
  • spark-submit実行jarクラスロード時のIOException→run.sh内でネィティブパスからURLに変換して引き渡すようにした
Exception in thread "main" java.io.IOException: No FileSystem for scheme: C
  • spark-submit時のNosuckMethodError→sparkとtoreeのscalaコンパイルバージョン差異が原因。toree0.2.0にアップグレード(参考)
Exception in thread "main" java.lang.NoSuchMethodError: scala.collection.immutable.HashSet$.empty()Lscala/collection/immutable/HashSet;
        at akka.actor.ActorCell$.<init>(ActorCell.scala:336)
        at akka.actor.ActorCell$.<clinit>(ActorCell.scala)
        at akka.actor.RootActorPath.$div(ActorPath.scala:185)
(略)
  • toree0.2.0アップグレード時のエラー→pipのアップグレード(参考)
pip install --upgrade https://dist.apache.org/repos/dist/dev/incubator/toree/0.2.0-incubating-rc2/toree-pip/toree-0.2.0.tar.gz
(略)
TypeError: parse() got an unexpected keyword argument 'transport_encoding'
  • spark-submit時のZMQException→調査/対応断念
17/12/27 15:08:13 ERROR ZeroMQSocketRunnable: Unexpected exception in 0mq socket runnable!
org.zeromq.ZMQException: Errno 48 : Address already in use
        at org.zeromq.ZMQ$Socket.mayRaise(ZMQ.java:1425)
        at org.zeromq.ZMQ$Socket.bind(ZMQ.java:1187)
        at org.zeromq.ZMQ$Socket.bind(ZMQ.java:1148)
        at org.apache.toree.communication.socket.ZeroMQSocketRunnable$$anonfun$processOptions$2.apply(ZeroMQSocketRunnable.scala:88)
        at org.apache.toree.communication.socket.ZeroMQSocketRunnable$$anonfun$processOptions$2.apply(ZeroMQSocketRunnable.scala:87)
        at scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:33)
        at scala.collection.mutable.WrappedArray.foreach(WrappedArray.scala:35)
        at org.apache.toree.communication.socket.ZeroMQSocketRunnable.processOptions(ZeroMQSocketRunnable.scala:87)
        at org.apache.toree.communication.socket.ZeroMQSocketRunnable.run(ZeroMQSocketRunnable.scala:144)
        at java.lang.Thread.run(Unknown Source)

  1. SBT導入までは必須でない