1. 先搞清楚一件事
离线数仓和实时数仓不是两套对立的系统,而是同一条数据管道上的两个节奏。
| 一句话 | 算得全、算得准 | 算得快、看得早 |
| 延迟 | 小时 ~ 天 | 秒 ~ 分钟 |
| 核心动作 | 批量跑批(Batch) | 流式处理(Streaming) |
| 适合场景 | T+1 报表、月度复盘 | 实时监控、秒级推荐 |
大多数企业两者都需要,不是二选一的问题。
2. 从一个场景看差异
还是电商。大促当天:
- 实时数仓在干的事:每秒汇总各品类 GMV、实时监控库存预警、动态调整推荐策略。延迟 5 秒,运营看到"手机品类 1 小时破 10 亿"。
- 离线数仓在干的事:第二天凌晨跑批,统计"昨天全网各品类销售额、退货率、用户分层"。延迟 12~24 小时,管理层看完整日报。
一个是战场上的指挥屏,一个是战后的复盘报告。
3. 架构对比
3.1 离线数仓架构
数据源 离线计算 输出
┌──────┐ 批量采集 ┌────────────┐ 调度引擎 ┌────────────┐
│ 业务DB│───Sqoop────→│ Hive / │───Airflow──→│ 报表/BI │
│ │ │ Spark SQL │ 定时调度 │ ADS 层 │
│ 日志 │───Flume────→│ (批处理) │ │ │
└──────┘ └─────────────┘ └────────────┘
按天/小时分区 全量/增量批处理 T+1 产出
特征:
- 数据按时间分区(dt=2026-06-18)
- 调度引擎定时触发(每天凌晨 2 点跑批)
- 计算引擎一次性读入全部数据,做 JOIN、聚合、窗口计算
- 产出结果写入 Hive 表或同步到 MySQL/Redis 供 BI 查询
3.2 实时数仓架构
数据源 实时计算 输出
┌──────┐ CDC/日志 ┌────────────┐ 写入 ┌───────────┐
│ 业务DB│───Kafka───→│ Flink / │───ClickHouse─→│ 实时监控 │
│ │ │ Spark │ StarRocks │ 推荐引擎 │
│ 日志 │───Kafka───→│ Streaming │ │ 大屏展示 │
└──────┘ └────────────┘ └───────────┘
变更捕获 流式处理 秒级可见
特征:
- 数据通过 CDC(Change Data Capture) 或日志实时采集到 Kafka
- 计算引擎常驻运行,持续消费数据流
- 增量更新,不做全量扫描
- 结果直接写入 OLAP 引擎或 KV 存储,供实时查询
3.3 一张图看清差异
离线数仓 实时数仓
│ │
│ ┌──────────────┐ │ ┌──────────────┐
├─→│ 数据采集 │ ├─→│ 数据采集 │
│ │ Sqoop/DataX │ │ │ Flink CDC │
│ │ Flume/Canal │ │ │ Flume │
│ └──────┬───────┘ │ └──────┬───────┘
│ │ 批量传输 │ │ 实时流
│ ┌──────▼───────┐ │ ┌──────▼───────┐
├─→│ 存储 │ ├─→│ 消息队列 │
│ │ HDFS / S3 │ │ │ Kafka / │
│ │ 分区文件 │ │ │ Pulsar │
│ └──────┬───────┘ │ └──────┬───────┘
│ │ 定时触发 │ │ 持续消费
│ ┌──────▼───────┐ │ ┌──────▼───────┐
├─→│ 计算引擎 │ ├─→│ 计算引擎 │
│ │ Hive SQL │ │ │ Apache Flink │
│ │ Spark SQL │ │ │ Spark Stream │
│ │ 批处理 │ │ │ 流处理 │
│ └──────┬───────┘ │ └──────┬───────┘
│ │ │ │ 实时写入
│ ┌──────▼───────┐ │ ┌──────▼───────┐
└─→│ 输出 │ └─→│ 输出 │
│ Hive / MySQL │ │ ClickHouse / │
│ 报表/BI │ │ StarRocks / │
└──────────────┘ │ Redis / 大屏 │
└──────────────┘
4. 核心差异逐项对比
4.1 延迟与吞吐量
| 数据延迟 | 小时 ~ 天 | 秒 ~ 分钟 |
| 单次数据量 | 大(TB 级批处理) | 小(逐条/微批) |
| 总体吞吐量 | 高(批量处理效率高) | 中高(持续流式) |
| 端到端时效 | T+1 或小时级 | 秒级(P99 < 10s) |
关键点:离线追求"单位时间处理量大",实时追求"端到端延迟低"。两者的吞吐量不一定谁高谁低,但延迟是数量级差异。
4.2 数据模型与更新语义
| 数据更新方式 | 追加写入(Append) | 流式追加 / Upsert |
| 历史数据 | 保留全量历史快照 | 通常只保留最新状态 |
| 数据一致性 | 最终一致性(批处理保证) | 近似一致(允许短暂乱序) |
| 数据模型 | 维度模型 / 3NF | 宽表 / 预聚合 Cube |
| 状态管理 | 无状态(每批次独立计算) | 有状态(窗口、Session) |
难点:实时数仓要处理乱序数据(Late Data)和数据回退(Retraction),这在离线场景里通过重跑批处理就能解决,在实时场景里需要额外机制(如 Watermark、两阶段提交)。
4.3 技术栈对比
| 数据采集 | Sqoop、DataX、Flume、Canal | Flink CDC、Debezium、Flume |
| 存储层 | HDFS、S3 | Kafka、Redis、HBase、HDFS |
| 计算引擎 | Hive、Spark SQL、Presto | Apache Flink、Spark Streaming、Kafka Streams |
| 调度引擎 | Airflow、DolphinScheduler、Azkaban | 无(常驻服务) |
| OLAP 引擎 | Hive、Presto、Impala | ClickHouse、StarRocks、Apache Doris |
| 数据湖 | Hive 分区表、Iceberg、Delta Lake | Iceberg、Hudi、Paimon |
4.4 运维复杂度
| 部署复杂度 | 中(批处理集群) | 高(流式集群 + 消息队列) |
| 故障恢复 | 重跑失败任务即可 | Checkpoint + 回滚消费位点 |
| 监控重点 | 任务完成时间、数据完整性 | 延迟、吞吐、Checkpoint 成功率 |
| 人力要求 | SQL 工程师为主 | 需要流计算专业知识 |
| 成本 | 较低(计算资源按需使用) | 较高(常驻集群 + 高可用) |
5. 数仓分层:离线与实时的交汇点
不管离线还是实时,分层思想是一样的:
┌─────────────────────────────────────────────────────────┐
│ ADS 层(应用数据层) │
│ 离线:T+1 报表 │
│ 实时:秒级大屏、实时推荐 │
├─────────────────────────────────────────────────────────┤
│ DWS 层(汇总数据层) │
│ 离线:每日聚合(按天分区) │
│ 实时:滚动窗口聚合(分钟级更新) │
├─────────────────────────────────────────────────────────┤
│ DWD 层(明细数据层) │
│ 离线:清洗后的明细表(按天分区) │
│ 实时:清洗后的明细流(Kafka Topic) │
├─────────────────────────────────────────────────────────┤
│ ODS 层(原始数据层) │
│ 离线:原始数据同步(T+1) │
│ 实时:CDC 实时捕获变更流 │
└─────────────────────────────────────────────────────────┘
关键认知:分层是逻辑概念,离线和实时只是数据在不同时间点到达同一层。同一张表可以同时有离线版和实时版。
6. 混合架构:Lambda vs Kappa
当企业同时需要离线和实时能力时,有两种经典架构:
6.1 Lambda 架构(批流分治)
┌──────────────┐
数据源 ──Kafka────→ │ 流处理层 │──→ 实时服务(秒级)
│ │ Flink │
│ └──────────────┘
│
└──→ ┌──────────────┐
│ 批处理层 │──→ 离线服务(T+1)
│ Spark/Hive │
└──────────────┘
两套逻辑、两套代码、两套存储
优点:批处理和流处理各自优化,互不干扰。 缺点:同一业务逻辑要写两遍(批处理写一遍 SQL,流处理写一遍 Flink Job),容易不一致。
6.2 Kappa 架构(流批一体)
┌──────────────┐
数据源 ────────Kafka──────→ │ 流处理层 │──→ 实时 + 离线服务
│ Flink │
└──────────────┘
一套逻辑、一套代码、流处理即一切
优点:只维护一套代码,逻辑一致。 缺点:流处理做复杂批计算(如全量 JOIN)性能不如批处理;历史数据回放需要时间。
6.3 实际选择
| 实时需求简单,离线为主 | Lambda(流处理只做简单预聚合) |
| 实时需求复杂,要求逻辑一致 | Kappa(流批一体) |
| 两者都要,资源充足 | Lambda + 数据湖(Iceberg/Hudi 打通批流) |
现代趋势:流批一体是方向。Apache Flink 的 Batch + Stream 统一 API、Iceberg 的流式读写、StarRocks 的实时 + 离线混合负载,都在推动两者融合。
7. 常见误区
误区一:“实时数仓能完全替代离线数仓”
❌ 实时数仓在处理大规模历史数据回溯、复杂多表 JOIN、数据质量校验方面不如离线数仓高效。全量重算一个月的数据,用 Spark 跑 2 小时,用 Flink 重放可能要 2 天。
✅ 两者互补。实时做"快速感知",离线做"深度分析"。
误区二:“上了 Kafka + Flink 就是实时数仓”
❌ 技术栈不等于数仓。实时数仓的核心是数据分层、口径统一、质量保障,不是工具堆砌。没有统一口径的实时数仓,产出的是"快速但不可信的数据"。
✅ 先设计数据模型和分层规范,再选技术栈。
误区三:“实时数仓的数据一定比离线准”
❌ 实时数仓为了低延迟,通常牺牲了部分准确性:允许乱序、允许近似计算、允许短暂不一致。离线数仓通过全量重算保证最终准确。
✅ 关键指标用离线数仓做"对账",实时数仓做"预警"。
误区四:“小团队应该直接上实时数仓”
❌ 实时数仓的运维成本、人力要求、基础设施投入远高于离线数仓。一个 5 人团队,用 Hive + Spark 跑离线批处理,性价比远高于上 Flink 全家桶。
✅ 先用离线数仓把数据基础打扎实,再按需引入实时能力。
8. 选型决策树
你的核心需求是什么?
│
├─ 只需要 T+1 报表、月度分析
│ → 离线数仓(Hive + Spark + Airflow)
│
├─ 需要秒级实时监控,但数据量小
│ → 轻量实时(Flink CDC → ClickHouse)
│
├─ 既要实时监控,也要 T+1 完整报表
│ → 混合架构(Lambda 或 Kappa)
│
├─ 预算有限,团队 5 人以下
│ → 先离线,后实时(渐进式)
│
└─ 大规模数据 + 高实时性要求
→ 流批一体 + 数据湖(Flink + Iceberg + StarRocks)
9. 总结
| 一句话 | 算得全、算得准 | 算得快、看得早 |
| 延迟 | 小时 ~ 天 | 秒 ~ 分钟 |
| 计算模式 | 批量处理 | 流式处理 |
| 数据模型 | 分区表、全量快照 | 宽表、增量更新 |
| 一致性 | 强一致(批保证) | 最终一致(允许乱序) |
| 运维成本 | 中 | 高 |
| 适用场景 | 日报、月报、数据分析 | 实时监控、推荐、风控 |
不要问"哪个更先进",要问"我的业务需要什么节奏"。大多数企业的真实答案是:离线打底,实时加分。先把离线数仓建扎实,再根据业务需要逐步引入实时能力,才是最务实的路径。
参考资源
- Nathan Marz, How BigQuery’s Real-time Analytics Works
- Jay Kreps, The Log
- Apache Flink 官方文档:Streaming Concepts
- 阿里云实时数仓白皮书:Real-time Data Warehouse Architecture
- 美团技术博客:实时数仓在美团外卖的实践





