pandasをLambdaのLayerとして追加する

この記事は、ハンズラボ Advent Calendar 2018 12日目の記事です。

先日のAWS:reInventで発表されたLambdaLayerspandasのlayerを作成して、lambdaから使用していきたいと思います。


概要

今までではlambda関数ごとにパッケージし、デプロイしなければいけません。

共通で使用したい関数やライブラリはその都度パッケージの際にpipなどで入れる必要がありました。

numpypandasといったPure PythonでないライブラリはAmazonLinux環境でインストールしたファイルを使用してパッケージする必要があります。

実際、Lambdaを1つ作成する作業としては手間がかかります。

LambdaLayersにより共通で使用したい関数やライブラリをLayerに設定しておくことで、複数のLambda関数から呼び出すことができます。

すでにnumpyscipyを使用できるLayerをAWSが公開しています。


なんかひとつ足りなくね

numpy, scipyと来たらやっぱりpandasでしょ。(個人の意見)

とりあえずpandasの依存関係を確認します。

  - pandas [required: >=0.15.2, installed: 0.23.4]

- numpy [required: >=1.9.0, installed: 1.15.4]
- python-dateutil [required: >=2.5.0, installed: 2.7.5]
- six [required: >=1.5, installed: 1.11.0]
- pytz [required: >=2011k, installed: 2018.7]

こいつらをzipで固めてLambdaLayerにアップロードすればいいわけです。

ちなみに依存関係はpipdeptree確認しました。


zipファイルの作成

最初はdocker環境でインストールしてzipで固めようと思いましたが、結局EC2インスタンスを作成して行いました。Pythonのバージョンは3.6.5(pyenvでインストール)


  1. EC2インスタンスを作成(AmazonLinux)してsshで入る

  2. pyenvを入れる(参考)

  3. 以下のコマンドを実行

$ mkdir python

$ pip install -t ./python pandas
$ zip pandas.zip python

注意点:AmazonLinux2はなくAmazonLinuxで!(どうやらLambdaはAmazonLinuxで動いてるそうです)

最後に、EC2インスタンスから出て、ローカルから作成したpandas.zipscpでローカルにダウンロードすればOK。

また作る機会があると面倒なのでgithubにあげときました。(これをcloneしてきてもいいです。)


Layerの作成

AWSのコンソール画面→Lambda→Layersから作成をします。

スクリーンショット 2018-12-11 17.39.24.png

名前と説明を書いてzipファイルをアップロードします。

10 MB より大きいファイルの場合は、Amazon S3 を使用したアップロードを検討してください。

とありますが、10MBを超えていてもアップロードできました。(できない場合はS3にアップロードしてURLを入力してください)

ランタイムはPython3.6で。


関数を作成

スクリーンショット 2018-12-11 17.44.32.png

Lambdaのコンソール画面から関数を作成します。

ランタイムは先ほど作成したLayerと同じにしてください。ロールについては特別何も使用しないのでなんもでいいです。


Lambda

スクリーンショット 2018-12-11 17.50.31.png

とりあえずpandasDataFrameを作成して出力してみます。

import json

import pandas as pd

def lambda_handler(event, context):
data = {"year": [2010, 2011, 2012, 2013],
"pref":["千葉", "山口", "岐阜", "東京"]}

df = pd.DataFrame(data)
print(df)

# TODO implement
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}


Layerを追加する

スクリーンショット 2018-12-11 17.55.07.png

DesignerにあるLayersをクリックしてLayerを追加します。

スクリーンショット 2018-12-11 17.54.08.png

ランタイムと互換性があるレイヤーのリストから先ほど作成したLayerを選択します。バージョンは最新にします。(初めて作成したら1になります)

スクリーンショット 2018-12-11 17.59.06.png

こんな感じになっていればOK。


いざテスト

スクリーンショット 2018-12-11 18.02.24.png

ちゃんと出力されました。


いろんなことができそう

S3に入ってきたcsvファイルを処理して、S3に置き直したり、MySQLにいれたりといろんなことができそうです。

ServerlessFlameworkではすでにLayerのサポートがされているので今回作成した手順より楽かつ早く作成ができるかもしれません。

参考ページ:https://serverless.com/framework/docs/providers/aws/guide/layers/

ハンズラボ Advent Calendar 2018 明日13日目は@sr-mtmtです!