このトピックでは、PySpark パッケージの複数のパッケージング方法について説明します。
概要
PySpark ジョブは通常、サードパーティ製ライブラリ(他の Python ライブラリ、プラグイン、プロジェクトなど)およびユーザー定義モジュールという 2 種類の Python リソースに依存します。MaxCompute クラスター上では Python ライブラリを直接インストールできないため、ローカルでパッケージを作成し、spark-submit を使用してアップロードする必要があります。
サードパーティ製ライブラリの管理:特定の依存関係を使用する場合、ローカルのパッケージング環境は本番環境と一致している必要があります。以下のいずれかの方法を使用してください。
追加のリソースは不要です。ただし、デフォルトの Python 環境のみが使用できます。
少数のシンプルな Python 依存関係が必要な場合にこの方法を使用します。
この方法では Docker を使用して複数の Python バージョンを提供します。requirements ファイルを読み取り、完全な Python パッケージを 1 ステップで生成します。
方法 5:Docker を使用して Python 環境をパッケージ化
任意の Python バージョンを選択できます。Docker は Linux 環境のみを提供します。最終的な Python 環境を MaxCompute リソースにアップロードする必要があります。
ユーザー定義モジュールの管理:これはユーザー定義の Python パッケージを参照することを意味します。
__init__.pyファイルを含むフォルダ全体を.zipファイルにパッケージ化します。これにより、ファイルを個別にアップロードおよび参照する手間を省けます。
方法 1:パッケージングせずにパブリックリソースを使用
spark-defaults.conf または DataWorks で構成を更新します。以下の例は、異なる Python バージョンのデフォルト環境構成を示しています。
Python 2.7.13
Python 2.7.13 のデフォルト環境構成です。サードパーティ製ライブラリの一覧を表示します。
spark.hadoop.odps.cupid.resources = public.python-2.7.13-ucs4.tar.gz
spark.pyspark.python = ./public.python-2.7.13-ucs4.tar.gz/python-2.7.13-ucs4/bin/pythonPython 3.6.12
Python 3.6.12 のデフォルト環境構成です。
spark.hadoop.odps.cupid.resources = public.python-3.6.12.tar.gz
spark.pyspark.python = ./public.python-3.6.12.tar.gz/python-3.6.12/bin/python3Python 3.7.9
Python 3.7.9 のデフォルト環境構成です。サードパーティ製ライブラリの一覧を表示します。
spark.hadoop.odps.cupid.resources = public.python-3.7.9-ucs4.tar.gz
spark.pyspark.python = ./public.python-3.7.9-ucs4.tar.gz/python-3.7.9-ucs4/bin/python3Python 3.11
spark.hadoop.odps.spark.alinux3.enabled = true方法 2:単一の WHL パッケージをアップロード
依存関係がシンプルな場合は、単一の WHL パッケージをアップロードします。manylinux バージョンを使用してください。WHL パッケージをダウンロードします。
WHL パッケージの拡張子を zip に変更します。たとえば、ダウンロードした PyMySQL の WHL パッケージを
pymysql.zipに名前変更します。DataWorks コンソールにログインし、左上隅でリージョンを選択します。
ワークスペースを選択するセクションで、DataStudio へ移動をクリックします。
左側のナビゲーションウィンドウで
アイコンをクリックします。次に
をクリックして MaxCompute アーカイブリソースを作成し、パッケージ化された pymysql.zipをアップロードします。DataWorks の Spark ノードを使用できます。
spark-defaults.confファイルまたは DataWorks に次の構成を追加します。spark.executorEnv.PYTHONPATH=pymysql spark.yarn.appMasterEnv.PYTHONPATH=pymysqlコード内でパッケージをインポートします:
import pymysql。
方法 3:pyodps-pack を使用して迅速にパッケージ化
多数のサードパーティPythonライブラリをパッケージ化し、特定のPythonバージョンに強く依存しないようにするには、pyodps-packツールを使用します。このツールはDockerを使用してパッケージング環境を提供します。このツールは、requirements.txtファイルからの依存関係のバッチ処理をサポートしています。次の例では、Python 3.11 を使用して pandas ライブラリをパッケージ化する方法を示します。詳細については、「Create and use third-party packages – PyODPS 0.12.4」をご参照ください。
Python バージョンのサポート:pyodps-pack は Python 3.8 ~ 3.14 をサポートします。
pyodps-packでパッケージ化# 開発環境で実行します。 pip install pyodps # Spark ジョブと同じ Python バージョンを使用します。Docker がまだインストールされていない場合は、インストールして実行します。 pyodps-pack pandas --python-version=3.11 -o pyodps-pandas.tar.gz # または requirements.txt ファイルを使用します。 pyodps-pack -r requirements.txt --python-version=3.11 -o pyodps-pandas.tar.gzodpscmd でパッケージをアップロード
add archive PATH/pyodps-pandas.tar.gz -f;ジョブ起動設定を構成
spark-defaults.confファイルを更新します。spark.hadoop.odps.cupid.resources = {your_project}.pyodps-pandas.tar.gz spark.executorEnv.PYTHONPATH = ./{your_project}.pyodps-pandas.tar.gz/packages spark.yarn.appMasterEnv.PYTHONPATH = ./{your_project}.pyodps-pandas.tar.gz/packages # ノートブックを使用する場合は、以下の行をスキップします。 # Spark バージョンを 3.4 または 3.5 に設定します。 spark.hadoop.odps.spark.version = spark-3.4.2-odps0.48.0 または spark.hadoop.odps.spark.version = spark-3.5.2-odps0.48.0 # Python 3.11 に切り替えます(オプション)。pyodps-pack で使用した Python バージョンと一致していることを確認してください。 spark.hadoop.odps.spark.alinux3.enabled = true
方法 4:スクリプトを使用して Python 環境を生成
多くのサードパーティライブラリをパッケージ化するには、個々の WHL パッケージをアップロードする反復的な作業 (メソッド 2) を行うのではなく、この自動パッケージングスクリプトを使用します。requirements ファイル (requirements ファイルガイドをご参照ください) を準備し、スクリプトを実行して、必要なすべての依存関係を含む完全な Python 環境を構築します。この環境は PySpark ジョブで直接使用できます。このメソッドは Python 2.7、3.5、3.6、および 3.7 をサポートしています。プロジェクトで特定の Python バージョンが不要な場合は、Python 3.7 を使用してください。
以下の手順に従ってください。
自動パッケージングスクリプトをダウンロードします。
このスクリプトは Mac および Linux で実行されます。事前に Docker をインストールしてください。「Docker ドキュメント」をご参照ください。
コマンドラインでファイルの権限を変更し、使用方法のヘルプを表示します。
$ chmod +x generate_env_pyspark.sh $ generate_env_pyspark.sh -h Usage: generate_env_pyspark.sh [-p] [-r] [-t] [-c] [-h] Description: -p ARG, the version of Python. Supported versions: 2.7, 3.5, 3.6, and 3.7. -r ARG, the local path to your requirements file. -t ARG, the output directory for the gz package. -c, clean mode. Packages only your specified dependencies. Does not include pre-installed dependencies. -h, display help for this script.-cオプションを指定すると、クリーンモードが有効になります。クリーンモードではプリインストール済みの依存関係を使用できませんが、結果として生成される Python パッケージのサイズが小さくなります。現在、MaxCompute ではアップロード可能なリソースの上限が 500 MB に設定されています。そのため、プリインストール済みの依存関係の大部分が不要な場合は、-cオプションを使用してコードをパッケージ化することを強く推奨します。各 Python バージョンのプリインストール済み依存関係の一覧は、以下のリンクから確認できます:Python 2.7 のプリインストール済み依存関係、Python 3.5 のプリインストール済み依存関係、Python 3.6 のプリインストール済み依存関係、Python 3.7 のプリインストール済み依存関係。パッケージ化コマンドの例
# プリインストール済みの依存関係を含めてパッケージ化します。 $ generate_env_pyspark.sh -p 3.7 -r your_path_to_requirements -t your_output_directory # プリインストール済みの依存関係を含めずにパッケージ化します(クリーンモード)。 generate_env_pyspark.sh -p 3.7 -r your_path_to_requirements -t your_output_directory -cSpark での使用方法
generate_env_pyspark.shは、指定されたディレクトリ(-t オプション)に指定された Python バージョン(-p オプション)用の gz パッケージを生成します。たとえば、Python 3.7 の場合、py37.tar.gzが生成されます。このパッケージをアーカイブリソースとしてアップロードできます。たとえば、odpscmdまたはodps-sdkを使用してパッケージをアップロードできます。リソースのアップロードに関する詳細については、「リソース操作」をご参照ください。# odpscmd で実行します。 add archive /your/path/to/py37.tar.gz -f;次に、
spark-defaults.confファイルまたは DataWorks に次の構成を追加します。spark.hadoop.odps.cupid.resources = your_project.py37.tar.gz spark.pyspark.python = your_project.py37.tar.gz/bin/python 上記の 2 つのパラメーターが有効にならない場合(たとえば、Zeppelin ノートブックで PySpark をデバッグする場合など)は、Spark ジョブに次の 2 つの設定項目を追加します。 spark.yarn.appMasterEnv.PYTHONPATH = ./your_project.py37.tar.gz/bin/python spark.executorEnv.PYTHONPATH = ./your_project.py37.tar.gz/bin/python
方法 5:Docker を使用して Python 環境をパッケージ化
以下のいずれかに該当する場合は、この方法を使用します。
依存関係に Python 以外のコードが含まれる場合:ライブラリに
.soファイルなどのバイナリファイルが含まれており、これらは単純なpip installコマンドや zip アップロードでは配布できません。カスタム Python バージョンが必要な場合:プロジェクトで特定の Python バージョン(たとえば Python 3.8)が必要であり、プラットフォームが提供するバージョン(2.7、3.5、3.6、または 3.7)ではない場合。
この方法では Docker を使用して環境をパッケージ化します。以下の例は、Python 3.8 環境を構築する方法を示しています。
Dockerfile を準備します。
Docker がインストールされたローカル開発マシンで、
Dockerfileという名前のファイルを作成します。ターゲット環境に応じて、以下のテンプレートのいずれかを選択します。Python 3.8 + Alibaba Cloud Linux 2
FROM alibaba-cloud-linux-2-registry.cn-hangzhou.cr.aliyuncs.com/alinux2/alinux2:latest RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo RUN curl -o /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo RUN set -ex \ # 必要なコンポーネントを事前にインストールします。 && yum clean all \ && yum makecache \ && yum install -y wget tar libffi-devel zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc make initscripts zip\ && wget https://www.python.org/ftp/python/3.8.20/Python-3.8.20.tgz \ && tar -zxvf Python-3.8.20.tgz \ && cd Python-3.8.20 \ && ./configure prefix=/usr/local/python3 \ && make \ && make install \ && make clean \ && rm -rf /Python-3.8.20* \ && yum install -y epel-release \ && yum install -y python-pip # Python 3 をデフォルトに設定します。 RUN set -ex \ # 古い Python バージョンをバックアップします。 && mv /usr/bin/python /usr/bin/python27 \ && mv /usr/bin/pip /usr/bin/pip-python27 \ # Python 3 をデフォルトとして構成します。 && ln -s /usr/local/python3/bin/python3.8 /usr/bin/python \ && ln -s /usr/local/python3/bin/pip3 /usr/bin/pip # Python バージョン変更による yum のエラーを修正します。 RUN set -ex \ && sed -i "s#/usr/bin/python#/usr/bin/python27#" /usr/bin/yum \ && sed -i "s#/usr/bin/python#/usr/bin/python27#" /usr/libexec/urlgrabber-ext-down \ && yum install -y deltarpm # pip をスペックアップします。 RUN pip install --upgrade pipPython 3.7 + Alibaba Cloud Linux 3
FROM alibaba-cloud-linux-3-registry.cn-hangzhou.cr.aliyuncs.com/alinux3/alinux3:latest RUN set -ex \ && yum clean all \ && yum makecache \ && yum install -y \ wget \ tar \ libffi-devel \ zlib-devel \ bzip2-devel \ openssl-devel \ ncurses-devel \ sqlite-devel \ readline-devel \ tk-devel \ xz-devel \ gcc \ make \ initscripts \ zip \ which RUN set -ex \ && wget https://www.python.org/ftp/python/3.7.17/Python-3.7.17.tgz \ && tar -zxvf Python-3.7.17.tgz \ && rm -f Python-3.7.17.tgz \ && cd Python-3.7.17 \ && ./configure --prefix=/usr/local/python3 \ --enable-optimizations \ && make -j$(nproc) \ && make install \ && make clean \ && cd / \ && rm -rf Python-3.7.17 \ && yum clean all RUN ln -sf /usr/local/python3/bin/python3.7 /usr/bin/python \ && ln -sf /usr/local/python3/bin/pip3 /usr/bin/pip # pip をスペックアップします。 RUN pip install --no-cache-dir --upgrade pipイメージをビルドし、コンテナを実行します。
Dockerfile を含むディレクトリで、以下のコマンドを実行します。
# 1. Docker イメージをビルドします(Python 3.8 の例)。 # -t は <image_name>:<tag> 形式でイメージに名前を付けます。 docker build --platform linux/amd64 -t python-centos:3.8 . # 2. バックグラウンドでコンテナを起動します。 # --name は参照しやすいようにコンテナに名前を付けます。 docker run --platform linux/amd64 -itd --name python3.8 python-centos:3.8 bashコンテナに入り、Python 依存関係をインストールします。
docker attach python3.8 pip install [required dependencies]Python 環境をパッケージ化します。
cd /usr/local/ zip -r python3.8.zip python3/Python 環境をコンテナからホストにコピーします。
Ctrl+P+Q を押してコンテナからデタッチします。 docker cp python3.8:/usr/local/python3.8.zip .python3.8.zip を MaxCompute リソースにアップロードします。
ローカルクライアント (odpscmd) を使用してファイルをアップロードします。アップロードタイプをアーカイブに設定します。コマンドの詳細については、「リソース操作」をご参照ください。
add archive /path/to/python3.8.zip -f;spark-defaults.confファイルまたは DataWorks 構成を更新します。Spark ジョブを送信する際に、
spark-defaults.confファイルまたは DataWorks に次の構成を追加します。spark.hadoop.odps.cupid.resources=[project_name].python3.8.zip spark.pyspark.python=./[project_name].python3.8.zip/python3/bin/python3.8
共有オブジェクト (.so) ファイルが不足している場合は、手動でそれらを Python 環境内にコピーします。その後、これらの環境変数を Spark 構成に追加します。.so ファイルは通常、コンテナ内にあります。
spark.executorEnv.LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./[project_name].python3.8.zip/python3/[so_file_directory]
spark.yarn.appMasterEnv.LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./[project_name].python3.8.zip/python3/[so_file_directory]ユーザー定義の Python パッケージを参照する
zip パッケージを作成します。
対象ディレクトリに空の
__init__.pyファイルを作成し、zip パッケージを作成します。cd /path/to/parent_dir touch __init__.py zip -r target_dir.zip target_dir/ 注意:相対パスを使用します。zip ファイルに親ディレクトリを含めないでください。展開時、target_dir.zip には parent_dir パスが含まれていてはなりません。zip パッケージをアップロードします。
オプション 1:DataWorks でアーカイブリソースとしてアップロードします。
オプション 2:odpscmd でアーカイブリソースとしてアップロードします。
add archive /path/to/python3.8.zip -f;
タスク内で zip パッケージを参照します。
オプション 1:DataWorks タスクノードのアーカイブリソースセクションで zip パッケージを追加します。
オプション 2:
spark-defaults.confファイルを更新します。spark.hadoop.odps.cupid.resourcesパラメーターを使用して zip パッケージを参照し、エイリアスを割り当てます。例: spark.hadoop.odps.cupid.resources=[project_name].target_dir.zip:target_dr 複数のリソースはカンマで区切ります。
タスクパラメーターを構成します。
spark-defaults.confファイルを更新します。タスクパラメーターを設定し、Python パッケージをインポートします。ファイルの場所が不明な場合は、「データ相互運用性構成」をご参照ください。アップロードされたパッケージの内部ディレクトリ構造を理解していることを確認してください。以下の例では、
./は現在の作業ディレクトリ/workdir/を意味します。PYTHONPATH環境変数および対応するimportパスを正しく設定します。## 1. 最初のケース:target_dir.zip の内部構造が target_dir.zip/sub/target_module であると仮定します。 spark.executorEnv.PYTHONPATH=./target_dir spark.yarn.appMasterEnv.PYTHONPATH=./target_dir # Python パッケージをインポートします。 from sub import target_module.xxx ## 2. 2 番目のケース:target_dir.zip の内部構造が target_dir.zip/target_module であると仮定します。 spark.executorEnv.PYTHONPATH=./ spark.yarn.appMasterEnv.PYTHONPATH=./ # Python パッケージをインポートします。 from target_module import xxx ## その他のケースも同様のパターンに従います。