AWSでのサーバレスアーキテクチャ入門 Lambdaの仕組みと使い方

サーバレスアーキテクチャ を使いこなすには、試行錯誤が必要である話をよく聞くが、彼らが提唱している ベストプラクティス (サーバではなくサービス) や、日々追加されるサーバレスアーキテクチャの新機能を見れば、AWSがサーバレスアーキテクチャに力を入れているのが伝わってくる(多分)

また コスト負荷の見直し密結合の解決 の観点でも、現代のシステム開発でサーバレスアーキテクチャの開発スキルは、必須となりそうな気がする(まだ市民権は得てないだろうけど)

ちなみに最近の新規開発案件では、Lambdaを取り入れるケースが増えているらしく、ただ魅力があったとしても、すぐ移行出来る簡単な技術ではない(従来とプログラミング方法や設計思想も随分違うため)ので、自分に使えそうかを理解するためにコチラを読んでみた。

本書のあらすじ

第1章 では、従来のシステム開発(EC2)との違いとLambda利用のメリットについて。

第2章 では、Lambda関数をどのような書式で作成し、登録するかをハンズオン形式で解説。

第3章 では、Lambdaの内部的な仕組みと、開発に欠かせない基礎知識。

第4章 〜 第6章 では、Lambda開発のユースケース(S3 / API Gatewat / DynamoDB / SES / SQS / SNSとの組み合わせ)が幾つか紹介(今回はほぼ割愛)

Lambdaで実現するサーバレスアーキテクチャ

AWSでのアプリケーション構築を行う場合、一般的にはEC2上でプログラムを動かすのが一般的だが、その運用には結構な手間やコストを要し、また性能上の問題 (最初に選択したインスタンスタイプは一時停止しないと変更出来ない)も併せて考慮しなければならないのは面倒。

POINTそういった手間を軽減する一つの手段が AWS Lambda であり、EC2のような仮想サーバーを必要とせず 実行時間に対しての課金なのでコスト削減効果を期待できる / マネージドサービスなので保守・運用が不要 / 高負荷時は自動的にスケーリング などの特徴がある!

ただ 2つの制限(①.ステートレス / ②.最大稼働時間5分) があるので、現時点では全てをサーバレスアーキテクチャで賄うのではなく、継続的に稼働する処理ではないもの(必要に応じて少しだけ動く)に限定して利用するのが主な用途 (2018年に15分に変更されたので複雑な処理も可能になった)

Webサイトの管理画面機能として、画像アップロード後にサーバー上に画像を格納すると、サムネイル画像を自動生成する機能があるが、Lambdaを使えば、S3アップロード時の自動生成処理を、簡単に作れる(本書の第4章では同内容が紹介されている)

またLambdaの呼び出しには、ファイルがS3に置かれたタイミングや、API Gatewayと組み合わせて、REST形式のWeb API (JavaScriptのAjax通信)で呼び出したり、CloudWatchでスケジューリングなど、Lambda自体が疎結合を実現させ、AWSサービス間の接着剤的な役割を担っている。

Lambda関数の作り方

第2章 では、簡単なLambda関数を作って実行するまでのハンズオン。

PythonではLambda関数を以下記述 (eventにリクエスト、contextに実行環境の情報)

本書ではPython3系 (Python 3.6)で解説されており、他言語の場合、微妙に書き方が異なるので、それぞれの言語に併せた書式を覚える必要有り!

Lambdaの仕組み

第3章 では、EC2と異なる性質を持つLamdbaの仕組みを知ることで、パフォーマンス低下を防いだり、同時実行時に期待した動きにならなかった際の対応方法を理解。

POINTLambda関数は Lambdaコンテナ (Linuxコンテナ環境) で動作し、実行時にコンテナ生成(EC2より起動時間は短く、必要なCPUリソースも少ない)するので、初回起動時に多少時間がかかり、二回目以降の実行では一度作成したコンテナを再利用し、高速化する仕組みが採用されている。

またLambdaはインターネットと接続可能なパブリック環境にあるので、デフォルトでプライベートなネットワークであるVPCと接続が出来ず、これを実現するためには、Lambda関数のVPCオプションを設定し、VPCの任意のサブネットに配置する構成とする必要有り(主にVPC内のRDSになるかと)

POINTただVPC接続だと 2つの制限 (①.起動時間がかかる / ②.同時実行性が落ちる) を考慮する必要があり、パフォーマンスに影響を及ぼすので、本書ではRDSよりもDynamoDBの利用を推奨 (理由として、DynamoDBならVPC接続が不要なので、パフォーマンス低下を多少軽減出来る)

リアルタイム性の考慮がいらなければ、一旦はLambda関数でDynamoDBにデータを格納し、そこから別のLambda関数でRDSに徐々に転送するよう構成すれば、直接RDSに書き込むよりもパフォーマンスが向上する事例を紹介 (Lambda関数の処理の多くがDynamoDBらしい)

Lambda関数呼び出しには2種類があり、特に利用頻度の高いプッシュモデル(非同期呼び出し)について、キューに溜まっているイベントを複数Lambdaが処理する可能性もあるので、何かしらの理由で実行時エラーが発生した場合、2回の試行(つまり初回を含めれば最大3回の実行可能性)が発生する。

POINTここでの 失敗 とは、Lambda関数呼び出し時の失敗だけでなく、処理中の例外が発生した場合も含み、また正常実行されても複数回実行されるケースも考えられるので、冪等性を考慮した作り (例えば前回実行したかのフラグを持たせ、フラグ判定を入れるとか)が大切。

API Gateway + Lambda + DynamoDB + S3

第5章 では主要なサービスとLambdaを活用した事例を紹介。

S3にホスティングされているWebサイトにて、ユーザーが入力した値をAPI Gatewayで経由させ、Lambda関数でDynamoDBに登録と、著名付きURLの発行 + SESでのメール送信を実現。

API Gateway は一種のプロトコル変換器であり、HTTPSプロトコルで送られてきたリクエスト値を受け取り、Lambda関数に渡し、Lambda関数からの戻り値をHTTPSプロトコルに変換して返却。

API Gatewayは重要サービスなので必須知識になっていると思う。

あとDynamoDBの活用について、ノウハウを収集した方が良さげだと感じた(Lambda利用では必須っぽいので) ただ実運用でのスループットと価格について、適切な読み込み・書き込みキャパシティーユニットの見極めは悩みどころなので、ホワイトペーパー等でノウハウ収集が必要になりそう。