こんにちは!
Lambda 関数でメッセージの受け渡しをする場合、SQSを使っていますか?それとも Step Functions を使っていますか?
今回はいまいちどっちを使えばいいのかわからない方に向けて解説していこうと思います。ぜひ参考にしてください!
SQS とは AWS が提供するマネージドなメッセージキューイングサービスです。対して Step Functions はサーバーレスオーケストレーションサービスという位置付けで、様々な AWS リソースを組み合わせてワークフローを構築・可視化できるものです。
Lambda + SQS の組み合わせはサーバーレスなアーキテクチャでよく見られますが、Lambda + Step Functions の組み合わせは活用されていますでしょうか?ふたつのユースケースを見て、目的にあったサービスを選定していきましょう!
先に結論を申し上げますと、以下のようになります。
どちらもサーバーレスなサービスではありますが、スケーラブルな要件に対応しているのは SQS です。また疎結合なアーキテクチャを組む上では欠かせないサービスとなっております。
対して、Step Functions はそもそもサーバーレスに特化したオーケストレーションサービスです。各ステップでどういった処理を行っているのかを可視化したり管理が容易になったりすることで、サーバーレスアーキテクチャにおいてありがちな全体像が見えにくい状態を解決してくれるマネージドサービスとなります。
なお Step Functions 内で SQS も利用できますが、今回は Lambda などを用いたサーバーレスなロジックを組む際に、どちらを選ぶべきかといった内容になりますので、そこに注目して話をしていきます。
SQS のユースケースとして最も最適なのは、スパイクアクセスが発生しやすいアプリです。SQS は高可用性で非同期に処理を行うスケーラブルなサービス、それに加え耐久性があるのでメッセージの内容を十分に保護することができます。
例えば投票アプリを構築する際、どのくらい集中的にアクセスが来るのか読みづらい場合があります。そのときに最適なコストでインフラを調達するのは難しいでしょう。そういった場合は SQS を利用することで、スパイクアクセスによるデータの損失を防ぎ、かつ最適なコストでアプリケーションを動かせることができます。
またサーバーレスやマイクロサービスなアーキテクチャを実現するため、サービス間に SQS を置くことがあります。これによりリソースを効率的に使いこなし、メッセージを安全に送受信できるので、ぜひクラウドネイティブなアプリケーションの場合は採用することをおすすめします。
Step Functions は同期ワークフローや長時間実行されるワークフローなどの場合に利用するのがよいでしょう。AWS Fargateをワークフローに組み込むことによって、Lambda では処理しきれないものにも対処することができます。
またリアルタイムなワークフローにも向いております。Step Functions には2種類のワークフローを選択できるのですが、リアルタイムに向いている Express ワークフローを利用することで、IoT データの取り込みやストリーミングデータ処理などを実現できます。
そしてなんといっても Step Functions の魅力は、複数のサービスがどのように繋がってどのように動いているのかが可視化および管理されている点です。これによりサーバーレスなアーキテクチャの全体像が把握しやくなるため、管理者としてもメリットが多いでしょう。
SQS と Step Functions は、サーバーレス製品という共通点がありますが、前者と比べて後者はオーケストレータであるため、必然的に CloudFormation テンプレートが長くなってしまいます。実際に比較してみましょう。
SQS
Resources:
Queue:
Type: AWS::SQS::Queue
Properties:
QueueName: TestQueue
VisibilityTimeout: 30
RedrivePolicy:
deadLetterTargetArn: !GetAtt DeadQueue.Arn
maxReceiveCount: 1000
DeadQueue:
Type: AWS::SQS::Queue
Properties:
QueueName: TestQueue-dead
Step Functions
Resources:
StateMachine:
Type: AWS::StepFunctions::StateMachine
Properties:
DefinitionString: !Sub |
{
"Comment": "AWS Step Functions Example",
"StartAt": "SendMessage1",
"Version": "1.0",
"States": {
"SendMessage1": {
"Type": "Task",
"Resource": "${FunctionSendMessage.Arn}",
"Retry": [{
"ErrorEquals": ["States.TaskFailed"],
"IntervalSeconds": 2,
"MaxAttempts": 16,
"BackoffRate": 2
}],
"Next": "Wait1"
},
"Wait1": {
"Type": "Wait",
"Seconds": 3,
"Next": "SendMessage2"
},
"SendMessage2": {
"Type": "Task",
"Resource": "${FunctionSendMessage.Arn}",
"Retry": [{
"ErrorEquals": ["States.TaskFailed"],
"IntervalSeconds": 2,
"MaxAttempts": 16,
"BackoffRate": 2
}],
"End": true
}
}
}
- {lambdaArn: !GetAtt LambdaFunction.Arn}
RoleArn: !GetAtt StatesExecutionRole.Arn
上記の通り、あきらかに記述量が異なります。これは Step Functions のテンプレートにステートの定義(つまりロジック)を記述しないといけないからです。
SQS の場合だと、SQS を用意したあとに Lambda 側でターゲットなどを指定すればいいのですが、Step Functions の場合だとロジックを記述する必要があります。
一見手間に見えますが、これによりサーバーレス製品によって行われるロジックを可視化することができるので、管理は楽になるかと思います。
もちろん、複雑なロジックになればコード量が増えますが、CloudFormation のテンプレートを見るだけで、何と何を使ってどういうことをしているのかが把握しやすいので、記述量が少ないのが SQS、可読性が高いのは Step Functions のほうになります。
いかがでしたでしょうか?ぜひ今回ご紹介したユースケースを参考に選定してみてください。両方ともサーバーレスなアーキテクチャの恩恵をたっぷり受けられる素晴らしいサービスなので、こういったものは積極的に取り入れていきたいですね。
このブログでは、AWS の記事をどんどん公開しておりますので、ご興味のある方は他の記事もご覧いただければと思います。
AWS に関する開発は、お気軽にお問い合わせください。