メインコンテンツへジャンプ

分散コンピューティング環境におけるアプリケーションの環境管理は難しい。 すべてのノードがコードを実行するのに必要な環境を持っていることを保証し、ユーザーのコードの実際の場所を決定することは、複雑なタスクである。 Apache Spark™は、Conda、venv、PEXなど様々な方法を提供している。 --jars、--packagesの ようなスクリプトオプションや、 spark.jars.*の ようなSparkコンフィギュレーションをサブミットする方法と 同様に、 PySparkでPythonの依存関係を管理する方法も併せて参照してみてください。これらのオプションにより、ユーザーはクラスタ内の依存関係をシームレスに処理できる。

しかし、Apache Sparkの依存関係を管理するための現在のサポートには限界がある。 依存関係は静的にしか追加できず、実行中に変更することはできない。 つまり、Driverを起動する前に必ず依存関係を設定する必要がある。 この問題に対処するため、Apache Spark 3.5.0からSpark Connectにセッションベースの依存関係管理サポートを導入した。 この新機能により、実行時にPythonの依存関係を動的に更新することができる。 このブログポストでは、Apache SparkのSpark Connectを使って実行時にPythonの依存関係を制御する包括的なアプローチについて説明する。

Spark Connectのセッションベースの成果物

スパーク・コンテキスト
One environment for each Spark Context

Spark Connectを使用せずにSpark Driverを使用する場合、Spark Contextがアーカイブ(ユーザー環境)を追加し、後にノード上で自動的に解凍され、すべてのノードがジョブを実行するために必要な依存関係を持っていることが保証される。 この機能により、分散コンピューティング環境における依存関係の管理が簡素化され、環境汚染のリスクを最小限に抑え、すべてのノードが意図した実行環境を確保できる。 しかし、これはSpark ContextとDriverを起動する前に静的に一度だけ設定することができ、柔軟性が制限される。

スパーク・セッション
Separate environment for each Spark Session

Spark Connectでは、コネクトサーバーの寿命が長くなり、複数のセッションやクライアント(それぞれが独自のPythonバージョン、依存関係、環境を持つ)が存在する可能性があるため、依存関係の管理がより複雑になる。 提案する解決策は、セッションベースのアーカイブを導入することである。 このアプローチでは、各セッションは専用のディレクトリを持ち、そこに関連するすべてのPythonファイルとアーカイブが保存される。 Pythonワーカーが起動すると、カレント作業ディレクトリはこの専用ディレクトリに設定される。 これによって、各セッションが特定の依存関係と環境のセットにアクセスできることが保証され、潜在的な競合が効果的に緩和される。

Condaの使用

Condaは、多くの人に利用されているPythonパッケージ管理システムだ。 PySparkユーザーはConda環境を直接活用して、サードパーティのPythonパッケージをパッケージ化できる。 これは、再配置可能なConda環境を作成するために設計されたライブラリであるconda-packを活用することで実現できる。

次の例は、セッションベースの依存関係管理を可能にするために、後でドライバとエクゼキュータの両方でアンパックされる、パックされたConda環境の作成を示している。 この環境は、Pythonインタプリタと関連するすべての依存関係をキャプチャして、アーカイブファイルにパックされる。

import conda_pack
import os

# 現在の環境('pyspark_conda_env')を'pyspark_conda_env.tar.gz'にパックする。
# シェルで 'conda pack' を実行することもできる。

conda_pack.pack()
spark.addArtifact(
 f"{os.environ.get('CONDA_DEFAULT_ENV')}.tar.gz#environment",
 archive=True)
spark.conf.set(
 "spark.sql.execution.pyspark.python""environment/bin/python")

# 以降、エクゼキュータ上の Python ワーカーは `pyspark_conda_env` Conda
# 環境を使用します。

PEXの使用

Spark ConnectはPEXを使ってPythonパッケージをバンドルすることをサポートしている。 PEXは、自己完結型のPython環境を生成するツールである。 Condaやvirtualenvと同様の機能を持つが、.pexファイルはそれ自体が実行可能ファイルである。

次の例では、.pexファイルは、ドライバとエクゼキュータの両方が各セッションで使用するために作成される。 このファイルには、pexコマンドで提供される指定されたPython依存性が組み込まれる。

# 現在のenvをpyspark_pex_env.pex'にパックします。
pex $(pip freeze) -o pyspark_pex_env.pex

.pexファイルを作成した後、セッションが分離された.pexファイルを使用するように、セッションベースの環境にそれらを送ることができる。

spark.addArtifact("pyspark_pex_env.pex",file=True)
spark.conf.set(
 "spark.sql.execution.pyspark.python""pyspark_pex.env.pex")

# 以降、エクゼキュータ上の Python ワーカーは `pyspark_conda_env` venv 環境を使用します。

Virtualenvの使用

Virtualenvは、隔離されたPython環境を作成するためのPythonツールである。 Python 3.3.0から、 その機能のサブセットは、venvモジュールの下で標準ライブラリとしてPythonに統合されている。 venvモジュールは、conda-packと同様の方法でvenv-packを使うことで、Pythonの依存関係に活用できる。 以下の例は、venvによるセッションベースの依存関係管理を示している。

import venv_pack
import os

# 現在のvenvを'pyspark_conda_env.tar.gz'にパックする。
# シェルで 'venv-pack' を実行することもできる。

venv_pack.pack(output='pyspark_venv.tar.gz')
spark.addArtifact(
 "pyspark_venv.tar.gz#environment",
 archive=True)
spark.conf.set(
 "spark.sql.execution.pyspark.python""environment/bin/python")

# 以降、エクゼキュータ上の Python ワーカーはあなたの venv 環境を使います。

まとめ

Apache Sparkは、Apache Spark 3.5.0において、実行時に動的にSpark ConnectによるPython依存関係の送信と管理を容易にするために、Conda、virtualenv、PEXを含む複数のオプションを提供している、 これは静的なPythonの依存関係管理の限界を克服するものです。

Databricksノートブックの場合、この問題に対処するために、Pythonの依存関係のためのユーザーフレンドリーなインターフェイスを備えた、よりエレガントなソリューションを提供します。 さらに、ユーザーはPythonの依存関係管理のためにpipとCondaを直接利用することができる。 Databricksの無料トライアルで、これらの機能を今すぐご利用ください。

Databricks 無料トライアル

関連記事

Apache Spark™ 3.5のご紹介

翻訳:Junichi Maruyama. - Original Blog Link 本日、Databricks Runtime 14.0の一部として、Databricks上でApache Spark™ 3.5が利用可能になったことを発表いたします。Spark 3.5のリリースに多大な貢献をしていただいたApache Sparkコミュニティに深く感謝いたします。 Sparkをこれまで以上にアクセスしやすく、多用途で効率的なものにするという我々のミッションに沿った今回のアップデートには、以下のような新機能と改良が盛り込まれています: The English SDK for Apache Spark enables users to...
エンジニアリングのブログ一覧へ