FullStackEngineer 2020年3月17日更新

バッチ処理

Index

バッチ処理 (Batch Processing) 解説記事

1 はじめに

「バッチ処理」を一言でいうと: 「大量のデータやジョブを、あらかじめ決められた手順に従って、一括で自動処理する仕組み」のことです。

なぜ重要なのか: 現代のシステムは24時間365日稼働していますが、すべての処理をユーザーが操作した瞬間に(リアルタイムで)行うと、サーバーに負荷がかかりすぎてパンクしてしまいます。 バッチ処理は、夜間やシステム利用が少ない時間帯に重い処理をまとめて行うことで、システムリソースの有効活用業務の効率化を実現します。例えば、銀行の夜間集計、クレジットカードの請求確定、ECサイトのランキング更新などはバッチ処理の代表例です。

2 ビギナー向け・ドキュメント

概要:洗濯機で例えるバッチ処理

バッチ処理を理解するには、「洗濯」をイメージすると分かりやすいでしょう。

  • リアルタイム処理(対義語): 靴下が1足汚れるたびに、すぐに洗濯機を回すこと。常に清潔ですが、水も電気も時間も無駄にかかります。
  • バッチ処理: ランドリーバスケットに溜めておき、夜になったらまとめて洗濯機を回すこと。効率的で、寝ている間に完了します。

コンピュータの世界でも同様に、「データ(洗濯物)」を一定量ためておき、「決まった時間(夜)」に「一括処理(洗濯)」を行います。

公式情報・信頼できるリソース

バッチ処理は概念であり、特定のツールを指すものではありませんが、実装によく使われる代表的なフレームワークやツールのドキュメントを紹介します。

導入:Pythonで書くシンプルなバッチ処理

ここでは、「リストにある複数のユーザー名に対して、挨拶ログを書き出す」という極めて単純なバッチ処理の例をPythonで示します。実務では、これを cron などのスケジューラで定期実行します。

import datetime
import time

# 処理対象のデータ(本来はデータベースなどから取得)
users = ["Alice", "Bob", "Charlie", "Dave"]

def process_batch(user_list):
    print(f"--- バッチ処理開始: {datetime.datetime.now()} ---")

    with open("daily_greet_log.txt", "a") as f:
        for user in user_list:
            # 擬似的な重い処理(0.5秒待機)
            time.sleep(0.5)
            log_message = f"Hello, {user}! Processed at {datetime.datetime.now()}\n"
            f.write(log_message)
            print(f"{user} の処理完了")

    print(f"--- バッチ処理終了: {datetime.datetime.now()} ---")

if __name__ == "__main__":
    process_batch(users)

その他のBatch処理について

3 会話集

エンジニアの現場でよく耳にする、バッチ処理に関する会話例です。

Q1: なぜリアルタイムで更新されないの?

マーケ担当: 「先ほど登録した商品のランキングがまだ反映されていないんですが……バグですか?」 エンジニア: 「いえ、ランキング集計はデータ量が膨大なのでバッチ処理にしています。毎晩深夜2時に走るよう設定しているので、明日のお昼には反映されていますよ。」

Q2: 処理が失敗したらどうする?

新人: 「もしバッチ処理中にエラーが起きて止まったら、どうなりますか?」 先輩: 「いい質問だね。だから冪等性(べきとうせい)を意識した設計が必要なんだ。途中で止まっても、もう一度最初から実行すれば正常な状態になるように作っておく必要があるよ。あとはリトライ処理の設定も重要だね。」

Q3: バッチの時間が足りない!

運用担当: 「最近データが増えてきて、夜間バッチが朝の始業時間までに終わらない『突き抜け』が発生しそうです。」 エンジニア: 「処理を並列化するか、処理対象を差分(変更があったデータ)だけに絞るようにロジックを見直す必要がありそうですね。」

4 より深く理解する為に

アーキテクチャ:ETLプロセス

バッチ処理の多くは、ETLと呼ばれる以下の3段階で構成されます。

  1. Extract (抽出): データベースやログファイルから必要なデータを吸い出す。
  2. Transform (変換): 集計、計算、フォーマット変換などを行う。
  3. Load (書き出し): 結果を別のデータベースやファイル、データウェアハウス(DWH)に保存する。

重要な概念:冪等性(Idempotency)

バッチ処理開発における最大のベストプラクティスは「何度実行しても結果が同じになること(冪等性)」を担保することです。 * 悪い例: 実行するたびに「売上合計」に数値を単純加算する(2回実行すると売上が2倍になってしまう)。 * 良い例: その日の売上データを一度削除してから再計算して保存する、あるいは重複チェックをしてから保存する。

バッチの起動方式

  • 定期実行(Scheduled): CronAirflow を使い、毎日決まった時間に実行。
  • イベント駆動(Event Driven): ファイルがアップロードされた、データ量が閾値を超えた、などのトリガーで実行。

5 関連ワード

  1. Cron (クーロン / クロン): UNIX系OSで標準的に使われる、コマンドを定時実行するためのスケジューリング・デーモン。「crontab」ファイルに設定を記述します。
  2. Job Scheduler (ジョブスケジューラ): Cronより高度な管理ツール。ジョブ同士の依存関係(Aが終わったらBを実行)や、失敗時の通知などを管理します。例:JP1, Jenkins, Apache Airflow。
  3. 突き抜け: 予定していた時間内にバッチ処理が終わらず、次の業務時間や次のバッチ実行時間に食い込んでしまうこと。システム障害の原因になります。
  4. ストリーミング処理: バッチ処理の対義語的な存在。絶え間なく流れてくるデータをリアルタイムに処理する方式。KafkaやApache Flinkなどが使われます。
  5. データウェアハウス (DWH): バッチ処理で集計された分析用データを保管するための大規模なデータベース。例:Snowflake, Google BigQuery, Amazon Redshift。

6 要点チェック

  • バッチ処理は、大量のデータをオフピーク時に一括で自動処理する技術である。
  • ユーザーへの即時応答が不要な処理(集計、バックアップ、請求計算)に向いている。
  • 設計においては、再実行してもデータがおかしくならない「冪等性(べきとうせい)」が非常に重要。
  • データ量が増えると処理時間が伸びるため、パフォーマンスチューニングや並列化が課題になりやすい。
  • リアルタイム性が必要な場合はストリーミング処理、大量一括処理ならバッチ処理と使い分ける。

最新記事一覧

続きを見る

関連コンテンツ

カテゴリー一覧

TOP フルスタックエンジニアを目指すに方々へ 2018年5月3日 パッケージマネージャー、バージョン管理(composer,npm,yarn・・・)