バッチ処理にAWSのECS/Lambdaを採用するときに注意すること 4選
はじめに:バッチ処理とクラウド(CaaS/FaaS)
本記事のバッチ処理は、HPC(High Performance Computing)の文脈のバッチ処理ではなく、いわゆる業務バッチ処理を意図しています。
バッチ処理には以下のようなデメリットがあるため、削減した方が望ましいケースも多いと思います。
- ワークフローが複雑化し、メンテナンスが難しくなったり、障害復旧に時間がかかる。
- 処理の集中によって性能問題が発生する場合がある。
- 顧客体験のため24時間稼働を求められるシステムも増えており、リアルタイム処理との共存が難しい。
とはいえ、やはりバッチ処理は避けられないものです。例えば、以下のような要件ではバッチ処理が避けられない場合があります。
- 月次処理や、会計締め処理等特定の日を基準として集計する必要がある。
- 途中で人間の作業が必要であり、特に委託部分があるなどリアルタイムにすべての処理を捕捉することは難しい。
バッチ処理には、大容量データを処理するという特性があることが多いため、クラウドのスケーラビリティから恩恵を受けることができるシステムが多いです。
また、バッチ処理では各ジョブ(1つの処理やスクリプトの塊)を連ねて実装されることも多く、エフェメラルに各処理を実行できるCaaS(Container as a Service)やFaaS(Function as a Service)といったサービスとの相性の良さの観点でもクラウドと親和性があります。
ただし、実際にバッチ処理をCaaS/FaaSで実行するにあたっては考慮すべきポイントがあります。
そこで、本記事ではAWS(Amazon Web Services)のCaaS/FaaSでバッチ処理を実装する際の考慮点について述べます。
本記事では、特に実務で課題となりやすいと感じたいくつかの観点を取り上げます。
考慮ポイント
考慮ポイント①:処理の集約
バッチ処理では多様なジョブが必要となります。
各ジョブについて、個別にLambda関数やECS(Elastic Container Service)Task定義を実施するのが理想ですが、ログや監視、権限の設計による管理や設計工数上現実的ではないケースもあるかと思います。
ある一定数の処理を1つのLambda関数やECS Taskに集約することで対応する場合、集約の際には以下のような考慮が必要です。
- 処理をその関数やTask内に持たせるのか、それともスクリプトファイル等の形式で外部配置するのか
⇒ 内部に持たせる場合、必ずイメージや関数自体の更新が必要になる。一方外部に持たせる場合は外部に配置されたファイルのバージョン管理について考慮する必要がある。 - 共通処理(実行履歴の管理等)を切り出して独立した関数やTaskにするのか、すべての関数やTaskにそれぞれ含めるのか
⇒ 独立した関数等とした場合、別関数等で行われる業務処理の途中経過を細かく追跡するのが難しくなる。一方、すべての関数ごとに含める場合はバージョン管理とリリースの問題に対処する必要がある。 - デプロイライフサイクルが大きく異なる処理が混ざっていないか
⇒ ライフサイクルの短い処理に応じてライフサイクルの長い処理も更新する必要があり、管理負担が増加する。 - 最小権限の原則と大きく乖離しないか
⇒ 影響の小さいList等の権限を他のジョブが持つことは許容される場合もあるが、機微な権限(機密データの処理)については関数やTaskなどを分けることが望ましい。
上記のような考慮点によるトレードオフ及び、アプリケーション観点(関心ごとやドメイン)、対象システムの特性に応じた適切な粒度での集約が必要です。
考慮ポイント②:起動オーバーヘッド
バッチ処理におけるジョブは、基本的に1回限りの処理であり永続するものではありません。
そのため、起動オーバーヘッドの問題を考慮する必要があります。起動オーバーヘッドはコンテナを利用する場合に顕著です。特に、ECS/Fargateについてはイメージキャッシュが効かず、またLambdaについても初回起動時には同様にイメージをすべてプルする必要があるため、オーバーヘッドが大きく影響しやすいです。
また、Java等起動にウォームアップが必要な言語の場合にはその起動オーバーヘッドについても考慮する必要があります。
加えて、考慮ポイント①での処理によって、イメージサイズや関数の初期化処理が増えたことによる起動オーバーヘッドが発生する場合もあります。
この観点からも処理の過度な集約は不利に働くケースが多いと思います。
起動オーバーヘッドへの対策としては以下のようなものがあります。
- 処理や依存環境が複雑でないものは適宜コンテナではないLambda関数と非コンテナLambdaの一部でサポートされるSnapStartを利用するなど起動オーバーヘッドの少ない方式を選択する。
- ECS on EC2やECS Managed Instancesのようなイメージキャッシュの効くホストで処理を行ったり、LambdaのProvisioned Concurrencyを利用する。
- Fargateを採用せざるを得ない場合については、SOCI(Seekable OCI)による遅延読み込みの採用を検討する。
- Go言語等のイメージサイズを小さくできる言語を利用する、そうでない言語もJavaであればカスタムJREの作成やマルチステージビルド等イメージサイズの最適化を実施する。
- RunTaskやLambdaではなく、サービスとして処理を起動して、1回の起動で複数の対象を処理する。
バッチ処理においては処理の締め切り時間が定められているケースも多いかと思います。
起動オーバーヘッドについて考慮できていないと、例えば、非コンテナからコンテナへ処理を移植した際に同等のスペックでジョブを起動したのに想定の性能が出ないなどの問題が発生する場合があります。
なお、JavaについてはCRaCやGraalVM等より高度な最適化手法もありますので、もし体制として十分な技術者を揃えられ、また保守においてもそれに準じた体制を維持できるのであれば採用可能かと思います。Java周りの最適化については、少し古い記事(2022年)となりますがAWS公式のSpring Boot アプリケーションを AWS Fargate に最適化するが非常に参考になります。
考慮ポイント③:NW帯域
バッチ処理の中には容量の大きなデータ(例えば画像ファイル群)を処理する必要があるものが含まれる場合があります。そのような大容量データ処理をする際の考慮ポイントとしてNW(Network)帯域があります。
テキスト形式のファイル等を処理する業務バッチ処理であれば、多くの場合ファイルの取得時間などはあまり大きな問題とはならないかと思いますが、対象が画像データを含んでいたり、件数が非常に多い場合についてはNW帯域がボトルネックになる可能性があります。
注意しなければならない点として、ECS on FargateやLambda関数のNW帯域については公称のベースライン帯域やバースト帯域の情報がありません。そのため、データ量が大きい処理がある場合についてはその点も考慮した上で以下のような対策を行う必要があります。
- 処理対象をいくつかの塊に分割し、NW帯域による処理遅延が発生したときの影響を少なくする。
⇒ もし、配置されたホストでNW帯域の問題が発生しても、分割されたデータ分にしか遅延が発生しないため、全体としての遅延量を小さく抑えることができる。 - ベースライン帯域やバースト帯域に合わせてホストを選択できる、ECS on EC2やECS Managed Instancesのようなサービスを選択する。
考慮ポイント④:再実行・重複等実行履歴管理
最後については広く知られた考慮ポイントかと思います。バッチ処理/リアルタイム処理にかかわらず考慮する必要があります。
コンテナやLambda関数はエフェメラルなため、正常・異常終了を問わず処理の結果や処理の経過をログや外部のデータベースに記録をしておかないと、異常終了時のリトライや、SQSの標準キューの仕様である"at least once"の処理の際に重複処理が発生してしまいます。
- ログをしっかりと出力し、CloudWatch Logsなどで収集管理する
- AWS X-Ray等のオブザーバビリティサービスを利用する
- 処理の途中でDynamoDBや何らかのRDB(Relational Database)に処理結果を格納しておく
- リトライやロールバックを考慮した設計を行う。例えばロールバック用のジョブについても準備しておく
といった対策を行う必要があります。
まとめ
ECSやLambdaを組み合わせることでクラウドでも柔軟なバッチ処理を実現できます。
一方で、コンテナをバッチ処理の実行環境として利用するためには考慮すべきポイントがあるため今回はそちらをお伝えさせていただきました。
より良い設計のため、ご参考になりましたら幸いです。
仲間募集中です!
NTTデータ クラウド&データセンタ事業部では、以下の職種を募集しています。
- プライベートクラウドコンサル/エンジニア
- デジタルワークスペース構築/新規ソリューション開発におけるプロジェクトリーダー
- IT基盤(パブリッククラウド、プライベートクラウド)エンジニア
- パブリッククラウド/プライベートクラウドを用いた大規模プロジェクトをリードするインフラエンジニア
ソリューション紹介
NTT DATA公式アカウントです。 技術を愛するNTT DATAの技術者が、気軽に楽しく発信していきます。 当社のサービスなどについてのお問い合わせは、 お問い合わせフォーム nttdata.com/jp/ja/contact-us/ へお願いします。