[レポート] API304 Amazon SQSとLambdaを使ったスケーラブルでサーバレスなイベント駆動アプリケーション #reinvent

はじめに

横田あかりです。AWS re:Invent2019にてセッション API304 「Scalable Severless Event-Driven Applications Using Amazon SQS & Lambda」を聴講してきたのでレポートします。

セッションの概要は下記になります。

Event-driven integration patterns emerged to enable integration between serverless applications at scale. Join this session to learn best practices for integrating serverless applications using Amazon Simple Queue Service (Amazon SQS) triggers. We dive deep into the architecture of Amazon SQS triggers to AWS Lambda and how it was engineered to autoscale your Lambda functions. Explore how to tune Lambda and Amazon SQS to scale your existing applications without having to worry about provisioning capacity.

スピーカーは下記のお二人です。

  • Rory Richardson - Global Head of Business Development - Serverless, Amazon Web Services
  • Luay Kawasme - Sr. Manager, Software Development, Amazon SQS, Amazon Web Services

レポート

  • アジェンダ
    • SNSを用いたメッセージのフィルタ
    • Lambda非同期プッシュ vs Amazon SQS
    • Amazon SQSの拡張機能
    • イベントソースとしてのAmazon SNSとAmazon SQS
    • Amazon SQSからLambdaへ

はじめに

このセッションでは、Amazon SQSとLambdaを用いた設計のパターンについて紹介しています。また、他のサービスや機能との比較について詳しく説明していますので、頭の中を整理するために良いセッションだと思います。

AirBnBの例

まずは、顧客事例から。外部システムや他SaaSなどの様々なソースから取得したデータは、KinesisやS3を経由して分析アプリケーションへと渡されます。データ到着のイベントフックでLambdaが起動しますが、ここで同期処理を行わずに疎結合にします。ここでSQSの登場です。昔は、SQSの後ろにワーカーとなるEC2を置くことが多かったですが、今はLambdaを指定することができますので、サーバレスで非同期処理を実現しています。また、異なるワークロードについては更に疎結合処理として、Kinesis Firehoseを経由してS3にデータを繋いでいます。S3では、データ到着のイベントフックでSQSにデータが格納され、後続のLambdaで過去データからの集計や検索を行っています。できるだけ同期処理をしないことと、サーバを用いないことで、安価に耐障害性や可用性を上げているように見えました。

SNSを用いたメッセージのフィルタ

SNSにはフィルタ機能があります。別のシステムから呼び出される単一のSNSエンドポイントに様々な種類のメッセージが飛んでくるとします。ここで、後続の処理を振り分けるためにSNSのフィルタ機能を用いて、それぞれ別のSQSに繋いでいます。あるSQSキューはシンプルな処理のためLambdaを置き、あるSQSキューは複雑な処理のためEC2を置くなどです。このように、SQSメッセージをどのように処理したいかで後続のサービスを切り替えることは設計パターンとしてあります。

Lambda非同期プッシュ vs Amazon SQS

Amazon SQS+Lambdaの組み合わせは、とても良い設計パターンですが、Lambda単体でも非同期処理できる機能があります。ここでは、これらの違いについて紹介していました。とりあえずサクッと簡単に非同期処理をするのであれば、Lambdaの非同期呼び出しでも良いと思いましたが、実際のビジネス運用を考えると、様々なチューニングやメトリクスの確認をしたくなると思います。多少の追加コストは掛かりますが、SQS+Lambdaは設計パターンとして強力です。

  • Lambda 非同期呼び出し
    • 単体のサービス内で実現
    • オートスケール
    • バッチ処理は無し
    • シンプルなDLQ(デットレターキュー)ポリシー
    • バックログの可視化はできない
    • 特別なキューの設定はできない
    • 追加コストは掛からない
  • Amazon SQS + Lambda
    • 2つのサービスを繋げて実現
    • オートスケール
    • バッチ処理のサポート
    • 拡張DLQポリシー
    • CloudWatchメトリクス
    • SQSの機能をフル活用できる
    • SQSの従量課金

Amazon SQSの拡張機能

  • SQSの拡張機能
    • 拡張DLQポリシー
    • バッチ処理のサポート
    • メッセージの遅延処理
    • 顧客管理の鍵によるサーバサイド暗号化
    • メッセージ保持期間の設計
    • メッセージ属性
    • CloudWatchメトリクス
    • メッセージ消去操作

イベントソースとしてのAmazon SNSとAmazon SQS

Amazon SNSとLambdaの組み合わせは、低遅延でシンプルに使う場合は有効です。SNSに飛んでくるメッセージのスループプットに対して、後続の処理が受けきれるのであれば、SNS+Lambdaで問題ありません。逆に言うと、右から左に問答無用でメッセージを渡しまくるので、受けきれない場合には問題が発生しますね。

イベントソースとして、SNSとSQSは、どちらも拡張性や耐障害性を持っています。メッセージの消費モデルとして、SNSは同じメッセージを全配信(fanout)し、SQSは購読して削除します。回復力として、SNSは1回のみ配信されて、何か問題発生時にやり直しはできません。SQSは、処理が正しく完了したときのみ削除するなどの処理を指定することができ、失敗した場合にはキューに戻して再実行することができます。リトライについては、SNSは13時間保持し、SQSは最大で14日間保持します。全体的に、SQSのほうが、システム間を疎結合に繋げることができ、より全体の動きをコントロール可能なサービスとなっています。

Amazon SQSからLambdaへ

  • TIPS
    • 低い同時実行と高い処理遅延の場合は、表示タイムアウト設定(VisibilityTimeout)を配信遅延の5倍にすることで、DLQとカウント取得の再実行を回避できます。
    • 重複実行を回避するために、常に配信遅延よりも表示タイムアウト設定が大きいことを確認してください。
    • わずかなエラーであったとしても、後続の処理に負担を掛けてしまい、同時実行性を損なう可能性があります。
    • 呼び出し回数自体はスループットと同じではありませんし、最大バッチ処理は保証されません。

以下はSQSの設定画面例です。

  • まとめ
    • Amazon SQSとLambdaを併せて用いることで、システム全体を疎結合にし、全体の耐障害性や可用性を上げられることがわかりました。
    • Amazon SQSの前段にSNSを置くことで、フィルタ結果に応じたキューに振り分けられることがわかりました。
    • Amazon SQSのキューの種類によって、LambdaやEC2などの処理サービスを自由に組合わせることがわかりました。
    • Amazon SQSとLambda非同期処理の違いを認識し、SQSがより高機能であることがわかりました。
    • CloudWatch、DLQ、サーバサイド暗号化など、より実際の運用で必要となる機能についてご紹介しました。

感想

Amazon SQSとLambdaの相性の良さをよく理解できました。次は処理の結果から状態を関するStep Functionsへの活用へとつなげていきたいと思います。