バッチ処理とストリーム処理、どちらを選ぶべきか――この問いに対する正直な答えは「まずバッチで始めて、必要な時だけストリームに進む」です。本記事では両者の違いを遅延・スループット・コスト・複雑さで比較し、ユースケース別の選定フレームワークを解説します。

バッチ処理とストリーム処理の定義

バッチ処理は「一定間隔で溜まったデータをまとめて処理する」方式、ストリーム処理は「データが発生した瞬間に逐次処理する」方式です。両者の処理フローを対比した図を示します。

【バッチ処理 vs ストリーム処理】

[Batch]
Source --> [Queue / Storage] --> [Scheduler triggers] --> [Batch Job] --> DWH
                                     |
                              e.g. every 1h / 1day

[Stream]
Source --> [Message Broker] --> [Stream Processor] --> DWH / Store
             Kafka / Kinesis      Flink / Spark Streaming
                                   running 24/365

※ バッチは「区切って処理」、ストリームは「流れ続ける処理」と理解してください。

バッチ処理の特徴とユースケース

バッチ処理の強みは「シンプルさ」と「コスト効率」です。処理のスケジュールが明確で、障害復旧が容易、リソースもピーク時だけ必要なためコストを抑えられます。日次の売上集計、月次レポート、機械学習モデルの定期再学習、データ基盤の日次Transformといったユースケースはすべてバッチが適任です。

Airflowを使った典型的なバッチジョブ定義は次の通りです。dbt runを日次で実行し、失敗時にSlackへ通知する、といった設計が一般的です。

from airflow import DAG
from airflow.operators.bash import BashOperator
from datetime import datetime

with DAG("daily_transform", start_date=datetime(2026, 1, 1),
         schedule="@daily", catchup=False) as dag:
    dbt_run = BashOperator(task_id="dbt_run", bash_command="dbt run --target prod")
    dbt_test = BashOperator(task_id="dbt_test", bash_command="dbt test --target prod")
    dbt_run >> dbt_test

ストリーム処理の特徴とユースケース

ストリーム処理は「リアルタイム性が必要な場面」に真価を発揮します。クレジットカード不正検知、リアルタイム在庫更新、リアルタイム広告入札、ゲームのリーダーボード、IoTセンサー監視などがこれに該当します。

代表的な実装にはKafka Streams、Apache Flink、Spark Structured Streamingがあります。Spark Structured Streamingの簡易コードを示します。ウィンドウ集計を行う例です。

from pyspark.sql.functions import window, count

stream = spark.readStream.format("kafka")     .option("kafka.bootstrap.servers", "kafka:9092")     .option("subscribe", "events").load()

agg = stream.groupBy(window("timestamp", "1 minute"), "event_type")             .agg(count("*").alias("events"))
agg.writeStream.format("delta").outputMode("append").start("/delta/events_agg")

徹底比較

主要な観点で両者を比較した表です。運用面・コスト面でのインパクトが最も大きいことが読み取れます。

観点バッチ処理ストリーム処理
遅延分〜時〜日ミリ秒〜秒
スループット高(まとめ処理)中〜高(継続処理)
複雑さ
コスト低(実行時のみ)高(24/365稼働)
障害復旧容易(再実行すればOK)困難(状態管理が必要)
適するデータ量GB〜TBMB〜TB(流量次第)
代表ツールAirflow / dbt / Spark BatchKafka / Flink / Spark Streaming
監視難易度
運用チーム規模小〜中中〜大

「リアルタイム」の定義を疑う

「リアルタイム」と一言で言っても、実際には幅があります。1秒以内のハードリアルタイムから、5分間隔のマイクロバッチまで、実装コストは1桁以上違います。要件ヒアリングで「リアルタイムにしたい」と言われても、その裏にある本当の要件を掘り下げてみると、実はマイクロバッチで足りるケースが多々あります。

カテゴリ遅延実装方式コスト傾向ユースケース例
ハードリアルタイム数ミリ秒インメモリ処理 + ストリーム広告入札、金融取引
ニアリアルタイム1秒〜数秒ストリーム処理中〜高不正検知、リアルタイムダッシュボード
マイクロバッチ5秒〜5分Spark Structured Streaming / DagsterIoT集計、センサー監視
ショートバッチ5分〜1時間頻度の高いバッチEC在庫同期
デイリーバッチ24時間日次バッチ日次レポート、Transform

アーキテクチャ選定フレームワーク

選定判断をシンプルなツリーで整理しました。要件を上から順に確認して、最もシンプルな構成に落ち着かせるのが定石です。

【選定フレームワーク】

Q1. 遅延が24時間以内で良いか?
├── Yes → バッチ処理で確定。Airflow + dbtで十分。
└── No  → Q2. 遅延が5分〜1時間で良いか?
             ├── Yes → ショートバッチ。dbt 1時間ごと + Fivetran15分同期。
             └── No  → Q3. 遅延が5秒〜5分で良いか?
                          ├── Yes → マイクロバッチ。Spark Structured Streaming。
                          └── No  → Q4. ビジネスで秒単位が必要か?
                                      ├── Yes → ストリーム処理。Kafka + Flink。
                                      └── No  → 要件を再検討(たいていはNo)。

まとめ

バッチとストリームは「どちらが優れているか」ではなく「どちらが合うか」で選ぶべきです。バッチは運用が楽でコストも低く、ほとんどのユースケースに適合します。ストリーム処理は真に必要な場面だけで使い、過剰に複雑化させないことが賢明な選択です。

よくある質問

バッチ処理とストリーム処理のどちらを選ぶべきですか?

多くのユースケースではバッチ処理で十分です。秒〜分単位の遅延が許容できない場合(不正検知、リアルタイムレコメンド等)にストリーム処理を検討しましょう。「リアルタイム要件」を鵜呑みにせず、本当の許容遅延をヒアリングで深掘りしてください。

マイクロバッチとストリーム処理の違いは?

マイクロバッチは数秒〜数分間隔の小さなバッチ処理で、Spark Structured Streamingが代表例です。真のストリーム処理(1イベントずつ処理)より実装が容易でコストも低い妥協案です。実務ではマイクロバッチで十分足りる場面が大半です。

ストリーム処理のコストはバッチの何倍ですか?

インフラ・運用コストともにバッチの3〜10倍になるのが一般的です。「24/365で稼働するクラスタ」が必要なため、本当にリアルタイム性が必要か慎重に判断すべきです。費用対効果の議論を必ず通過させてください。