😺

バッチ処理を作る際に押さえておくこと

2024/09/04に公開

はじめに

バッチ処理を作る際に検討項目が多く手が動かない。。。。
そんな状況にならないためにフォローできる記事になれば良いと思い書き込んでみました。

そもそもバッチ処理とは

簡単にいうと一定量のデータを集めて、一括で処理する方法のことです。
主にユーザアクションに起因しない処理です。

実行についても定期実行、手動実行など様々な用途で用いられます。

バッチ処理にするメリット

大量のデータを一括で処理できること
稼働する時間を調整できる。(業務システムが稼働していない夜間などに処理を行える)

バッチ処理の構成

基本としてバッチ処理は以下の構成となっている。

入力して加工して出力する

入力
 DBのデータ
 CSVファイル

加工
 抽出する
 削除する 
 集計する 
 マージする

出力
 DBに登録する
 CSVファイルに書き起こす 
 メール送信 
 ファイル作成して転送

バッチを作る際の検討事項

構築する際に迷ったら以下ポイントを参考にしてください

  • 起動方法(定期実行?随時実行?)
  • 再実行(リラン)
  • 並列・直列
  • ドライラン
  • トランザクション制御
  • リソース監視
  • エラー、例外検知
  • オンライン処理との関係
  • ロギング(ログ)
  • 完了通知

起動方法

  • 定期実行
  • 手動実行

この2パターンになります。

定期実行

バッチのメリットは定期実行です。こちらはジョブ管理システム、またはcronを利用することで実現可能です。

手動実行

主に定期バッチを何かしらの理由で実行する方法です。定期スケジュール外で実行する状況が出てきたらコマンド実行などで実行します。
実行スケジュールをルール化し定期実行することができます。

再実行について

リランともよく言われます。
再実行する際はほぼイレギュラーが発生した状況が多いです。
バッチ実行中に何らかの事象で処理が中断した時にリランをします。
ただそのままリランをしたところで同じエラーになることが多いのでエラーをとりのぞく(入力値の修正、処理中のエラー確認)ことをしてからリランしましょう。
考えることとしてはすでに完了している処理・再実行時に行われる処理に影響がないように再実行させましょう

方法としては途中から再実行用のオプションを付けるなど

インプットのデータはバックアップをとりましょう

処理を実行する際に入力のファイルをそのまま加工するとエラーした際に再実行できません。
処理に間違いがあってもすぐに復元できるよう、 処理の実行で書き換えられる可能性があるデータはバックアップをとっておきましょう。

実行時のコマンドライン引数はわかりやすくしましょう

バッチ処理にコマンドラインから引数を渡すときは、 よりわかりやすい名前付きの引数を使うようにしましょう。

$ sh batch.sh 10 1 "test" //どの引数か分かりづらい
↓
$ sh batch.sh --name=hoge --age=1 --message="test"

まずはドライランから実行

web,APIとは異なり一度に大量のデータ処理を行うことが多いので手動実行する際はいきなり本番でGO!ではなく、仮実行(ドライラン)できるような構成にしておきましょう。

$ sh batch.sh --name=hoge --age=1 --message="test"
↓
sh batch.sh --name=hoge --age=1 --message="test" --dry  //これをつけておけば本番処理されない
または
sh batch.sh --name=hoge --age=1 --message="prod" --prod  //prod指定することで本番処理される

ロギング(ログ)

どんな開発でも同じだと思いますが、実行した処理についてはログを残しましょう。
バッチ内でログファイルに書き出すことで実現可能です。

ログを残す理由としては

  • バッチ処理が正常終了したか確認できるようにする
  • 処理が失敗した際にどこまで処理したかわかるようにする

ログに出す内容

  • 現在の時間
  • プロセスID
  • 実行バッチ名
  • 実行ファイル名、クラス名
  • 処理対象
  • エラーの際はエラーメッセージ

トランザクション処理

主にバッチ処理の中でデータベースを書き込む、書き換える際は1レコードずつ処理を終えるのか一気に処理を終えるのか検討しましょう。
処理が完了している部分としていない部分が混在するとまずい場合は、 すべての処理が完了するまでデータを書き換えないようにしておきましょう。
この方針はバッチの機能によって変わります。
データベースの話にもなりますが、長時間トランザクション処理でテーブルにロックをかけるとその間にデータの更新ができないため、web,apiと処理がかぶる場合は気を付けましょう。

まとめ

気づいたベースでダラダラ書いてしまいました。まだまだ足りないと思いますが、思いつきで追記します。
安定したバッチ処理を実装できるようお祈りしています。

Discussion