私の戦闘力は53万です

awsとgcpについて書きます

AWS StepFunctions Lambdaを利用する時のTips

Japan APN Ambassador Advent Calendarqiita.com

2020 8 日目のエントリです。
先日、会社でStepFunctionsの利用方法や、
Tipsを説明することがありました。
良い機会なので記事に書いてみようと思いました。

Stepfunctions概要

docs.aws.amazon.com サーバレスのサービスを組合せて利用する際の
オーケストレーションのサービスです。
具体例をみると分かりやすいかもしれません。
下記の図の各NodeがLambda、SQS等、 各種AWSのサービスを表しており、
それらの処理を組み合わせて定義することが可能です。 f:id:remmemento:20201208221953p:plain

Tips

利用し始めるとStepFunctionsならではの
機能や制限があることに後から気付き、
処理を作り直すことが良くありました。
事前に知っておきたかったことを 会社の後輩に伝えたところ割と喜んでくれたので書いていきます。

例外処理、再実行レベルを考慮する

上述のようにStepFunctionsでは
複数のLambdaを組み合わせることができます。
StepfunctionsでもLambda実行時のエラー考慮が必要になります。
Lambdaにはデッドレターキューというエラーの処理方法がありますが、
StepFunctionsのときは、代わりにStepFunctions独自のエラーハンドリングを利用すると便利です。

外部環境により発生した例外の場合

Lambdaでは(コードが正しくても)稀に実行が失敗することがあります。
レート制限エラーや、ネットワーク等の影響による一時的なエラーです。
このような場合は、数秒おいて再実行すれ成功する可能性が高いため
StepfunctionsのRetry機能を利用するのが良いと思います。
docs.aws.amazon.com 具体的には、下記のように特定のLambdaの処理に下記のように
Retryを設定することで、StepfunctionsがLambdaを再実行してくれます。

"Retry": [ {
   "ErrorEquals": [ "States.Timeout" ],  #このエラーのときに
   "IntervalSeconds": 3,    #インターバル3秒で
   "MaxAttempts": 2,        #最大2回再試行
   "BackoffRate": 1.5         #再実行の実行回数が増える毎にインターバルの秒数を増やす設定値
} ]

その他の例外の場合

上記以外ですと、 StepFunctionsのcatch機能を利用するのが良いと思います。
例外の内容により、次に実行する処理(Lambda)を制御できます。
docs.aws.amazon.com

具体的には、下記のように特定のLambdaの処理に下記のように
Catchを設定することで、StepfunctionsがLambdaがエラーだったときの ハンドリングをしてくれます。

 "Catch": [ {
            "ErrorEquals": ["States.Timeout"],  #このエラーのときは
            "Next": "fallback"    #次にfallbackの処理を実行する
         } ],

上記機能を利用し、
Lambda内はエラー処理をごちゃごちゃ書かず
シンプルな状態を保つとメンテナンスしやすいです。

Lambda単位で冪等性を持つように作る

上述のように各Lambdaの再実行設定が容易なため、
Lambda単位で冪等性(何回実行しても同じ結果になる)を
持つようにしておくと
StepFunctionsで利用しやすいです。

Mapやループ処理の際、StepFunctionsを分割する

バッチ処理をStepFunctionsで組む場合、 大量のデータをループ処理または並列処理したいことがあります。

StepFunctionsでは、下記のようにループ処理を書くことや f:id:remmemento:20201208231458p:plain
下記のような並列処理(MAP)の記載が可能です。 f:id:remmemento:20201208231557p:plain

ただし、StepFunctionsでは状態間の
データの受け渡し容量が262,144bytesと制限されています。
大量のデータをやりとりする場合は、この制限を超えてしまいます。
f:id:remmemento:20201208231829p:plain StepFunctionsではデータが制限を超える場合、S3等を利用し、
一時的にデータを別場所に保管することが推奨されています。

ただし、S3を利用しデータを受渡すると、
上記のような、ループや並列処理の記述ができません。

そこで、私の場合はStepFunctionsを2つに分けました。 f:id:remmemento:20201208232643p:plain 3つ目の処理の中で、大量データを取得し、
データ毎に別のStepFunctionsを実行することで
並列処理が可能でした。 将来的にデータ量が拡張し、制限を超える場合は、 このような記述も良いと思います。

StepFunctionsの実行時の引数を活用する

Stepfunctionsのフロー図を作成すると、
極力それを使いまわしたいと思います。
例えば特定条件のリソースを停止する処理を作成するとします。
毎月末に対象を通知し、毎月初に停止処理を実行する場合
停止をするかしないか以外は、ほぼ同じ処理になります。

そんなとき、StepFunctionsの実行時の引数で処理を分岐すると便利でした。
具体的にはStepFunctions実行時の引数として変数を渡し
その変数によって処理を分岐するイメージです。 f:id:remmemento:20201209000017p:plain

さいごに

Japan APN Ambassador Advent Calendarの
記事を書かせて頂き大変光栄でした!
会社を超えて、日々前向きな方達と交流が持てるのは
本当にありがたいです。 コロナ影響が早くなくなって、
もっとリアルでもお会いできるのを楽しみにしています。