Upgrade to Pro — share decks privately, control downloads, hide ads and more …

AWS Step Functions 大規模並列の壁を越える / jaws-sonic-202...

AWS Step Functions 大規模並列の壁を越える / jaws-sonic-2026-niigata-step-functions

2026/9/5 (土) - 9/6 (日) 開催の「JAWS SONIC 2026」にて登壇した資料。

イベントページ
https://jawssonic2026.jaws-ug.jp/timetable/niigata

Avatar for kasacchiful

kasacchiful PRO

September 05, 2026

More Decks by kasacchiful

Other Decks in Programming

Transcript

  1. 自己紹介 笠原 宏 (@kasacchiful) クラスメソッド株式会社 データ事業本部 ビジネスソリューション部 ソリューションアーキテクト 新潟県新潟市在住 JAWS-UG新潟

    / Python機械学習勉強会 in 新潟 / JaSST Niigata / ASTER / SWANII / Cloudflare Meetup Niigata / AI CRAFT Hacks Niigata / KomeKaigi AWS Community Builder (Serverless) 2022, 2025 Japan AWS Top Engineer / 2022-2026 Japan All AWS Certifications Engineer AWS Samurai 2025 2
  2. クイズ Lambda を呼んで、Choice で判定して、まだなら戻る。 それだけのループです。 Standard ワークフロー (ステートマシン) の最大実行時 間は1年です。

    さて、Lambda関数は何回ループ実行され るでしょうか? A. 約25,000回 B. 約5,000回 C. 約3,500回 D. 上限なし(1年動き続ける) 4
  3. 最大実行イベント履歴 25,000 イベント Standard Express 最大実行時間 1年 5分 最大実行履歴サイズ 25,000イベント

    無制限 イベント履歴の上限を超えるとステートマ シンの実行が失敗します 上限解放不可 (ハードクォータ) Express は無制限 履歴を Step Functions 側に持たず CloudWatch Logs で持つため https://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/service-quotas.html 7
  4. イベント履歴 24,999 からの挙動 公式ドキュメントより AWS Step Functionsの実行イベント履歴には 25,000 エントリのハードクォータがあり ます。実行イベントが

    24,999 件に達すると、次のイベントが発生するまで待機しま す。 イベント番号 25,000 が ExecutionSucceeded の場合、実行は正常に終了します。 イベント番号 25,000 が ExecutionSucceeded 以外の場合、ExecutionFailed イベント はログに記録され、履歴の上限に達したためステートマシンの実行は失敗します。 https://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/sfn-best-practices.html 8
  5. 状態遷移と実行イベント {% $count < $iterations %} 状態遷移 実⾏イベント Start Pass

    state Task state (Lambda Invoke) Choice state ExecutionStarted PassStateEntered TaskStateEntered ChoiceStateEntered PassStateExited LambdaFunctionScheduled ChoiceStateExited Succed state End ExecutionFailed LambdaFunctionStarted LambdaFunctionsSucceeded TaskStateExited ループは Lambda関数実行のTaskステートとChoiceステートを順に繰り返したので、 1ループあたり「2つの状態遷移」/「7つの実行イベント」が発生。 Starndardワークフローの課金対象は「状態遷移数」(今回は 7145 ) なので、実行イベントは あまり気にしないことが多いが、大規模実行の場合は実行イベントも気にする必要がある。 9
  6. 実行結果 Start 1イベント × 1回 ( ExecutionStart ) EventHistoryInit (Pass

    state) 2イベント × 1回 EventHistoryInvokeCounter (Lambda Invoke) 5イベント × 3571回 EventHistoryCheckDone (Choice state) 2イベント × 3570回 + 1イベント 24999イベント目が ChoiceStateEntered End 1イベント × 1回 ( ExecutionFailed ) 実行イベント: 1+2+(5×3571)+(2×3570+1)+1 = 25000 10
  7. 入れ子の書き方 { "Type": "Task", "Resource": "arn:aws:states:::states:startExecution.sync:2", "Arguments": { "StateMachineArn": "arn:aws:states:...:stateMachine:ChildWorkflow",

    "Input": { "AWS_STEP_FUNCTIONS_STARTED_BY_EXECUTION_ID": "{% $states.context.Execution.Id %}" } } } Resource startExecution startExecution.sync startExecution.sync:2 挙動 起動して即座に次へ。完了を待たない 完了を待つ。結果は「エスケープされた文字列」 完了を待つ。結果は「パース済み JSON」 入れ子したい部分をTaskステートで子ステートマシンを呼び出す。同期実行であれば、結果 を親ステートマシン側に返せる。 12
  8. JSONata なら、入出力処理が5つから2つになる 入力側 出力側 変数 JSONPath + Parameters ResultSelector +

    ResultPath + OutputPath Assign で保存、後続で参照可能 InputPath JSONata Arguments Output Assign で保存、後続で参照可能 JSONPathよりシンプルに処理できる。 QueryLanguage はステート単位で指定可能 既存はそのままJSONPathで、新しく書くステートからJSONataにすることが可能 Assign した変数は入出力ペイロードに載せずに渡せる 単一変数最大サイズ: 256 KiB / 1実行あたりの全変数合計: 10 MiB 別ステートマシンには変数は渡らない (スコープ外) 18
  9. 同じ子ワークフローを3,000個起動したいときは? Mapステートを使って子ワークフローを並列処理するのが王道 シンプルな処理では、Distributed Mapで並列実行数を簡単に引き上げることが可能 観点 同時実行数 実行履歴 入力 256KiB制限 Map

    最大 40 程度 Mapステートを管理する親ワークフローに残る JSON配列のみ 受ける Distributed Map 最大10,000 「マップ実行」として独立して持つ JSON配列 / S3(CSV, JSON, JSONL, Parquet ほか) S3 から直接読む場合は回避可能 「S3バケット内の特定のパス配下にある全ファイルを処理する」ケースだと、Distributed Mapがシンプルかつ強力な武器となる。 20
  10. 子の起動速度は、ワークフローの種別で変わる Distributed Map の⼦ワークフロー起動速度(実測) 6秒 3,000件 30秒 2,500 2,000 凡例

    1,500 実測 約550/秒(公称 up to 1,000 TPS) Express ⼦ Standard ⼦ 実測 ちょうど100/秒(公称 100 TPS) 1,000 500 0 0 5 10 15 20 到達点は同じ3,000。違うのは、そこまでの速さ 25 30秒 24
  11. ワークフロー種別毎の起動速度比較 子の種別 公称 実測(3,000件) Express up to 1,000 TPS 6秒(約500件/秒)

    Standard 100 TPS 30秒(100件/秒) Standard は30秒間ぴたりと毎秒100件。 Express は公称「最大 1,000 TPS」に対して、実測値は約半分程度。 25
  12. Distributed Mapの子ワークフローへの入出力 で各子に渡す入力を組み立てる JSONata が使える 大きなデータはペイロードに載せず、S3 のキーだけ渡して子ワークフロー側で読み込む ResultWriter で結果を S3

    に書き出す 親ワークフローに集約しなくて済む あわせて設定しておきたいもの。 ItemSelector ItemBatcher 複数アイテムをまとめて1つの子に渡す。起動回数が減る ToleratedFailurePercentage エラー許容率。指定した割合までのエラーを許容してMap全体を成功として扱える。 既定だと 1件失敗した時点で他も中断される 26
  13. 実際に 3,000 並列実行してみた結果 確認事項 Step Functions 側の子実行 Lambda 最大同時実行数 Lambda

    スロットリング 全体の所要時間 結果 3,000件すべて起動完了 1,500(上限緩和して 1,500 にしている状態) 8,273回 265秒 所要時間の理想は 60秒くらい (3,000×30秒÷1,500) だが、実際には 約4.4倍時間がかかった 28
  14. 壁は下流に移る 並列数を上げると、サービスクォータの壁は下流側のサービスに移っていく When using a distributed map, be sure to

    verify the quota on downstream services. — Distributed Map 発表ブログ https://aws.amazon.com/blogs/aws/step-functions-distributed-map-a-serverless-solution-for-large-scale-parallel-data-processing/ 30
  15. 並列実行数を上げた際に気になる Lambda の制限 壁 値 1 同時実行数 既定 1,000 /

    リージョン 2 スケール速度 1,000インスタンス / 10秒 / 関数 3 リクエスト速度 10,000 req/s 引き上げ 可 不可 不可 通常はあまり気にしない同時実行スケーリングレートだが、並列実行数を上げるとスロット リング発生につながる 公式ドキュメントの理解度テストの例がわかりやすい。 平均20ms の関数で 30,000 req/s を捌きたい。同時実行数は 30,000 × 0.02 = 600 で 足りそう。 しかし 10,000 req/s の上限に引っかかるので、同時実行数を3,000以上に上げる申請が 必要。 https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/lambda-concurrency.html 31
  16. Step Functions 自身のクォータも確認しておく オープン状態の Map 実行の最大数: 1,000 Distributed Mapに適用 /

    ハードクォータ 超えた分は MapRunStarted イベントで待機される StartExecution API にもスロットリングがあり リージョンによって値が異なる 上限緩和可能 1.でイベント履歴 25,000 を回避するために入れ子ワークフローにしたが、その入れ子は StartExecution APIを呼んでいる。公式ドキュメントの通り、スロットリングに対応するた めに Retry を設定しておく方が良い。 Retry で StepFunctions.ExecutionLimitExceeded を使用して、実行が確実に開始さ れるようにします。 https://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/concepts-nested-workflows.html 32
  17. MaxConcurrency で制御する 同じ処理を MaxConcurrency: 1500 に絞って実行してみた。 3000 最大同時実行数 1,500 Throttles

    8,273 所要時間 265秒 1500 1,500 0 128秒 最大同時実行数を絞ったら Throttles がゼロになり、しかも2倍以上速くなった! 上限を超えて投げても、下流が受け取れなければ Retry の往復が増えるだけ。 並列度は上げれば上げるほど良い、わけではないことに注意。 33
  18. まとめ Standard の実行履歴は 25,000イベントまで 履歴は「実行単位」 入れ子に分割すれば、各ワークフローで実行履歴 25,000イベントまで対応できる。 分割したら次はデータの受け渡し 必要な値だけをうまく入出力できるようにしておくこと。 Distributed

    Map は入れ子をシンプルに利用可能 子の起動速度は Express と Standard で5倍以上違う。 並列を上げるとサービスクォータの壁は下流に移る 特に各サービスのスケーリングや最大実行数に注意が必要。 上限緩和できるかどうかも確認しておく。 スロットリング対策として Retry 設定しておくと良い。冪等性の担保を忘れずに。 MaxConcurrency で制御する 最大実行数を絞ったほうが速いこともある 35
  19. 今後のJAWS-UG新潟 2026/9/16 (水) JAWS-UG新潟#33 AWSサポートが言いたいセキュリ ティサービスあるあるPart2 AWS Expert Online for

    JAWS-UG #39 2026/10/03 (土) JAWS-UG新潟#34 AWS Step Functionsハンズオン 2026/12 頃 AWS re:Invent 2026 re:Cap (予定) 他、毎週木曜夜21時からオンラインで「プチキャッチア ップ会」も開催中! 詳細・参加申込は connpass ページをご確認ください。 37
  20. 参考リンク Step Functions service quotas(AWS Docs) Best practices — Starting

    new executions to avoid reaching the history quota Start workflow executions from a task state(入れ子ワークフロー) Transforming data with JSONata in Step Functions Map workflow state Understanding Lambda function scaling Step Functions Distributed Map(発表ブログ) 39