AWS Step Functionsとは ― Lambdaとの違いと再試行
複数の
AWS Step Functionsとは、処理の順番とやり直しをまとめて管理するサービス
注文の受付・在庫確認・決済・通知をLambdaでつなぐと、途中で失敗したときのやり直しが複雑になります。AWS Step Functionsは、こうした処理の順番・分岐・再試行を定義にまとめるサービスです。各処理は、その定義どおりに動きます。
関数どうしが直接呼び合う作りでは、再試行のコードや進み具合の記録を関数ごとに持つことになります。Step Functionsに任せると、関数には自分の処理だけを書けば済みます。構成図でLambdaの隣にStep Functionsの箱があるときは、Lambdaを動かす順番をそこで決めています。
Lambdaの実行時間は1回15分までなので、長い処理を分けたいときにも使います。まず、ステートの種類とLambdaとの分担を説明します。続いて、RetryとCatchの書き方、StandardとExpressの選び方を取り上げます。
ステートマシンは、ステートをつないだ処理の流れ
Step Functionsでは、処理の流れ全体をステートマシンと呼びます。ワークフローも同じものを指します。流れの中の1つ1つの段階がステートです。ステートマシンを1回動かしたものは、実行と呼びます。
同じステートマシンは、複数の実行を同時に動かせます。注文が10件入れば、同じ定義のまま10個の実行が並んで進みます。それぞれの実行はJSONの入力を受け取り、JSONの出力を返します。
実行の始め方はいくつかあります。コンソールやAPIから始めるほか、Amazon EventBridgeのルールやスケジュールからも始められます。Webからのリクエストで始めたいときは、Amazon API Gatewayを前に置きます。
次の図は、注文を処理するステートマシンの例です。起きることを選ぶと、その実行が通るステートと矢印に色が付きます。定義は1つのままで、実行ごとに通る経路が変わります。
- 在庫を
確認する Lambdaが 動きます。 - Choiceが、
在庫が ある 側を 選びます。 - 決済の
Lambdaが 1回で 成功します。 - メールを
送る Lambdaが 動きます。 - Succeedで
実行が 終わります。
実行の
- 在庫を
確認する Lambdaが 動きます。 - Choiceが、
在庫が ない 側を 選びます。 - Failで
実行が 終わります。 決済の Lambdaは 動きません。
実行の
- 在庫を
確認する Lambdaが 動きます。 - Choiceが、
在庫が ある 側を 選びます。 - 決済の
Lambdaが 一時的な エラーを 返します。 Retryの 設定どおりに 3秒待って 同じ ステートを やり直すと、 2回目で 成功します。 - メールを
送る Lambdaが 動きます。 - Succeedで
実行が 終わります。
実行の
- 在庫を
確認する Lambdaが 動きます。 - Choiceが、
在庫が ある 側を 選びます。 - 決済の
Lambdaが 失敗します。 Retryで 3回やり直しても 失敗します。 - Retryを
使い切ると、 Catchに 書いた 在庫を 戻すステートへ 移ります。 - Failで
実行が 終わります。
実行の
ステートの種類は、処理を実行するTaskと流れを決める7種類
処理を実行するステートはTaskです。残りの7種類は、分岐や待ち時間など、流れそのものを決めます。前の図では、四角い箱がTaskで、両端のとがった箱がChoiceです。
| ステート | する | 例 |
|---|---|---|
| Task | 1つの | 決済の |
| Choice | 入力の | 在庫の |
| Parallel | 複数の | 住所と |
| Map | 配列などの | 注文の |
| Wait | 指定の | 翌朝まで |
| Pass | 入力を | 既定の |
| Succeed | 実行を | 注文を |
| Fail | 実行を | 在庫切れの |
Parallelでは、枝の1つでも失敗すると、Parallelのステート全体が失敗します。Taskが呼べるのはLambdaだけではありません。200を超えるAWSサービスのAPIを呼べます。そのため、DynamoDBへの書き込みやSNSへの発行は、関数を作らずに書けます。
ステートマシンの定義は、Amazon States Languageで書きます。JSONをもとにした言語で、略してASLと呼びます。コンソールでは、定義をステートのつながった図として確かめられます。
Lambdaとの違いは、処理を書くか順番を決めるか
Lambdaは、サーバーレスで処理を動かすサービスです。Step Functionsは、処理を動かす順番を管理するサービスです。どちらかを選ぶ関係ではなく、組み合わせて使います。在庫確認や決済の中身をLambda関数に書き、順番と失敗したときの扱いをステートマシンに書きます。
| 比べる | Lambda | Step Functions |
|---|---|---|
| 書く | 処理の | 順番・分岐・再試行の |
| 実行時間の | 1回15分 | Standardは |
| どこまで | 作る | Standardは |
| 料金の | リクエスト数と | Standardは |
Step Functionsを使っても、1つのLambda関数の上限は1回15分のままです。15分を超える処理は、段階ごとの関数に分けてつなぎます。
Lambdaにも、複数の手順を再試行つきで最長1年動かせるdurable functionsがあります。こちらは流れをプログラミング言語のコードで書き、Lambdaの中で動かします。使い分けについて、AWSのガイドは次のように勧めています。Lambdaが中心ならdurable functions、複数のAWSサービスをつなぐならStep Functionsです。
エラー処理は、Retryで再試行し、Catchで別の流れへ移す
何も書かないと、1つのステートのエラーで実行全体が失敗します。これを変えるのがRetryとCatchで、Task・Parallel・Mapのステートに書けます。Retryは同じステートをやり直す設定で、Catchは別のステートへ移る設定です。両方を書くと先にRetryを試し、解決しなければCatchへ移ります。
前の図の決済のステートは、ASLでは次のように書けます。Typeがステートの種類で、Nextが次のステートです。ResourceはLambdaを呼ぶ指定で、FunctionNameに動かす関数を書きます。
"Pay": {
"Type": "Task",
"Resource": "arn:aws:states:::lambda:invoke",
"Parameters": {
"FunctionName": "arn:aws:lambda:ap-northeast-1:123456789012:function:pay",
"Payload.$": "$"
},
"TimeoutSeconds": 30,
"Retry": [{
"ErrorEquals": ["States.TaskFailed"],
"IntervalSeconds": 3,
"MaxAttempts": 3,
"BackoffRate": 2
}],
"Catch": [{
"ErrorEquals": ["States.ALL"],
"Next": "RestoreStock"
}],
"Next": "SendMail"
}この定義では、最初の再試行まで3秒待ち、待ち時間を2倍ずつ延ばして3回やり直します。IntervalSecondsが最初の待ち時間で、MaxAttemptsがやり直す回数、BackoffRateが倍率です。省略すると、待ち時間1秒・回数3回・倍率2.0になります。
ErrorEqualsには、対象にするエラーの名前を書きます。States.TaskFailedは、タイムアウト以外のエラーに一致します。States.ALLは、残りのエラーをまとめて受けるときに最後に書きます。ただし、States.Runtimeのように一致しないエラーもあります。
Retryを書くと、同じ処理が複数回動きます。決済のように二重の実行が問題になる処理では、同じ注文を二度処理しないよう関数の側で防ぎます。Standardの実行が失敗で終わっても、14日以内なら失敗したステップから再開できます。この機能をredriveと呼びます。成功済みのステップはやり直しません。
タイムアウトを書かないと、応答を待ち続けることがある
TaskのTimeoutSecondsは、そのステートが動いてよい最大の秒数です。超えるとStates.Timeoutのエラーになり、RetryやCatchの対象にできます。ステートマシン全体にも、同じ名前の項目で上限を書けます。
APIを呼んですぐ次へ進むTaskには、既定のタイムアウトがあります。一方で、ジョブの完了や外部からの通知を待つTaskには既定のタイムアウトがありません。応答が来なければ、実行の上限まで待ち続けます。AWSのベストプラクティスも、Taskごとに妥当なタイムアウトを書くよう勧めています。
StandardとExpressの違いは、長く確実に動かすか、短く大量に動かすか
ステートマシンを作るときは、ワークフローの種類をStandardかExpressから選びます。既定はStandardで、作成後は変更できません。長く動き、1回だけ確実に実行したい処理にはStandardが向きます。短い処理を大量に回すならExpressが向きます。
| 比べる | Standard | Express |
|---|---|---|
| 実行時間の | 1年 | 5分 |
| 実行の | 1回だけ。 | 非同期は |
| 料金の | 状態遷移の | 実行回数と、 |
| 実行の | APIと | CloudWatch Logsへの |
| 完了の | 使える | 使えない |
| 向く | 決済や | IoTデータの |
Expressには非同期と同期の2つの動かし方があります。非同期は開始の確認だけを返します。同じ実行が2回以上動くことがあるので、2回動いても結果が変わらない処理に使います。同期は、終わるまで待って結果を返します。途中でエラーになっても、その実行をやり直しません。
人の承認を待つ処理はStandardで作ります。Standardなら、タスクトークンという識別子が返ってくるまでTaskを止めておけます。Expressはこの待ち方を使えず、実行も5分までなので、数日待つ処理は作れません。2つを組み合わせる形もあります。AWSのベストプラクティスが挙げる例では、決済や承認をStandardに残します。在庫の更新のようにやり直せる処理は、Expressに切り出します。
Step Functionsが向く場面と向かない場面
次のような処理に向きます。
- 注文処理のように、順番どおりに進み、途中で分岐や再試行がある処理
- 人の承認や外部のシステムの完了を待ち、数時間から数日かかる処理
- 複数のサービスを順に呼ぶ処理。マイクロサービスの間の流れもここに入ります
- どのステップまで進んだかを、あとから確かめる必要がある処理
次のような処理には別の方法が合います。
- 1つの関数で終わる処理は、Lambdaだけで足ります
- 処理の依頼をためておき、あとで順に片付けるだけなら、Amazon SQSのキューで足ります
- 同じ通知を複数の相手に配るだけなら、Amazon SNSのトピックで足ります
SQSとの違いは、進み具合を誰が持つかにあります。Step Functionsは、各ステップの状態を記録します。SQSで流れを作ると、進み具合の管理はアプリの側に残ります。
大きなデータの受け渡しには注意が要ります。ステートの入出力の上限は256 KiBなので、大きなデータはAmazon S3に置き、場所だけを渡します。Standardの1回の実行の履歴にも25,000件の上限があり、超えると実行が失敗します。
料金は、Standardが状態遷移の回数、Expressが実行回数と時間で決まる
Standardの料金は、状態遷移の回数で決まります。状態遷移は、ワークフローのステップを実行するたびに数える回数です。Retryのやり直しも1回ずつ加わります。無料枠は月4,000回で、12か月の無料期間が過ぎても続きます。
AWSの料金ページには、米国東部(バージニア北部)で1回$0.000025の例があります。開始と終了を含めて4回遷移するワークフローを月10万回動かすと、40万回です。無料枠を引いた396,000回分で、月$9.90になります。
Expressの料金は、実行の回数と実行時間で決まります。実行時間は100ミリ秒単位で切り上げ、使ったメモリは64 MB単位で数えます。どちらの種類でも、呼び出したLambdaなどの料金は別にかかります。単価は2026年10月31日に確認した値です。最新の値はAWSの料金ページで確認してください。
参考にした資料
- AWS「What is Step Functions?」(ステートマシン・ステート・実行の定義、呼び出せるサービス)
- AWS「Choosing workflow type in Step Functions」(StandardとExpressの違い、実行の保証)
- AWS「Discovering workflow states to use in Step Functions」(ステートの種類)
- AWS「Using Amazon States Language to define Step Functions workflows」(定義の書き方)
- AWS「Parallel workflow state」(枝が失敗したときの動き)
- AWS「Starting state machine executions in Step Functions」(実行の始め方、JSONの入出力)
- AWS「Handling errors in Step Functions workflows」(RetryとCatch、エラーの名前、既定値)
- AWS「Task workflow state」(タイムアウトの既定)
- AWS「Discover service integration patterns in Step Functions」(完了の通知を待つ呼び出し、人の承認)
- AWS「Best practices for Step Functions」(タイムアウトの指定、大きなデータの渡し方、Expressとの組み合わせ)
- AWS「Restarting state machine executions with redrive in Step Functions」(失敗したステップからの再開)
- AWS「Step Functions service quotas」(入出力の大きさと実行履歴の上限)
- AWS「Durable functions or Step Functions」(Lambda durable functionsとの選び方)
- AWS「AWS Step Functions Pricing」(課金の単位、無料枠、計算の例)
- AWS「AWS Step Functions FAQs」(Lambda・SQSとの関係)
練習問題(全4問)
正解:Lambdaに
処理の
正解:実行全体が
Step Functionsの
正解:先に
Step Functionsは、
正解:Standard。
数日の
選んでから「採点する」を押すと、解説つきで答え合わせができます。