現代Webサービスでのバッチ処理についての考察
現代、Webサービスでは多くの場合バッチ処理というものが存在する。
これは数十分から数時間かかるような長時間の処理で、大抵の場合DBへの大量のアクセスやS3などのストレージへのIOを行う。
このバッチ処理だが、現代、割とベストプラクティスが定まっていない気がする。
今回、アーキテクチャ選定に非常に迷ったので、それを整理するためにこちらへ論理を書き出す。
まず、バッチ処理の歴史について。
おそらく最も初期にあったバッチ実装はcronjobを使ってWebサーバ上で実行していたもの。
2010年以前などは1インスタンスの価格が非常に高かったので、当然のようにWebサーバとバッチ実行の場所は同居していた。
殆どの場合、実行するプログラムもWebアプリケーションと同じものだったので、デプロイサイクルが一致するメリットもあった。
次が、cronサーバのみ別のインスタンスにする時期。
そしてそこから更に進んでJenkinsのようなリッチなジョブ管理をするようになった。
で、そこからもう少し進み、SideKiqのようなジョブスケジューラーが出てきた。ここはcron系の直径の子孫というわけではないものの、DBやストレージへのヘビーで長時間のIOを伴わない処理はこれで事足りることが多くなってきた。
上記は主にアプリケーション側の話。
で、これに関わってくるのがIaaS、特にサーバレス。
ここまでの歴史は、基本的に実行箇所が1つの物理的サーバもしくは1インスタンス内で継続的に行われる前提だった。
ただ、2010年代後半からFargateやECSなどdockerでサーバレスな環境がデフォルトになっていく中でそのような1つのインスタンスが長期間実行され続けるのはデメリットが目立ち始めた。特にバッチの実行環境は利用者の手によって状態を持ってしまいやすく[1]、これは大きな問題と言えた。
また、インスタンス数が固定ということは負荷に対してスケーリングすることも困難にしており、コスト最適化も難しいと言えるためデメリットは大きい。
ただ、2025年現在、Ruby系で広く使われるSideKiqやActiveJobsなどを見てもこの問題に対してのソリューションを提供しているところは無いように見える。
このサーバレスバッチに対するソリューションとしては現状IaaSが提供しているものを使うのが一般的に見えるが、
これはWebアプリケーションとの統合性が低く、インフラ側で多くの準備をする必要がある。
-
sshで中に入ってのいろいろ。例えばjqコマンドをインストールする、などを手動でやってしまいがち ↩︎
Webアプリケーション・フレームワークの立場に立って見る。
前述のAWSなバッチ処理インフラ構築をよりスマートにやるには次のようなツールはある
が、正直コレが限界な気はする。
おそらく、IaaS + 認知のバッチ実行というのがフレームワークや言語に依存するものがないため、Webフレームワークにどこも組み付けで用意していないのだと思われる。
つまり、ecscheduleが正解、のように見える。