バッチ処理とストリーム処理、どちらを選ぶべきか――この問いに対する正直な答えは「まずバッチで始めて、必要な時だけストリームに進む」です。本記事では両者の違いを遅延・スループット・コスト・複雑さで比較し、ユースケース別の選定フレームワークを解説します。
バッチ処理とストリーム処理の定義
バッチ処理は「一定間隔で溜まったデータをまとめて処理する」方式、ストリーム処理は「データが発生した瞬間に逐次処理する」方式です。両者の処理フローを対比した図を示します。
【バッチ処理 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〜TB | MB〜TB(流量次第) |
| 代表ツール | Airflow / dbt / Spark Batch | Kafka / Flink / Spark Streaming |
| 監視難易度 | 低 | 高 |
| 運用チーム規模 | 小〜中 | 中〜大 |
「リアルタイム」の定義を疑う
「リアルタイム」と一言で言っても、実際には幅があります。1秒以内のハードリアルタイムから、5分間隔のマイクロバッチまで、実装コストは1桁以上違います。要件ヒアリングで「リアルタイムにしたい」と言われても、その裏にある本当の要件を掘り下げてみると、実はマイクロバッチで足りるケースが多々あります。
| カテゴリ | 遅延 | 実装方式 | コスト傾向 | ユースケース例 |
|---|---|---|---|---|
| ハードリアルタイム | 数ミリ秒 | インメモリ処理 + ストリーム | 高 | 広告入札、金融取引 |
| ニアリアルタイム | 1秒〜数秒 | ストリーム処理 | 中〜高 | 不正検知、リアルタイムダッシュボード |
| マイクロバッチ | 5秒〜5分 | Spark Structured Streaming / Dagster | 中 | IoT集計、センサー監視 |
| ショートバッチ | 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で稼働するクラスタ」が必要なため、本当にリアルタイム性が必要か慎重に判断すべきです。費用対効果の議論を必ず通過させてください。