3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

管理者権限の無い Windows11で Apache Spark環境を作る(2023/5月版)

Last updated at Posted at 2021-06-26

今日は、管理者権限の無い Windows 11で Portableな Apache Spark環境を作ってみます。

Linuxに比べると ちょい面倒だな、と思ったので共有しておきます。

更新履歴

(2023/05/01) Golden Weekに Windows11で色々最新化しておきましたが、コンパイル済みのWinUtilsが提供されなくなっているため、

入れる物

バージョン依存もあるので、あまり環境に影響を与えない形で入れて使う形にします。

VC++のRUNTIME DLLを除けば、今回作る Sparkのフォルダを丸ごとコピーして、
他のマシンにも持っていけるはずです(所謂Portable)。

  • Spark: 3.4.0 (Apr 13, 2023)
  • Java: OpenJDK17.0.7+7
  • Python: 3.7+ latest (3.11.3 - Embedded/Isolated)
  • Scala: 2.13.10

必要な物

  • Windows11 64bit
  • 7-zip(7z.exe)

7-zipは zipと tgz(.tar.gz)の解凍ができればよいので 他に方法があれば それでかまいません。

懸念点

管理者権限が完全無しでいけるかどうか。

Runtime DLL

管理者権限が無い場合、実行ファイルのDLL依存関係が少しやっかいです。

インストールされるファイルの .exe および .dll が static に linkしている DLL (変な表現)で
通常 Windows10の Systemに無いかもしれない DLLは以下の三つがあります。

MSVCP140.dll - MSVC++ 2015
VCRUNTIME140.dll - MSVC++ 2015
MSVCR100.dll - MSVC++ 2012

私の環境では VC++2013と VC++2015-2019の 再頒布可能パッケージが 既に入っていたため、問題ありませんでした。

入っていない場合、 Visual Studio 2019 の Microsoft Visual C++ 再頒布可能パッケージ等から入手してインストールが必要になります。

インストールパス

管理者権限無しでファイルを書き込む事ができる場所のパスに、空白文字が含まれる場合、問題が発生するはずです。

以下の例では C:\tools\spark にインストールしています。

書き込めるパスに空白文字がどうしても入ってしまうという場合、確かSUBSTコマンドは管理者権限でなくても実行できると思うので、別のドライブにアサインする等して回避できるかと思います。

ダウンロード

まず必要なファイルを全部ダウンロード。

下で細かく説明してますが、バージョンにこだわりが無く、まとめてダウンロードしたいなら以下の直リンクから落としてください。

他のバージョンにしたい、mirrorなどの状況もあって直接落とせない場合は以下を参照してみてください。

Eclipse Temurin™

.msiではなく、.zip のアーカイブが欲しいので以下からダウンロードします。

Latest Release | Adoptium

  1. Operating System で Windowsを選択
  2. Architectureで x64
  3. Package Typeで JDK
  4. Versionで 17
  5. .zipを押してダウンロード

image.png

Python 3.7+

今回 Spark 3.4.0を使うため Python 3.7が Deprecatedになっています。
Python Versionに制約のあるWindows7では、Python 3.8.16が使えるかと思います。

以下から Windows embeddable package (64-bit) をダウンロードします。

Python Releases for Windows

Scala 2.13

Version 2 系は以下のページから。

DOWNLOAD SCALA 2

このページの Current releasesから 2.13系のLatestに飛びます。今だと SCALA 2.13.10です。

ここの Other Resourcesから scala-2.13.10.zip をダウンロードします。

image.png

Apache Spark 3.4.0

Download Apache Sparkのページにいきます。

  1. Choose Spark Release から バージョンを指定
  2. Choose Package Type から パッケージタイプを選択(Pre-built for Apache Hadoop ...にしてください)
  3. ダウンロードリンクからダウンロード

image.png

蛇足ですが、Package Typeの選択で user-provided Apache Hadoopを選ぶとファイル名が spark-3.1.2-bin-without-hadoop.tgz になります。Hadoopなんて要らんって思ってこれを選ぶと、必要な Hadoop Client が無くて動きませんので注意してください。

WinUtils

Hadoop 3.3.5向けが無いので自前でコンパイルしてみます。

Windows 11 Proなどを使っているのであればサンドボックスで環境を汚さずに済むと思います。

なお、Visual Studioですが、Build Toolsでは コマンドが足りないため、IDEを入れる必要があります。

  • サンドボックス起動
  • Visual Studio 2022 Community EditionをDownloadして"C++によるデスクトップ開発"をチェックしてInstall
  • OpenJDK17 17.0.7+7をInstall。このとき JAVA_HOMEを設定する項目をチェックしておくこと。
  • CMake 3.26.3をインストール。このとき "PATHを設定する" を選択しておく。
  • Maven 3.9.1をダウンロードして、C:\tools\apache-maven-3.9.1 に展開して、M2_HOMEを "C:\tools\apache-maven-3.9.1"に設定、PATHに"%M2_HOME%\bin"を追加
  • Protocol Buffers v22.3をダウンロードして "C:\tools\protoc"に展開。PATHに "C:\tools\protoc\bin" を追加
  • Cygwinを "C:\cygwin64" にインストール。
  • gitをinstall
  • vcpkgをInstall
git clone https://github.com/microsoft/vcpkg
.\vcpkg\bootstrap-vcpkg.batvcpkg
.\vcpkg\vcpkg.exe install openssl --triplet x64-windows-static
.\vcpkg\vcpkg.exe install protobuf --triplet x64-windows-static
.\vcpkg\vcpkg.exe integrate install
  • コマンドプロンプトを立ち上げて以下を実行して Hadoopのソースをダウンロードして展開
SET "PATH=C:\cygwin64\bin;%PATH%"
call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat"
mkdir C:\work
cd C:\work
curl -LOJR https://dlcdn.apache.org/hadoop/common/hadoop-3.3.5/hadoop-3.3.5-src.tar.gz
tar xzf hadoop-3.3.5-src.tar.gz
cd hadoop-3.3.5-src
mvn package -Pdist,native-win -DskipTests -Dtar -Dmaven.javadoc.skip=true -Dnative_cmake_args="-DOPENSSL_USE_STATIC_LIBS=TRUE -DProtobuf_USE_STATIC_LIBS=ON -DCMAKE_TOOLCHAIN_FILE=C:/work/vcpkg/scripts/buildsystems/vcpkg.cmake"

mvn package -Pdist,native-win -DskipTests -Dtar -Dmaven.javadoc.skip=true "-Dnative_cmake_args=--trace-expand -DOPENSSL_ROOT_DIR=C:/work/vcpkg/installed/x64-windows-static -DOPENSSL_USE_STATIC_LIBS=TRUE -DProtobuf_USE_STATIC_LIBS=ON -DCMAKE_TOOLCHAIN_FILE=C:/work/vcpkg/scripts/buildsystems/vcpkg.cmake" -rf :hadoop-hdfs-native-client

展開

ダウンロードしたファイルを展開します。

私は C:\tools\spark\ に展開する事にしますのでダウンロードしたファイルを集めます。

C:\tools\spark>dir
2021/06/26  11:09       196,371,089 OpenJDK11U-jdk_x64_windows_hotspot_11.0.11_9.zip
2021/06/26  11:16         8,427,568 python-3.9.5-embed-amd64.zip
2021/06/26  10:31        21,133,076 scala-2.12.14.zip
2021/06/26  11:28       228,834,641 spark-3.1.2-bin-hadoop3.2.tgz
2021/06/26  11:51        20,758,178 winutils-master.zip

これを適宜解凍しますが、pythonだけは zipがフォルダ名を含んでいないので python-3.9.5に解凍します。

以下は7z.exeを使った場合のバッチ

ex.cmd
7z x OpenJDK11U-jdk_x64_windows_hotspot_11.0.11_9.zip
7z x scala-2.12.14.zip
7z x -opython-3.9.5 python-3.9.5-embed-amd64.zip
7z x spark-3.1.2-bin-hadoop3.2.tgz
7z x spark-3.1.2-bin-hadoop3.2.tar
7z x winutils-master.zip

こんな感じでフォルダに展開されると思います。

C:\TOOLS\SPARK
├───jdk-11.0.11+9
├───python-3.9.5
├───scala-2.12.14
├───spark-3.1.2-bin-hadoop3.2
└───winutils-master

調整と利用

環境設定用バッチファイルの作成

ファイルを置いただけなので、利用するためにはいろいろ設定する必要があります。

C:\tools\spark 配下に バッチファイルを一つ準備します。

enablespark.cmd
@ECHO OFF
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION

SET "SPARK_ROOT=%~dp0"
SET "SPARK_ROOT=%SPARK_ROOT:~0,-1%"

SET "JAVA_HOME=%SPARK_ROOT%\jdk-11.0.11+9"
SET "SCALA_HOME=%SPARK_ROOT%\scala-2.12.14"
SET "SPARK_HOME=%SPARK_ROOT%\spark-3.1.2-bin-hadoop3.2"
SET "HADOOP_HOME=%SPARK_ROOT%\winutils-master\hadoop-3.2.0"
SET "PYTHONHOME=%SPARK_ROOT%\python-3.9.5"

SET "PATH=%JAVA_HOME%\bin;%PYTHONHOME%;%PYTHONHOME%\Scripts;%SCALA_HOME%\bin;%SPARK_HOME%\bin;%HADOOP_HOME%\bin;%PATH%"

SET "PROMPT=(Spark 3.1.2) %PROMPT%"

REM SET PYSPARK_DRIVER_PYTHON=ipython.exe

CMD /K "ECHO Enable Spark on %SPARK_ROOT%"

ECHO Bye

ENDLOCAL

Spark環境にしたい場合は、CMD.exe等を起動して このバッチファイルを実行します。

実行するとプロンプトが変わります。

image.png

終わるときは exit してください。

Windows Terminal で Spark プロファイルの作成

私は Windows Terminalで使っているのでSpark用のプロファイルをこんな感じで登録しています。

image.png

※ この場合、先程のバッチファイルの最後に EXIT 0 を追加しています。

spark-shellの実行

この時点で Spark環境で Windows Terminalを開いて spark-shell が実行できます。pysparkはまだ動きません。

spark-shellを実行するとこんな感じになります。

image.png

port 4040で Web UIが起動するため、Windows Firewallなどが警告をあげてくるかと思います。
この許可には特権昇格して 管理者権限がどうしても必要になってしまうかもしれません。

最初に 5行ほど、盛大に出るWarningは JDK11を使っているためで、--illegal-access=permit がデフォルトのためです。
permitのため JVM起動後一回で 無視できますが、気持ち悪いので抑制したいところです。

それとプロンプトが出た後、しばらくすると WARN ProcfsMetricsGetter が出てきます。

さらに :quit で終了させると最後に盛大にワーニングが出ます。

Warningの抑制

Reflection

最初に出る Warningについてです。

いくつかのパッケージに対して Private Fieldに対する Reflectionを許可します。
SparkのJVM起動オプションを調整します。

cd C:\tools\spark\spark-3.1.2-bin-hadoop3.2\conf
copy spark-defaults.conf.template spark-defaults.conf

notepad spark-defaults.confで、最後に以下の数行を追加します。

spark.driver.extraJavaOptions      --add-opens java.base/java.lang=ALL-UNNAMED \
                                   --add-opens java.base/java.nio=ALL-UNNAMED \
                                   --add-opens java.base/java.util=ALL-UNNAMED \
                                   --add-opens java.base/java.util.concurrent=ALL-UNNAMED

作業によっては、これでも WARNINGが出るかと思います。その場合は更にパッケージを追加する等してください。

driverだけじゃなく、executorも同じ設定があります。
とりあえずLocalで触ってるだけなら影響ないので、ここでは設定していません。

ProcfsMetricsGetter

以下の箇所でprivateフィールドの初期化の瞬間にエラーが出てるみたいです。

Github ProcfsMetricsGetter.scala

Windowsには procfsはもちろん無いので、無視するというか、Log4Jで表示しないようにしてしまいます。

confの下の log4jテンプレートをコピーします。

cd C:\tools\spark\spark-3.1.2-bin-hadoop3.2\conf
copy log4j.properties.template log4j.properties

以下の二行を log4j.propertiesに追加します。

log4j.properties
# Disable logging for ProcfsMetricsGetter
log4j.logger.org.apache.spark.executor.ProcfsMetricsGetter=OFF

Setting default log level to "WARN"

ついでなので、最初に出ていた Default log level to "WARN"という表示も抑制します。
先ほどの log4j.properties を編集します。

log4j.properties
# Set everything to be logged to the console
log4j.rootCategory=INFO, console

↓ ここの INFOWARN に書き換えます。

log4j.properties
# Set everything to be logged to the console
log4j.rootCategory=WARN, console

終了時に大量に出る警告メッセージを抑制する

Sparkが Shutdownするタイミングで テンポラリディレクトリを削除しに行くのですが、
そのタイミングでロード済みの classファイル等はロックされているみたいで消せません。

ここだけは良い対応方法が分からず。
エラーの表示は抑制できるので、臭いものに蓋をします。

log4j.properties
# Disable logging for ShutdownHookManager
log4j.logger.org.apache.spark.util.ShutdownHookManager=OFF
#log4j.logger.org.apache.spark.SparkEnv=ERROR

2行目、コメントアウトしてありますが、同様に SparkEnv側をERRORまで落として
WARNINGを抑制する事が Googleで検索するとたくさん出てきます。

私が軽く触った範囲だと気にならなかったので コメントアウトして様子見しています。

なお、終了時に消したい物が消せないので
spark.repl.class.outputDir(%TEMP%\spark-*) フォルダに
毎度ファイルが残留する事になります。

通常これは %TEMP% 配下なので、ディスクのクリーンアップで消えると思います。
方法はどうあれ、%TEMP%\spark-... の定期的に削除する事が必要になるので注意してください。

定期削除を避ける

spark-shell起動時にバッチファイルで ユニークなフォルダを作って、
--conf spark.repl.class.outputDir=... で、そこを明示的に指定。
バッチファイルの最後でそこを消す。というやり方で問題回避できるかと思ってます。

今のところ、このやり方はCTRL+C等の影響受けるて、好きじゃないのでやってないです。

Warningを抑制した結果

だいぶすっきりしました。

image.png

PySparkの利用

PySparkが必要なら以下も行います。
まず、python-3.9.5\python39._pth ファイルを編集します。
このファイルは消さずに隔離モード1で使う形にしています。
PYTHONPATHを追加したい場合はこのファイルに書く様にしてください。

python-3.9.5\python39._pth
../spark-3.1.2-bin-hadoop3.2/python
../spark-3.1.2-bin-hadoop3.2/python/lib/py4j-0.10.9-src.zip
python39.zip
DLLs
Lib
Lib/site-packages
.

# Uncomment to run site.main() automatically
import site

python3.exe の作成

python.exeだけだと 一部で python3.exe を呼び出されてエラーになるので、
python.exe を python3.exe としてコピーしておきます。

cd C:\tools\spark\python-3.9.5\
copy python.exe python3.exe

pipの取得

pipぐらい無いとなぁと思ったので入れておきます。

pythonを使うので Spark環境で操作します。
Spark環境が立ち上がったら以下を実行します。

python -c "import urllib.request as r; r.urlretrieve('https://bootstrap.pypa.io/get-pip.py', 'get-pip.py')"
python get-pip.py
del get-pip.py

pip install pandas とかして インストールできれば問題無いと思います。

ポータブルに、と書きましたが、PIPについてはポータブルではないようです。
Scripts配下のpip.exeを調べると以下のようにパスが埋め込まれていました。

strings pip.exe | findstr /i python.exe
#!C:<get-pip.pyを実行したときのパス>\python.exe

このPython環境では モジュールが含まれていませんので venvは使えません。

一応、私の環境では Installer版のPythonから Lib/venvLib/ensurepipの二つをコピーして持ってくることでvenvも使うことができました。この二つはpipで持ってくることができないモジュールです。

IPython で PySparkを動かす

ipython を install します。

pip install ipython

その後 pysparkを起動するときに環境変数を設定します。

set PYSPARK_DRIVER_PYTHON=ipython.exe

起動するとこんな感じです。

image.png

テスト実行

テキストファイルの行数数えてみる

  1. 先ほどの方法で IPython を使って PySpark を起動する。
  2. lines = sc.textFile('適当なテキストファイル')
  3. lines.count()

これでテキストの行数が出てくるかと思います。wc -l の方が速いとか言わない(笑)。

image.png

円周率を計算

spark-submit --class org.apache.spark.examples.SparkPi spark-3.1.2-bin-hadoop3.2\examples\jars\spark-examples_2.12-3.1.2.jar 100

回数を変えて二回実行してみます。

image.png

まとめ

こんな感じで Windowsでも 環境をあまり変えずにSpark環境を作る事ができました。

フォルダを丸ごとコピーすれば環境を持ち運べるので わりと便利に使えるのではないかと思います。

VCのRuntimeだけはインストール必要ですが、Office入ってたりすれば 多分大丈夫。

まだ、サンプルを流したくらいで、そんなに使い込んでいません。
何か問題等あれば コメント等いただけると ありがたいです!

蛇足:話の発端

いままで会社から支給される PCは macをお願いしており、いろいろやるときはその上に LinuxをVMで立てて使っていました。

3月、会社PCの入れ替えがあったときに「たまにはWindowsにするか」と思って なんとなく変えてみました。これで次の入れ換えまで 3年間は Windowsです。

それと同じ頃、会社が Spot Waveという、Cloud上のSpark Cluster(Cluster ManagerはKubernetes)のインフラコストを最適化するというサービスを発表してました。

計画は以前からあったのと、ベースは Spot Ocean なので、「出てきたなー」というだけの感じだったのですが、つい5日ほど前に「DataMechanics買収しちゃうよ」というアナウンス。

こちらは SparkのUI/History サーバとしてDelightの開発・提供と、SparkのJob設定の自動チューニングをしてくれる物です。

シンプルに Spark Jobを Submitすれば、SparkのJobのパラメータを最適化してくれて、インフラもお得に準備してくれる。そんな環境を提供できるようになります。楽ちんそう(小並感)。

おぉ、弊社 Cloud上の Sparkに本気?2と思ったので、久しぶりに Spark 入れておくかと思ったのが発端です。

私の会社では PCの管理者権限を一応取得できるのですが、環境を汚したくないというのもあって今回こんな記事を書きました。

Spot Waveについては、また別の機会に。

  1. python39._pthを削除して、PYTHONPATHに Spark関連のモジュールのパスを追加するという方法も使えますが、レジストリ等の影響を予期せずに受けてしまい、ポータブルにならないなと思ってやってません。

  2. というか、Kubernetesには本気なので、その上で動く 1 ワークロードとして捉えているんだと思ってます。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?