前回の記事に引き続き、Lambdaの仕様に悩まされた話です。
やろうとしたこと
今回開発した機能は、Excel形式の位置情報データを読み込み地図に表示する、というものです。データの表示に関しては、サーバ上のデータベースにデータを取り込めば自動的に地図に表示されるように既に作りこまれていたので、実作業としては、Excelファイルの内容をデータベースへ取り込む機能の実装でした。
今回は性能要件として、大きなデータサイズのExcelファイルにも対応する必要があるため、WebAPIでファイルアップロードのみを受け付け、インポート処理は前回実装したジョブ監視サービスの仕組みを流用し、バックグラウンドで実行されるように設計しました。アップロードされたExcelファイルは、Amazon S3を仲介してインポート処理に受け渡します。構成は以下の図の通りです。
実装は滞りなく完了しました。
開発環境で動作確認を行い、期待通り動作していることを確認できたので、検証環境のLambdaおよびEC2に各モジュールをデプロイ、動作を確認したのですが…インポートに失敗。はて…?
原因調査
ともかく原因を突き止めねばという事で、 まずはどこで躓いているのかを特定します。
- WebAPIのS3へのExcelファイルアップロード … OK
- インポート処理のS3からのExcelファイルダウンロード … OK
- Excelファイルを開く処理 … NG
S3からダウンロードしたファイルを開く処理でエラーが発生している様子。オープンソースのExcelライブラリを使用していたので、環境依存の不具合でもあるのか…?と思い、別のライブラリに差し替えてみたりしましたが、やはり同じところで躓きます。なんだか面倒なことになってきたな…
ああ、そういえばS3にアップロードされたファイルは大丈夫なのだろうか?
Excelファイルがどうやら破損しているようです。原因はこっちでしたか。でも、何故ファイルが破損してしまうのだろう?そういえば前にも似たような話が…ああ!
Lambdaでバイナリデータを扱う場合はBase64エンコード/デコードが必要になることを思い出しました。エンコードされたデータをそのままS3にアップロードしちゃってる…ってコト!?
再検討、そしてLambda利用断念
デコード処理を実装してやれば動くかな、と思ったのも束の間、Lambdaの別の問題にも気づきました。ペイロードのサイズ上限、AWSのドキュメントによると上限は6MBということで、要件に合いません。
Lambdaだとダメだ。諦めよう…
結局、Excelファイルのアップロードを含む一部のWebAPIをLambdaのプロジェクトから分離し、EC2上のWebサーバに配置することで問題を解消しました。
所感
Lambda関連でいろいろ苦労させられています。。。うまく使いこなせば便利なことは間違いないのですが。来月はバックエンド開発にAzureを採用したプロジェクトにアサインされる予定なので、いずれFaaSについてLambdaとAzure Functionsの比較をしてみたいと思います。