忙しい人へ
結論とまとめを最初にのせときます
結論
Djangoのようなフルスタックフレームワークではあまり良いとは言えない
フルスタックフレームワーク使うならECSを使った方が良いらしい
まとめ
Lambdaのコールドスタートで時間かかるのでは?
結構かかります
DjangoのプロジェクトをLambdaにアップロードしたら、Lambdaのアップロードサイズ制限に引っかかるのでは?
かかる可能性はあります
ただよほど入れなければ大丈夫なはず
REST APIを作る時に、DjangoのルーティングとAPI Gatewayの組み合わせって相性悪くね?
実害はないと思うけど悪いと思います
Django使うってことはサーバーレスなのにサーバー立ち上げるってこと?
その通りです
前置き
この記事はあくまでも私見です
これが絶対正しいということではないのでご了承ください
前提
zappaというデプロイツールを用いての検証
本題
LambdaとDjangoの組み合わせにした時の疑問点がいくつかあった
その疑問点をひとつづつ考えてみた
疑問点
- Lambdaのコールドスタートで時間かかるのでは?
- DjangoのプロジェクトをLambdaにアップロードしたら、Lambdaのアップロードサイズ制限に引っかかるのでは?
- REST APIを作る時に、DjangoのルーティングとAPI Gatewayの組み合わせって相性悪くね?
- Django使うってことはサーバーレスなのにサーバー立ち上げるってこと?
Lambdaのコールドスタートで時間かかるのでは?
Lambdaのコールドスタート
- ENIの作成(LambdaにVPC設定した時に限る)
- 実行コンテキストの起動
- デプロイパッケージの読み込み
- デプロイパッケージの展開
- ランタイムの起動と初期化
- 関数の実行
調査
今回はVPC設定なしで、コールドスタートの時間を調べたいので2~5までの時間を調べる
Djangoのプロジェクトと生のPythonのプロジェクトを用意
※DjangoのプロジェクトではzappaとDRFを導入
プログラムの内容はLambda実行時に「Hello world」をJSONで返す
これらをマネージドコンソールから実行してCloudWatchで処理時間を確認する
Djangoのパッケージサイズは42.2MB
生Pythonのパッケージサイズは129B
Lambdaに割り当てたメモリはどちらも512MB
####結果
(msで表記)
回数 | Django | 生Python | 差分 |
---|---|---|---|
1 | 3073 | 4 | 3069 |
2 | 3159 | 3 | 3156 |
3 | 3173 | 3 | 3170 |
4 | 3190 | 3 | 3187 |
5 | 3196 | 4 | 3192 |
デプロイパッケージのサイズによってコールドスタートにかなり影響があることが分かった
Lambdaはなるべく最小限のパッケージをアップロードすることが好ましいのでフルスタックフレームワークを使用するのは相性が悪そう
DjangoのプロジェクトをLambdaにアップロードしたら、Lambdaのアップロードサイズ制限に引っかかるのでは?
Lambdaのパッケージサイズの上限
50 MB (zip 圧縮済み、直接アップロード)
250 MB (解凍、レイヤーを含む)
いろいろライブラリを突っ込んでたら制限にかかりそう
REST APIを作る時に、DjangoのルーティングとAPI Gatewayの組み合わせって相性悪くないか?
実際にプログラムを動かす上で実害はない
だが、あまり筋の良いやり方だとは思えなかった
本来APIGateway + LambdaでREST APIを作成した時の処理の流れは
- APIGatewayでURLを指定
- 指定したURLと紐づくLambdaを呼び出す
- 処理
になると思う
Djangoを使用するとなると、Djangoで設定したURLに合わせることになる
処理の流れとしては
- APIGatewayはどんなURLが来ても同じLambdaを呼び出す
- Lambdaが起動したらまずDjangoのサーバーを立ち上げる
- DjangoのサーバーがURLを受け取りルーティングする
- URLに紐づいたDjangoのViewを実行
という流れになるため非常に筋が悪い
なのであまり相性が良いとは言えない
Django使うってことはサーバーレスなのにサーバー立ち上げるってこと?
そういうことになる
GitHubでzappaのLambda処理を見てみると
- Django動かす準備
- URLの取得
- Djangoのサーバー起動
みたいな感じだった
サーバーレスなのにサーバー立ち上げる処理が入るから違和感を感じた
その他
検証中に思ったこととかをここに書いときます
- RDSとLambdaって相性よくなかった気がする
- ただ2020年7月にRDS Proxyがリリースされたからかなり解消されてるかも?
- LambdaとDjangoの事例がなさすぎる
- 開発で詰まった時に調べても、ドキュメントがないから解決にかなり時間かかりそう
- zappaでRDS使おうと思ってmysqlclient入れてzappaのコマンドでマイグレーションしたら死ぬほどエラー出た
- zappaのコマンド使わずにマイグレーションしたら普通に通ったからzappaの問題?
- ライブラリによって使えないものがあると困るので結構致命的
- そもそもLambdaの実行時間制限15分・パッケージサイズ250MBまでなど、制限があるので一つのLambdaにいろんな処理をさせるのは不向きなのでは?
結論
Djangoのようなフルスタックフレームワークではあまり良いとは言えない
フルスタックフレームワーク使うならECSを使った方が良いらしい
まとめ
Lambdaのコールドスタートで時間かかるのでは?
結構かかります
DjangoのプロジェクトをLambdaにアップロードしたら、Lambdaのアップロードサイズ制限に引っかかるのでは?
かかる可能性はあります
ただよほど入れなければ大丈夫なはず
REST APIを作る時に、DjangoのルーティングとAPI Gatewayの組み合わせって相性悪くね?
実害はないと思うけど悪いと思います
Django使うってことはサーバーレスなのにサーバー立ち上げるってこと?
その通りです