实时数仓要不要建?——别急着上 Flink,先问这三个问题
本文目录
先说结论
实时数仓不是能不能建的问题,是『需要不需要』的问题。实时的技术壁垒已经很低,但运维和成本压力很大——要不要上实时,先问业务方『晚 1 小时出数据会死人吗』。
实时数仓的价值只有三个场景:(1)运营决策要分钟级响应(投放、风控);(2)用户端实时看到(推荐、大屏);(3)故障监控(数据链路本身的实时告警)。这三个之外都可以用离线。
实时和离线要并行运行。实时用于当日看板,离线用于修正最终口径。两者数据必然有小偏差,要建立分治机制。
先把这段讲顺;面试官追问时,再展开下面的原理和细节。
详细讲解
架构阶段的最后一道题:『你怎么看实时数仓?你们建不建?』这是一道价值观题。答『当然要建、Flink 是未来』或者『实时没必要、离线够用』都是外行。面试官想听的是:你懂不懂实时的代价、能不能判断什么场景值得上实时、有没有实际落地或推翻过实时方案。
业务场景:我在某元宇宙社交应用从 0 搭实时数仓
我在某元宇宙社交应用做过从 0 搭实时数仓的项目,技术栈 Flink + Kafka + Doris。当时的业务诉求有三个:(1)虚拟礼物打赏的实时大屏(看各主播的实时收入);(2)反作弊系统需要分钟级异常检测;(3)运营需要按分钟看 DAU 趋势。这三个都是非实时不可的场景——运营等 T+1 已经错过了反应窗口。
Plain
实时数仓的典型架构(我当时的设计):
[埋点 SDK] ─┐
├─→ [Kafka] ─→ [Flink] ─┬─→ [Doris] ─→ BI 大屏
[业务DB] ──┘ ├─→ [Redis] ─→ 反作弊
(Binlog) └─→ [Kafka] ─→ 下游实时应用
并行离线(T+1 兜底):
[Kafka] ─→ [Hive/MaxCompute] ─→ [ADS] ─→ 同一个 BI 大屏
策略:
当日 0-24 点:BI 看实时链路(Doris)
隔日 0 点后:BI 自动切换到离线口径(修正数据)
两份数据差异通常 < 0.5%,业务方可接受
段落一:三个问题决定要不要建实时
问题一:业务容忍的延迟是多少?——如果业务方说『早上 8 点看前一天就够』,直接离线解决;如果说『我需要看当前这一分钟』,那必须实时。中间灰色地带(小时级、半天级)要深聊——很多时候业务方只是想快,但能接受 T+1。
问题二:实时能带来多少额外业务收益?——如果运营看到分钟级数据能多赚 10%,值得上;如果只是『看起来酷』,不值得。推给业务方算一笔账:实时投入 20 万 / 年(含人力和资源),能多带多少业务收入?
问题三:团队有能力运维吗?——Flink 的运维比离线难一个量级。Checkpoint、State Backend、Watermark、Exactly Once 这些都是坑。3 人以下的小团队慎上实时。
段落二:实时数仓的额外成本
| 维度 | 离线成本 | 实时成本 |
|---|---|---|
| 开发复杂度 | SQL 中心、相对简单 | 状态管理、水位线、精确一次都要懂 |
| 测试成本 | 可重放、易验证 | 流式难重现、调试复杂 |
| 运维成本 | 失败重跑即可 | 状态丢失 = 数据丢失,故障恢复复杂 |
| 资源成本 | 按计算量付费、不用时不耗 | 7×24 常驻、资源消耗持续 |
| 人员要求 | SQL + 数仓建模即可 | + Flink / 状态管理 / 流处理理论 |
我的保守估计:同等业务诉求下,实时数仓的总成本(开发 + 运维 + 资源)是离线的 3-5 倍。这个账业务方必须清楚。
段落三:Lambda vs Kappa 架构
实时数仓两大流派:Lambda(实时 + 离线并行)和 Kappa(纯实时)。
| 架构 | 思路 | 优点 | 缺点 |
|---|---|---|---|
| Lambda | 实时链路出当日数据,离线链路隔日修正 | 容错好、离线兜底、回溯容易 | 维护两套代码、口径易分歧 |
| Kappa | 只有一条实时链路,历史数据从 Kafka 回放 | 代码一份、简单 | Kafka 保留代价高、回放慢 |
| Lakehouse | 数据湖 + 流批一体 | 最现代、结合两者优点 | 工具链还在演进、门槛高 |
我的选择:大多数业务用 Lambda——两套链路对业务方是透明的,分治反而更可靠。只有小团队 / 小业务才上 Kappa。Lakehouse(Iceberg + Flink)是未来方向但现在落地成本还大,除非团队有强 infra 能力。
段落四:实时数仓的分层
Plain
实时数仓的四层(和离线概念类似但机制不同):
ODS(实时原始层):
- 数据:Kafka 直接消费
- 存储:Kafka Topic 本身
- 保留:7 天
DWD(实时明细层):
- 数据:清洗 + 维度 join
- 存储:Kafka(下游订阅)+ Hologres/Doris(可查)
- 处理:Flink 实时计算
DWS(实时汇总层):
- 数据:分钟级窗口聚合
- 存储:Doris/Hologres
- 状态:Flink 管理滚动窗口
ADS(实时应用层):
- 数据:拼接后直接对外
- 存储:Doris/Hologres/Redis
- 使用:大屏 / API / 告警
段落五:实时和离线的口径对齐
实时和离线并行最难的是口径对齐。实时因为迟到数据、状态过期、去重不彻底等原因,和离线必然有小差异。
Plain
常见的实时离线差异原因:
1. 迟到数据
- 实时:超出 watermark 就丢弃或打侧输出
- 离线:按 event_time 回写历史分区,数据完整
2. 去重策略
- 实时:基于 state + TTL,过了 TTL 就认为是新的
- 离线:全量去重,永远准确
3. 维度关联
- 实时:异步 join 维表,可能用到稍旧的维度
- 离线:直接 join 当日维表,最新
业务协同方案:
- 当日 0-24 点业务方看实时(容忍 < 0.5% 误差)
- 次日 0 点之后自动切到离线口径
- 日报以离线为准,看板标注 '隔日口径修正'
面试高频追问
追问一:用 client 模式提交 Flink 作业行不行?
生产绝对不行。我在某元宇宙社交应用踩过两次血坑:(1)一个同事用 client 模式提交生产作业然后关笔记本,Driver 挂了整个作业跟着挂,生产事故;(2)跳板机被 client 模式的 Driver 吃满内存,其他人无法登录。生产必须用 per-job 或 application 模式,Driver 跑在集群不是跑在本地。
追问二:Flink 的 Exactly Once 怎么保证?
两步保证:(1)Source 端支持 offset 回放(Kafka 是天然支持的);(2)Sink 端支持事务或幂等写入——要么两阶段提交(比如 Kafka / JDBC Sink 的 TwoPhaseCommitSinkFunction),要么写入系统自己保证幂等(比如 Hologres 支持 upsert)。加上 checkpoint 机制,保证了状态和 offset 的原子提交。实操里:Kafka → Flink → Hologres 是最常见的稳定 exactly once 方案。
追问三:实时数仓状态爆炸怎么办?
状态爆炸是最常见的实时事故。原因:(1)没设 TTL;(2)key 基数无限(比如按 uid 聚合但 uid 永不清理)。解决:(1)所有状态必须有 TTL,业务侧明确『多久之后的数据可以丢』;(2)对高基数 key 考虑按更粗粒度聚合(比如按 uid 改成按 country);(3)用 RocksDB StateBackend(磁盘兜底)而不是 MemoryStateBackend。我做过一次排查,发现状态无 TTL 跑了 3 个月涨到 800GB,改完 TTL 一小时内降到 20GB。
实战踩坑:一个 Kafka 分区数配少了引发的雪崩
我在某元宇宙社交应用做实时数仓时还踩过一个坑:Kafka topic 的分区数设置了 12,Flink 作业的并发度设置了 32——Flink 期望 32 个 sub-task 平行消费,但 Kafka 只有 12 个分区,导致 20 个 sub-task 空转,吞吐反而下降。更严重的是当业务流量峰值来了,12 个分区的消费能力跟不上,Lag 急剧上升最终告警。
教训:Kafka 分区数要 ≥ Flink 并发度,且要给未来 2-3 倍的扩容余量。我的经验值:按峰值 QPS / 单分区消费能力 × 2 算出分区数。一旦上线改分区数很麻烦(要 rebalance),所以一开始就要预估好。
总结
实时数仓题的高分答案有三层:(1)判断力——能说出三个场景问题来决定要不要上实时;(2)架构观——讲清 Lambda vs Kappa、实时分层、口径对齐;(3)实操经验——Flink 状态、Exactly Once、client 模式的坑等。最忌讳的是无脑吹实时或无脑贬实时——都是没做过项目的表现。
下一篇:『请用 STAR 讲一个你做过最复杂的项目』——面试收尾阶段第一道软题。STAR 模型人人都会背,讲出高分版本的没几个。
你们公司建实时数仓了吗?当初是业务驱动还是技术驱动?上了之后 ROI 划算吗?
关注「Wood聊大数据」| 9年大数据老兵,聊技术、聊职场、聊成长