バッチ処理とは。さらにSpringBatchを用いたバッチ処理について

目次
はじめに
本記事はIT会社勤務の100名程の研修生を見てきた元Java研修講師が、システムやアプリなどでのバッチ処理について解説するのと、実際のバッチ処理をどう作っていくか、そのときに使われるSpringBatchとはなにか。についてお話ししていきます。
バッチ処理
バッチ処理は、一定のタイミング・条件でまとめて大量のデータや処理を一括で実行する方式のことです。身近な生活の中でバッチ処理を例えると、郵便局員などが良い例です。ポストの中に投函れたタイミングで毎回集めに来るのは大変ですよね。そこで、集める日をいつって決めて(一定のタイミング・条件)まとめてポストに投函されているものを集めに来ます。集める日に大量の郵便物を集める処理をしているので、バッチ処理の考え方に近いです。このイメージをまず持ってもらうと良いと思います。リアルタイム処理とは違い、ユーザーの操作を待たずに自動的に処理が進みます。
特徴として以下の項目が挙げられます。
- 大量データの一括処理
リアルタイムでは処理しきれない場合にバッチ処理が使われます。業務例では売り上げの集計などです。その日の売り上げなどを、リアルタイムで処理するには大変なので一度の処理で大量のデータを一括処理することができます。
- 決まったスケジュールで実行
スケジュール管理はSpringBatchの機能の一部で管理できます。一度決めると、そのタイミングに自動で実行してくれるようになります。さらに、早朝や深夜の時間帯で実行されることが多いです。その理由としては、利用者が少ない時間帯でシステムの負荷などが小さい。業務サイクルに合わせて「前日分」や「月次分」のデータをまとめて処理する必要があります。
- ユーザーの操作を待たない
一度バッチ処理を作ってしまえば、設定したタイミングでプログラムが動くので、ユーザーのアクションがバッチ処理のトリガーではないので、「設定したタイミングで処理が完了している状態」が理想。このため、バッチ処理は信頼性と完了保証が重視される。
SpringBatch
SpringBatchは、Java(特にSpringboot)での「バッチ処理」を効率よく、再利用可能かつ拡張性のある形で実装するためのフレームワークです。バッチ処理の書き方としては、2つのモデルがあります。「Chunkモデル」と「Taskletモデル」の2つです。それぞれの特徴と共通の特徴を説明します。
Chunkモデル
データを「読み込み⇨処理⇨書き込み」する構造。読み込みするクラスと、処理をするクラス、書き込みをするクラスに役割分担させる構造です。
一定件数(チャンク単位)でトランザクションがコミット(実行される)ため、大規模データでも効率的。トランザクションは全ての処理が成功してから、結果を反映させるので途中でエラーが起きても、再実行やリトライ制御がしやすい。
Job・Stepの構成
Jobはバッチ処理全体の単位で全体の流れを定義します。⇨1つのバッチ処理が1つのJobとなる。Jobの中は複数のStepで構成されていて、順番や条件付きで実行していきます。
Stepとは、Job内の1処理のまとまり。各Stepで「何をするか」を定義する。1つの処理に対して1つのStepで構成する。
Chunk処理に対応
データを一定件数ごとにまとめて(例:100件)処理・書き込み。「100件読み込んで⇨加工して⇨一括で書き込む」このようにすることでトランザクションの管理もしやすくなる。
Taskletモデル
Chunkモデルとは違い、1ステップで1つの処理を書きます。役割分担せずに1つのクラスで書くので柔軟性は高いです。データの量が少なくてChunkほどの構造がいらない場合に適しています。
共通
再試行・スキップ処理が可能
途中で止まったJobを再開したり、前回実行済みのJobをスキップしたりと柔軟な実行管理が可能。
ログや実行履歴の管理を自動でする
Jobの実行結果(成功/失敗/開始、終了時刻/件数など)をDBに登録する。再実行やトラブル調査に役立ちます。
まとめ
上記のようにバッチ処理とはなにかを学んでいただけたと思います。その上で使われるのが「SpringBatch」であり、「Chunkモデル」と「Taskletモデル」があります。Chunkモデルは大量のデータを扱うのに適しており、1日の売り上げ集計などの実務で使われています。Taskletモデルは、シンプルな処理に向いているので、売り上げの集計が終わったり以上があった際の通知メールの作成や送信などの実務で使われています。このように各特徴を押さえることで、なにをするときはどっちを使うかをスムーズに考えることができるようになると思います。