Python AWS クラウド プログラミング

【Lambda】EFS経由でPythonライブラリを呼び出す方法

こんにちは、yassanです。
今回は、【Lambda】EFS経由でPythonライブラリを呼び出す方法を紹介します。

前回は、LambdaにEFSをマウントする方法を紹介しました。

これでEFSマウントはできたとして、
実際にPythonライブラリをEFS経由で呼び出す方法を紹介します。

PythonライブラリをLambdaで管理するには、LambdaLayerが適しています。
しかし、LambdaLayerには250MBのアップロード制限があります。
機械学習ライブラリなどは、250MBを超えることが多々あります。

今回は、Pythonのバージョンを3.8と想定して実行します。

Pythonライブラリの準備

まずは、EC2インスタンスを起動します。

EC2インスタンスにEFSをマウントするため、EFSと同じVPCでEC2インスタンスを起動します。

こちらのリンクを参考に、Python3.8の環境を構築します。
pipコマンドでpython3.8用のpipが動作するようになればそれでOKです。

次に、EC2インスタンスにEFSをマウントします。

対象のEFSのアクセスポイントの詳細を表示し、右上の[アタッチ]を押すとマウントするためのLinuxコマンドが表示されます。

このコマンドを利用して、EFSをマウントします。
実際には、このコマンドをコピペしただけでは動作せず、ファイルシステムIDとリージョンを入力する必要があります。

# mkdir ~/efs
# sudo mount -t nfs -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport fs-xxxxxxxxxxxxxxxxx.efs.ap-northeast-1.amazonaws.com:/   ~/efs
# mount
fs-xxxxxxxxxxxxxxxxx.efs.ap-northeast-1.amazonaws.com:/ on /root/efs type nfs4 (rw,relatime,vers=4.1,rsize=1048576,wsize=1048576,namlen=255,hard,noresvport,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=10.0.0.13,local_lock=none,addr=10.0.0.11)

コマンドを実行しても結果が返ってこない場合は、セキュリティグループで接続が許可されていない場合があります。
対象のEC2インスタンスからの接続を許可するように、セキュリティグループを変更すると接続できるようになります。

では、Pythonのライブラリをpipコマンドでインストールします。
といっても、実際にpip環境にインストールするのではなく、”-t”オプションをつけて指定のディレクトリに保存します。
今回は例としてchainerとその依存ライブラリをインストールします。

# mkdir work
# cd work
# mkdir chainer
# pip install -t ./chainer/ chainer
Collecting chainer
  Downloading chainer-7.8.1.tar.gz (1.0 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.0/1.0 MB 34.1 MB/s eta 0:00:00
  Preparing metadata (setup.py) ... done
Collecting setuptools
  Downloading setuptools-60.10.0-py3-none-any.whl (1.1 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.1/1.1 MB 18.0 MB/s eta 0:00:00
Collecting typing_extensions
  Downloading typing_extensions-4.1.1-py3-none-any.whl (26 kB)
Collecting filelock
  Using cached filelock-3.6.0-py3-none-any.whl (10.0 kB)
Collecting numpy>=1.9.0
  Using cached numpy-1.22.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (16.8 MB)
Collecting protobuf>=3.0.0
  Downloading protobuf-3.19.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.1 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.1/1.1 MB 21.5 MB/s eta 0:00:00
Collecting six>=1.9.0
  Using cached six-1.16.0-py2.py3-none-any.whl (11 kB)
Using legacy 'setup.py install' for chainer, since package 'wheel' is not installed.
Installing collected packages: typing_extensions, six, setuptools, protobuf, numpy, filelock, chainer
  Running setup.py install for chainer ... done
Successfully installed chainer-7.8.1 filelock-3.6.0 numpy-1.22.3 protobuf-3.19.4 setuptools-60.10.0 six-1.16.0 typing_extensions-4.1.1
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
# ls -all chainer
total 168
drwxr-xr-x 22 root root   4096 Mar 20 05:07 .
drwxr-xr-x  7 root root     80 Mar 20 05:07 ..
drwxr-xr-x  2 root root     46 Mar 20 05:07 bin
drwxr-xr-x 21 root root   4096 Mar 20 05:07 chainer
drwxr-xr-x  2 root root    157 Mar 20 05:07 chainer-7.8.1-py3.8.egg-info
drwxr-xr-x 10 root root    226 Mar 20 05:07 chainermn
drwxr-xr-x  3 root root    151 Mar 20 05:07 chainerx
drwxr-xr-x  3 root root     63 Mar 20 05:07 _distutils_hack
-rw-r--r--  1 root root    151 Mar 20 05:07 distutils-precedence.pth
drwxr-xr-x  3 root root    177 Mar 20 05:07 filelock
drwxr-xr-x  2 root root    118 Mar 20 05:07 filelock-3.6.0.dist-info
drwxr-xr-x  3 root root     22 Mar 20 05:07 google
drwxr-xr-x 19 root root   4096 Mar 20 05:07 numpy
drwxr-xr-x  2 root root    158 Mar 20 05:07 numpy-1.22.3.dist-info
drwxr-xr-x  2 root root    123 Mar 20 05:07 numpy.libs
drwxr-xr-x  5 root root    216 Mar 20 05:07 onnx_chainer
drwxr-xr-x  5 root root     73 Mar 20 05:07 pkg_resources
drwxr-xr-x  2 root root    117 Mar 20 05:07 protobuf-3.19.4.dist-info
-rw-r--r--  1 root root    539 Mar 20 05:07 protobuf-3.19.4-py3.8-nspkg.pth
drwxr-xr-x  2 root root     72 Mar 20 05:07 __pycache__
drwxr-xr-x  7 root root   4096 Mar 20 05:07 setuptools
drwxr-xr-x  2 root root    126 Mar 20 05:07 setuptools-60.10.0.dist-info
drwxr-xr-x  2 root root    102 Mar 20 05:07 six-1.16.0.dist-info
-rw-r--r--  1 root root  34549 Mar 20 05:07 six.py
drwxr-xr-x  2 root root     81 Mar 20 05:07 typing_extensions-4.1.1.dist-info
-rw-r--r--  1 root root 10768

依存ライブラリを含めない場合は、 ”--no-deps”オプションを使用すると、対象のライブラリだけインストールできます。

ライブラリごとに分けるのが面倒な場合は、通常通りpipコマンドでインストールして、site-packageを丸ごとEFSに移すこともできます。

インストールしたライブラリをディレクトリごとEFSにコピーします。
(EFSへのコピーには少し時間がかかります)

# cd ~
# mkdir ~/efs/data
# cp -rf ./work/chainer ./efs/data/

これで、Pythonライブラリ側の準備は完了です。

Lambda側の設定

Lambda側でも、EFSをマウントします。
EFSのマウント方法は、下記リンクをご参考ください。

マウントが完了したら、
ライブラリを呼び出せるようにパスを通す必要があります。

というわけで、パスを通すために環境変数を変更します。
変更する環境変数は、公式ドキュメントより”PYTHONPATH”であることは読み取れます。

[設定] > [環境変数] から、環境変数を追加します。
”PYTHONPATH”にライブラリを入れたパスを入力します。

複数のパスを通したい場合は、”:”で区切ることができます。
例 /efs/data/tensorflow:/efs/data/keras

環境変数 PYTHONPATH を変更した場合は、LambdaLayerが利用できなくなる可能性があります。

Lambda側の設定はこれで完了です。

実際に呼び出す

では、実際に呼び出してみます。

Lambda関数の初めに対象のライブラリをimportして実行します。

import json
import chainer

def lambda_handler(event, context):
    # TODO implement
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }
Response
{
  "statusCode": 200,
  "body": "\"Hello from Lambda!\""
}

実行が正常終了しました。

というわけで、EFS経由でPythonライブラリを呼び出す方法でした。

AWS学習におすすめの書籍

AWSについて、しっかりと基礎から学びたい、実践的なスキルを身につけたいと考えている方向けに、おすすめの書籍を紹介します。
これらの書籍は、実際にAWSエンジニアとして働く僕が参考にしている書籍です。

AWSエンジニア入門講座――学習ロードマップで体系的に学ぶ

AWSを使いこなすための前提となるITインフラの知識が足りない初学者にとって、どこからどのように学べばよいのかがわかりづらくなっています。そこで本書では、AWS学習サイト運営YouTuberである監修者自身が実サービスの導入で習得しながら体系化した「学習ロードマップ」に沿って、AWSのサービスとIT技術をやさしく解説していきます。

著者が作成した学習ロードマップに沿って、AWSやインフラストラクチャを体系的に学ぶことができます。
付属のロードマップの完成度が高く、学習に迷ったときや復習にも使えます。
これからAWSエンジニアを目指す方や、インフラストラクチャを基礎から学びたい方におすすめです。

Amazon Web Services 業務システム設計・移行ガイド

オンプレミス上に構築された業務システムをAWS上に移行するための「サービスの選定」「ネットワーク設計・構築」「サーバとデータの移し方」「運用・監視体制の構築」など。これまで多くの企業にAWSを導入し、コンサルティングフェーズから実際の設計・開発、運用フェーズまでの全行程に携わってきた著者陣のノウハウを凝縮して、一般的な企業にAWSを導入する際のベストプラクティスをお届けします。

実務を想定した様々なユースケースとそれに対するベストプラクティスを、設計構築から運用まで幅広くカバーして紹介しています。
タイトルからは移行に焦点を当てたように見えますが、僕としては移行に限らずエンタープライズとしてAWSを利用する上で知っておくべきことが記されていると思います。
より実践的な知識やノウハウを身に着けたい方、初学者から一皮むけたい方におすすめです。

-Python, AWS, クラウド, プログラミング