Translate

2024年7月16日火曜日

AWS Glueジョブ(Python/Spark)にPythonパッケージを追加する方法

 AWS Glueジョブには2つの種類が存在します。

  • ETLジョブ(Spark)

PySparkコードが実行できるジョブ。
最低でも10並列で実行するので、DynamicFrame/DataFrame操作以外の処理はPython Shellジョブを使ったほうがよい。


  • Python Shellジョブ

通常のPythonコードを実行することのできるジョブ。



上記のジョブはともにAWSが提供する固定のコンテナイメージを使ってFaaSとして実行されます。なので、あらかじめ用意されたPythonパッケージがプリロードされた状態でコードを実行します。
コード内にプリロードされていないPythonパッケージを使う場合は、Pythonパッケージの導入を設定する必要があります。
 

AWS Glueのドキュメントにかかれている方法は以下のとおり

  • library-setを使う(Python Shell Python3.9ジョブのみ)

library-setというパラメータに"analytics"を指定すると、データ分析によく使われるパッケージがプリインストールされます(導入されるパッケージはドキュメントを参照してください)。このプリインストールパッケージで済む場合は、この方法を使ってください。

ただし、これはPython ShellジョブだけなのでETLジョブの場合は使用できません。



  • S3上にライブラリを配置してジョブから参照させる


ExtraPythonLibsS3Path/--extra-py-filesというパラメータを使うと、ジョブスクリプトファイル以外のPythonコードファイルを追加できます。このパラメータにファイルもしくはファイル群(Zip)をS3に置いて実行時参照させることができます。Zipではなくwhlファイルでも有効らしいのですが私はためしていません。そして重要なことは、純粋なPythonコードのみが対象になります。libxxxx.soなどのシェアードオブジェクトを使うPythonライブラリの場合Zipに含めても動作しませんでした(個人試行の結果です)。

ジョブ実行ロールにS3へのアクセス許可設定は必要です。


  • --additional-python-modulesを使ってPythonパッケージをpip installさせる


このオプションを使うとスクリプト実行前にpip installしてくれます。先程シェアードオブジェクトを含むzipがうまくいかないという場合は、こちらを試してみてください。ただし、AWS GlueジョブがIGW経由でPyPIにつながるVPC環境で実行される必要があります。PROXY指定しないとインターネットへ接続できない環境下のVPCの場合は失敗します。

AWS Glueジョブは公式ドキュメントどおりのセキュリティグループ設定をすると、接続するDBがある場合はそのDBがあるVPC内にコンテナが作られているかのような動作を行います。コンテナ自体のIPアドレスはAutoNumberになっていて、正直どのVPC傘下なのかわかっていませんが、おそらくAWS Glue用のプライベートVPCが暗黙にあって、そこでインスタンス化され、指定のセキュリティグループの許可する通信のみを実行するようです。そこで何も接続しない場合はよいのですがDB接続などを指定したジョブはそのDBにしかつながらなくなるようなのです。これも私個人の経験則ですけど..


  • Pythonジョブスクリプト内でpip installを実行する(Python Shellジョブのみ)


PROXY管理下のVPC環境などでpip installしたい場合は、スクリプトの中でpip install --proxy http://proxy.sample.com:8080 hogehogeするしかありません。

Python Shellジョブをlibrary-set:analyticsにして動かすとプリインストールパッケージにpipがあるので、このライブラリを使ってinstallします。


import pip

def pip_install(package:str, proxy_url=None) ->None:
    if hasattr(pip, 'main'):
        if proxy_url is None:
            pip.main(['install', package])
            #print('pip.main no_proxy')
        else:
            pip.main(['install', '--proxy', proxy_url, package])
            #print(f'pip.main proxy:{proxy_url}')
    else:
        if proxy_url is None:
            pip._internal.main(['install', package])
            #print('pip._internal.main no_proxy')
        else:
            pip._internal.main(['install', '--proxy', proxy_url, package])
            #print(f'pip._internal.main proxy:{proxy_url}')


pip_install('psycopg2-binary', 'http://proxy.sample.com:8080')



AWS Glueは提供側の想定がデータ分析が中心なので、ここまでして外部ライブラリをインストールしないといけない場合は、他の方法での実装が正しい解なのかもしれませんが..ご参考まで。

AWS Glueジョブ(Python/Spark)にPythonパッケージを追加する方法

 AWS Glueジョブには2つの種類が存在します。 ETLジョブ(Spark) PySparkコードが実行できるジョブ。 最低でも10並列で実行するので、DynamicFrame/DataFrame操作以外の処理はPython Shellジョブを使ったほうがよい。 Python...