1. 背景・対象
ローカル環境でcondaを使ってpysparkを動かすためのメモ。
他の一般的なPythonライブラリと同じような感じでpysparkをインストール・実行する。
想定する主な対象:
- 細かい設定は置いておいて、少ない手順でとにかく動く環境を作りたい
- SparkやJavaのバージョンを仮想環境毎に分けて管理したい
- PC本体で使うJavaとSparkで使うJavaを区別したい
- Spark2.4とSpark3.0を使い分けたい(あるいはプロジェクト毎に区別してSparkをインストールしたい)
- でもDockerや仮想マシンなどは使いたくない
といった状況を考えています。
2. condaでSparkとJavaをインストール
対象とするconda仮想環境に入って、
- Apache Spark3.0を使う場合
conda install -c conda-forge pyspark=3.0 openjdk=8
- Apache Spark2.4を使う場合
# 注意:Python3.8は未対応なのでPython3.7.xなどの環境を使う
conda install -c conda-forge pyspark=2.4 openjdk=8
とすると、pysparkライブラリだけでなくApache Spark本体も仮想環境下にインストールされます。(ちなみにpandasや、pandasとSpark間のデータ連携を担うpyarrowなども一緒に入ります)
ここまででとりあえずpyspark
が使える状態になっているはずです。
ちなみに、上の例のようにcondaでopenjdkを入れると、conda activate
で仮想環境に入ったときにJAVA_HOME
をcondaで入れたものに合わせて自動で良い感じに設定してくれます。(conda-forgeチャンネルから入れる場合、2020-08-14現在でバージョンは1.8.0_192 (Azul Systems, Inc.)になります。)
実行
conda activate <仮想環境名>
してからCLI上で
- Spark3
$ pyspark
Python 3.8.5 (default, Aug 5 2020, 08:36:46)
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
20/08/14 22:00:15 WARN Utils: Your hostname, <***> resolves to a loopback address: 127.0.1.1; using 192.168.3.17 instead (on interface wlp3s0)
20/08/14 22:00:15 WARN Utils: Set SPARK_LOCAL_IP if you need to bind to another address
20/08/14 22:00:15 WARN NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Using Spark's default log4j profile: org/apache/spark/log4j-defaults.properties
Setting default log level to "WARN".
To adjust logging level use sc.setLogLevel(newLevel). For SparkR, use setLogLevel(newLevel).
Welcome to
____ __
/ __/__ ___ _____/ /__
_\ \/ _ \/ _ `/ __/ '_/
/__ / .__/\_,_/_/ /_/\_\ version 3.0.0
/_/
Using Python version 3.8.5 (default, Aug 5 2020 08:36:46)
SparkSession available as 'spark'.
>>>
- Spark2
$ pyspark
Python 3.7.7 (default, May 7 2020, 21:25:33)
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
20/08/14 22:16:09 WARN Utils: Your hostname, <***> resolves to a loopback address: 127.0.1.1; using 192.168.3.17 instead (on interface wlp3s0)
20/08/14 22:16:09 WARN Utils: Set SPARK_LOCAL_IP if you need to bind to another address
20/08/14 22:16:09 WARN NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Using Spark's default log4j profile: org/apache/spark/log4j-defaults.properties
Setting default log level to "WARN".
To adjust logging level use sc.setLogLevel(newLevel). For SparkR, use setLogLevel(newLevel).
Welcome to
____ __
/ __/__ ___ _____/ /__
_\ \/ _ \/ _ `/ __/ '_/
/__ / .__/\_,_/_/ /_/\_\ version 2.4.6
/_/
Using Python version 3.7.7 (default, May 7 2020 21:25:33)
SparkSession available as 'spark'.
>>>
のようにしてそれぞれでpyspark
が使えることを確認出来ます。
- condaで仮想環境を用意して
conda install
しただけなので、他の普通のPythonライブラリと同じ感覚でpysparkをインストール・実行出来ています。
補足(Java)
なお、Spark3からはJava11も対応しているのですが、簡単に試してみたところメモリ関係のエラーが出るとかで満足に動かせていないです。。。
ここなどを見てもJava11を使う場合は追加で設定が必要そうですし(上述のエラーとは違いそうな気もしますが)、タイトルの通りに「手軽にとりあえず」で動かす場合はSpark3でもJavaのバージョンは8が無難だと思います。(なお、Spark2系ではJava8でないと動かないです。)
補足(Windows)
そこそこの機能は上の通りで動きますが、spark.sql
のデータベース・テーブル操作をするときなどにデフォルトでは権限周りのエラーが起きます。
ここなどを参考にして、
を追加でやっておく必要があります。
3. 追加で設定が必要な場合
ここまでで簡易的に(デフォルトの設定で)pysparkを実行出来るようになっているはずですが、ときにはconfigの設定や調整をしなくてはならないときがあります。
本格的にカスタマイズをしていくとタイトルの「手軽に」の範囲を超えてしまいますが、最低限のところだけ補足します。
(一般的な環境変数の設定など、condaで入れた場合に特有でない共通した話は省きます。)
SPARK_HOME
の設定
環境変数JAVA_HOME
(Sparkの実行に必要)は勝手にconda側で設定してくれると書きましたが、Apache Sparkを使う際によく設定する環境変数SPARK_HOME
は実は設定されていません。(未設定でも割と動きますが、たまに困るときがある)
仮想環境上でのインストール場所を指定すれば良いのですが、若干場所が分かりづらいです。
やり方は色々あると思いますが、個人的に使う調べ方として、
- condaでpysparkをインストールすると
scala
のSparkシェルであるspark-shell
も実行可能(PATHも通っているはず)なので、CLI上でspark-shell
を実行する -
sc.getConf.get("spark.home")
と打ってEnterを押すと出てくる文字列を取得して環境変数SPARK_HOME
に設定する
例えば、以下のような感じになります:
$ spark-shell
20/08/16 12:32:18 WARN Utils: Your hostname, <***> resolves to a loopback address: 127.0.1.1; using 192.168.3.17 instead (on interface wlp3s0)
20/08/16 12:32:18 WARN Utils: Set SPARK_LOCAL_IP if you need to bind to another address
20/08/16 12:32:19 WARN NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Using Spark's default log4j profile: org/apache/spark/log4j-defaults.properties
Setting default log level to "WARN".
To adjust logging level use sc.setLogLevel(newLevel). For SparkR, use setLogLevel(newLevel).
Spark context Web UI available at http://192.168.3.17:4040
Spark context available as 'sc' (master = local[*], app id = local-1597548749526).
Spark session available as 'spark'.
Welcome to
____ __
/ __/__ ___ _____/ /__
_\ \/ _ \/ _ `/ __/ '_/
/___/ .__/\_,_/_/ /_/\_\ version 3.0.0
/_/
Using Scala version 2.12.10 (OpenJDK 64-Bit Server VM, Java 1.8.0_192)
Type in expressions to have them evaluated.
Type :help for more information.
scala> sc.getConf.get("spark.home")
res0: String = <仮想環境のPATH>/lib/python3.8/site-packages/pyspark
# ↑ `String = `の部分にSparkのインストール場所の絶対パスが表示される
# `Ctrl-C`で抜けて、以下のように環境変数を設定
$ export SPARK_HOME=<仮想環境のPATH>/lib/python3.8/site-packages/pyspark
または、
- 同様に
spark-shell
を実行する - ローカルで動かす想定なので、1.の後で http://localhost:4040 にアクセスしてSpark UIを開く
- (sshなどでリモートで動かしている場合はlocalhost部分を適宜置き換えるなどする )
- Environmentタブの
spark.home
にあるパスを控えて、環境変数SPARK_HOME
に設定する
などとやります。(ここを参考にした方法です。)
例えばSPARK_HOME=/path/to/miniconda3-latest/envs/<仮想環境名>/lib/python3.7/site-packages/pyspark
みたいな感じになります。
要するにscalaのspark-shellではSparkSession内においてのみ自動で適切なspark.home
を設定してくれているのですが、何故かpysparkではやってくれないのでspark-shellを使って調べる、といった感じです。
設定ファイルの場所
公式などからダウンロードしてきたSparkにはconf
ディレクトリが存在しますが、condaで自動インストールしたものにはconf
ディレクトリが存在しないようです。。。
が、自分で然るべき場所にconf
ディレクトリを作って設定ファイルを置けば読み込んでくれるようです。(spark-defaults.conf
で検証)
設定ファイルの置き場所は先程調べたSPARK_HOME
のパスを使って、$SPARK_HOME/conf/
下になります。
そこで、例えば
$SPARK_HOME/conf/spark-defaults.conf
を作成・記入していくことでconfigの設定が可能です。
※SPARK_HOME
未設定でも読み込んでくれたので、上記読み込みに環境変数SPARK_HOME
は必須でないようです。
他の設定ファイル(例えばconf/spark-env.sh
など)は試していませんが、おそらく同じような感じで作成・記入すれば動くのではないかと思います。(違っていたらすみません。)
condaで入れた個別のパッケージに手を加えるのは可搬性が落ちて設定が汚くなる(タイトルの「手軽に」の要素が薄れてくる)ので、個人的にはそこまで好きなやり方では無いです。
(必要だったら出来る、という話です。)
ただ、それでも仮想環境毎に設定を独立させて保持出来るメリットは残ると思います。
3. (補足)
stackoverflowにある程度近いケースでの環境設定の話があったので、参考リンクとして記載
まとめ
condaでpysparkを手軽にインストール・管理出来ることと、その気になれば設定ファイルのカスタマイズなども可能なところまで確認した。