AWS Lambda のアップデートが来た!今こそ AWS Step Functions を活用しよう
こんにちは、田中孝明です。
このエントリは、Qiitaの Serverless Advent Calendar 2017 の10日目の記事です。
re:Invent 2017で AWS Lambda で利用できる動的メモリサイズが 3GB になったことが発表されました。
【速報】AWS Lambdaで使用できる最大メモリサイズが3GBになりました #reinvent
今までデータのパース処理など、インメモリを大量に確保する必要のあるプログラムをAWS Lambda に置き換える場合、1.5GBという制約がネックになって、置き換えることが難しかったバッチプログラムもありました。
最大メモリサイズが3GBになったことで、インメモリを大量に確保するデータのパース処理も行いやすくなりました。
今こそ、 AWS Step Functions を利用したバッチプログラムを採用してみてはいかがでしょうか?
AWS Step Functions
AWS Step Functions により、視覚的なワークフローを使用して、分散アプリケーションとマイクロサービスのコンポーネントを簡単に調整できます。それぞれ別個の機能を実行する個々のコンポーネントからアプリケーションを構築することで、簡単にアプリケーションをスケールおよび変更できるようになります。
AWS Step Functions より抜粋
「CSVを取得するLambda 関数」、「CSVをパースするLambda 関数」、「エラーを通知するLambda 関数」など、Lambda 関数を用途別に分離し、 Amazon ステートメント言語 で記述することで、各Lambda 関数のワークフローを視覚的に構築することができます。
AWS Step Functionsの構築
Amazon ステートメント言語 に従ってLambda 関数を Step Functions に構築します。
あらかじめ Lambda 関数 を作成しておき、 States
の Type
を Task
にし、 Resource
で Lambda 関数 の arn
を指定します。
{ "Comment": "An example of the Amazon States Language using a choice state.", "StartAt": "FetchCSV", "States": { "FetchCSV": { "Type": "Task", "Resource": "arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:fetch_csv", "End": "true" } } }
すると、ワークフローに反映されます。
Lambda 関数 同士を接続する場合は、 States
に新たな Task
を追加し、 Next
で追加した Task
を記述するだけで可能となります。
{ "Comment": "An example of the Amazon States Language using a choice state.", "StartAt": "FetchCSV", "States": { "FetchCSV": { "Type": "Task", "Resource": "arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:fetch_csv", "Next": "ParseData" }, "ParseData": { "Type": "Task", "Resource": "arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:parse_data", "End": "true" } } }
Task に関しては、タイムアウト等の設定をすることも可能です。
より複雑な行程の構築
Step Functions で利用できる ステートメント言語 には、Choice や エラー処理 もあります。
利用することで、より複雑なフローを構築することができます。
上記のような、一つの Lambda 関数 で行うとコードが煩雑になるものも、目的別の Lambda 関数 と選択処理、エラーハンドリングを組み合わせることで、視覚化できます。
ワークフローで可視化することで、複雑なフローのバッチ処理もメンテしやすくなるのではないでしょうか。
{ "Comment": "An example of the Amazon States Language using a choice state.", "StartAt": "FetchCSV", "States": { "FetchCSV": { "Type": "Task", "Resource": "arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:fetch_csv", "Catch": [ { "ErrorEquals": ["NotFuound"], "Next": "NotFuoundFallback" }, { "ErrorEquals": ["FileError"], "Next": "FileErrorFallback" } ], "Next": "ParseData" }, "NotFuoundFallback": { "Type": "Pass", "Result": "CSV Not Fuound", "End": true }, "FileErrorFallback": { "Type": "Pass", "Result": "File Error", "End": true }, "CSVParseErrorFallback": { "Type": "Pass", "Result": "CSV Parse Error", "Next": "SendMail" }, "ParseData": { "Type": "Task", "Resource": "arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:parse_data", "Catch": [ { "ErrorEquals": ["CSVParseError"], "Next": "CSVParseErrorFallback" } ], "Next": "ChoiceState" }, "ChoiceState": { "Type" : "Choice", "Choices": [ { "Variable": "$.foo", "NumericEquals": 1, "Next": "AddOnlyFiles" }, { "Variable": "$.foo", "NumericEquals": 2, "Next": "DeleteOnlyFiles" } ], "Default": "UpdateFiles" }, "UpdateFiles": { "Type" : "Task", "Resource": "arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:update_files", "Next": "SendMail" }, "AddOnlyFiles": { "Type" : "Task", "Resource": "arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:add_only_files", "Next": "SendMail" }, "DeleteOnlyFiles": { "Type" : "Task", "Resource": "arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:delete_only_files", "Next": "SendMail" }, "SendMail": { "Type": "Task", "Resource": "arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:send_mail", "End": true } } }
まとめ
弊社もバッチシステムをStep Functionsで構築しているところがあります。
AWS Lambda の最大メモリサイズが増えたことで、大量のインメモリを必要としていたパース処理も置き換えることが可能になったのではないでしょうか?