Step Functions の Map ステートで、処理時間が劇的に短くなった話

記事タイトルとURLをコピーする

はじめに

こんにちは。技術4課の河野です。最近作り置き料理にハマっていて、週末に平日分の夕飯を作るというライフハックを実践中です。

今回は、AWS Step Functions(以下「SFN」) の Map ステートについてのお話です。

要約

SFN で過去一年分のSlack投稿メッセージを取得するバッチを構築しました。 トータル処理時間が、1.5h (データ件数は 2万件程度)だったため、SFNの Map ステートを組み込んだところ処理時間が 10.0 min まで短くなったというお話です。

改善前

Slack投稿メッセージは、下記のような構成(ざっくり)で構築しました。

Slackのメッセージを取得する Lambda をタイムアウトするまでぶん回して、タイムアウトエラーを SFN 側でキャッチしてリトライするという力技です。

改善前の課題

冒頭でも述べた通り、「Slackメッセージを取得する(getSlackPostsステート)処理時間が 1.5h 以上かかっていた」ことです。

原因は以下の通りです。

  • 全てのメッセージの処理を一つの Lambda 関数で順次処理していたこと
  • 再試行の数が増える度に、待ち時間が増加していたこと

Map ステートについて

Map ステートは SFN 上で動的並列処理をサポートする機能です。 ステートの Input に配列を渡すと、配列の要素毎にステップを並列に実行できます。

下記例は、Lambda を並列実行させる Map ステートのイメージになります。

詳細な使い方については、公式ドキュメントをご参照ください。

改善後

上記のMap ステートのイメージを踏まえたところで、今回の構成をどのように改善したかを説明します。

変更点は以下の通りです。

  • メッセージの取得を一ヶ月単位で分散実行する(Mapステート)
  • Mapステートに渡す配列を作成するステートを追加
    • 指定した日付から過去一年間を一月毎に区切った配列
    • 例:
      • input: 2020-05-15
      • output: [{ start: 2019-04-15, end : 2019-05-15 }, { start: 2019-05-15, end : 2019-06-15 }, ...]

getSlackPostsステート のロジックは変更せずに、処理させる件数を少なくして並列で実行させるように変更しました。

構成は、以下のようになりました。

さいごに

実際の処理結果です。全体の処理時間が10分程度になっていることがわかります。

下記のように並列処理されていることも確認できました!

最後まで読んでいただきありがとうございました。