環境変数の利用
DBへの接続情報など環境変数から設定するようにしたいケースが発生しそうなので調査しました。
いずれもドライバプログラム内でしか利用できません。つまりworkerノード(リモート)で利用するためには一旦変数に格納してアプリケーションコード内で参照するような工夫が必要ですのでご注意ください。
方法1:initialization-actionsで自前スクリプトを実行する
initialization-actionsで自前のスクリプトを実行して、その中で環境変数を設定するというとても原始的な方法です。この方法だと変数の内容をファイルに記載して、GCSにアップロードしなくてはならないので正直使えないと思っています。
-
まず、クラスター作成時に
initialization-actions
オプションで指定するスクリプト(initialize.sh)を実装するecho "export HOGE=xxx" | tee -a initialize.sh
-
ドライバプログラム(main.py)を実装する
import os import pyspark hoge = os.getenv('HOGE')
-
実装したファイルをGCSにアップロードする
gsutil cp initialize.sh gs://hoge/ gsutil cp main.py gs://hoge/
-
クラスタを作成する
-
--initialization-actions
で作成したinitialize.sh
を指定しているgcloud dataproc clusters create hoge-gluster --initialization-actions='gs://hoge/initialize.sh'
-
-
ジョブを実行する
gcloud dataproc jobs submit pyspark --cluster=hoge-gluster gs://hoge/main.py
方法2:spark-env.shで環境変数を設定する(推奨)
--properties
でspark-env:HOGE=XXX
のように指定しておくと、spark-env.sh
はその内容を読み込んで環境変数HOGE=XXX
を設定してくれます。これが一番スタンダードな方法だと思います。
- ドライバプログラム(main.py)を実装する
import pyspark import os sc = pyspark.SparkContext() hoge = os.getenv('HOGE') :
- 実装したファイルをGCSにアップロードする
gsutil cp main.py gs://hoge/
- クラスターを作成する
-
--properties
オプションで、spark-env
プレフィックスをつけて、環境変数を設定するgcloud dataproc clusters create hoge-gluster --properties="spark-env:HOGE=xxx,spark-env:FUGA=yyy"
-
- ジョブを実行する
gcloud dataproc jobs submit pyspark --cluster=hoge-gluster gs://hoge/main.py
方法3:spark-defaults.confに設定を追加する
こちらは環境変数ではないのですが、--properties
でspark:HOGE=XXX
のように指定しておくと、spark-defaults.conf
にその内容が記載され、設定情報としてプログラム内から参照できます。
- ドライバプログラム(main.py)を実装する
import pyspark sc = pyspark.SparkContext() hoge = sc.getConf().get('HOGE')
- 実装したファイルをGCSにアップロードする
gsutil cp main.py gs://hoge/
- クラスターを作成する
-
--properties
オプションで、sparkのexecutorEnvを指定しているgcloud dataproc clusters create hoge-gluster --properties="spark:HOGE=xxx,spark:FUGA=yyy"
-
- ジョブを実行します
gcloud dataproc jobs submit pyspark --cluster=hoge-gluster gs://hoge/main.py
別フォルダのpythonファイルをimport
残念ながら別フォルダのpythonファイルをimportする方法はなさそうです。
hoge.py
models
┗fuga.py
のようなフォルダ構成で、hoge.py
では、以下のようにでfuga.py
をimportするケースを試しました。
from models import fuga
これをDataProcで実行すると、以下のように ImportError: No module named models
というエラーが発生します。
gcloud dataproc jobs submit pyspark \
--cluster=hoge-cluster \
--files='gs://hoge-bucket/models/fuga.py' \
gs://hoge-bucket/hoge.py
> Traceback (most recent call last):
> File "/tmp/987eqbkewqvf0uh9qet43/hoge.py", line 9, in <module>
> from models import grants
> ImportError: No module named models
これは、結局--files
で指定したファイルは、元のフォルダ構成に関係なく実行ファイル(hoge.py)と同じテンポラリフォルダに展開されて実行されるためです。
なので
try:
from models import fuga
except ModuleNotFoundError:
import fuga
とすると、ローカルPC上でも、クラスタ上でもエラーは発生しなくなります。