1. 实时数仓概述
大家好,我是老张。做大数据这行十几年了,从离线数仓到实时数仓,踩过的坑不少。今天咱们聊聊实时数仓的入门话题——它到底是什么,跟离线数仓有啥区别,用在哪儿,以及技术选型怎么选。
说实话,我刚接触实时数仓那会儿,也觉得不就是把批处理改成流处理嘛。后来真正上手才发现,事情没那么简单。
1.1 实时数仓 vs 传统离线数仓
先看一张对比图,帮你快速建立整体认知。
离线数仓,说白了就是 T+1 的模式。今天的数据,明天才能看到。我早年做离线数仓的时候,每天凌晨跑一堆 Hive 任务,早上 8 点前出报表。业务方习惯了,也没觉得有啥问题。
但后来业务变了。老板要实时大屏,运营要看分钟级转化率,风控要秒级拦截异常交易。离线数仓那套就不够用了。
实时数仓的核心区别在于:数据从产生到可查询,延迟从小时级降到秒级。它不是简单地把批处理改成流处理,而是整个架构思路都要变。
| 对比维度 | 离线数仓 | 实时数仓 |
|---|---|---|
| 数据延迟 | T+1 / 小时级 | 秒级 / 分钟级 |
| 计算引擎 | Hive、Spark SQL、Presto | Flink、Spark Streaming、Kafka Streams |
| 存储选型 | HDFS、Hive 表、ClickHouse | Kafka、Redis、Druid、ClickHouse |
| 数据模型 | 星型/雪花模型,宽表 | 流式表、动态聚合、OLAP 预计算 |
| 容错机制 | 任务重跑即可 | Exactly-Once、状态恢复、Checkpoint |
| 适用场景 | 历史趋势、财务对账、深度分析 | 实时大屏、实时风控、实时推荐 |
我的经验:别一上来就想用实时数仓替代离线数仓。我见过不少团队,把离线那套照搬到实时上,结果数据对不上、延迟降不下来。正确的做法是:离线数仓做底座,实时数仓做上层敏捷层,两者共存。
1.2 实时数仓的应用场景
你想想看,哪些场景非实时不可?我总结了三类典型场景。
场景一:实时大屏与运营监控
这是最常见的入口。双十一大屏、GMV 实时看板、用户活跃度曲线。业务方要的是「现在这一刻」的数据,不是昨天的。
我记得有一次双十一,大屏上的实时 GMV 比离线报表少了 2%。排查了半天,发现是实时链路里丢了一条 Kafka 消息。从那以后,我养成了一个习惯——实时链路必须做数据对账。
场景二:实时风控与异常检测
金融交易、反欺诈、账号安全。这类场景对延迟极其敏感。一笔异常交易,晚 10 秒拦截,钱可能就转走了。
实时数仓在这里的角色是:在数据流经 Kafka 时,用 Flink 做规则匹配和特征计算,毫秒级输出风险评分。离线数仓根本做不到这个速度。
场景三:实时推荐与个性化
用户刚点了一个商品,推荐系统要立刻更新候选集。如果等离线任务跑完,用户早走了。
实时数仓在这里提供的是「用户实时行为画像」——点击、加购、收藏、下单,这些事件流经过实时数仓,变成用户标签,推给推荐引擎。
核心判断标准:如果业务决策的窗口期在分钟级以上,离线数仓就够了。如果窗口期在秒级,或者需要「当前状态」做决策,那就得上实时数仓。
1.3 实时数仓的技术选型
技术选型这块,我踩过的坑最多。市面上工具太多了,选错了后面改起来很痛苦。
我个人的选型思路是:先定引擎,再定存储,最后定消息队列。为什么这个顺序?因为引擎决定了你的开发模式和容错能力。
计算引擎:Flink 是当前主流
目前实时数仓领域,Flink 基本是事实标准。Spark Streaming 虽然也能做,但它在事件时间语义、状态管理、Checkpoint 机制上不如 Flink 成熟。
我最早用 Spark Streaming 做实时数仓,遇到水位线乱序的问题,处理起来很麻烦。后来切到 Flink,这些问题迎刃而解。
// Flink 实时数仓典型入口代码
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
env.enableCheckpointing(60000, CheckpointingMode.EXACTLY_ONCE);
// 从 Kafka 读取 ODS 层数据
DataStream<String> sourceStream = env
.addSource(new FlinkKafkaConsumer011<>("ods_order", new SimpleStringSchema(), kafkaProps))
.assignTimestampsAndWatermarks(new BoundedOutOfOrdernessTimestampExtractor<String>(Time.seconds(10)) {
@Override
public long extractTimestamp(String element) {
return JSON.parseObject(element).getLong("event_time");
}
});
消息队列:Kafka 是标配
实时数仓的数据管道,Kafka 几乎是唯一选择。它高吞吐、持久化、支持多消费者。我建议用 Kafka 做 ODS 层的数据总线,所有业务数据先进 Kafka,再分流到不同实时任务。
避坑指南:我曾经在一个项目里用 RabbitMQ 做实时数仓的消息队列,结果数据量一上来就积压。RabbitMQ 适合小规模异步消息,不适合大数据量的流式管道。实时数仓的消息队列,老老实实用 Kafka。
存储选型:分层搭配
实时数仓的存储不像离线那么单一。不同层用不同的存储:
| 数仓分层 | 推荐存储 | 原因 |
|---|---|---|
| ODS(操作数据层) | Kafka | 原始数据流,不落地,高吞吐 |
| DWD(明细数据层) | Kafka + HBase | 明细数据需要随机查询,HBase 适合 |
| DWS(汇总数据层) | ClickHouse / Druid | OLAP 查询,秒级聚合,列式存储 |
| ADS(应用数据层) | Redis / MySQL | 高并发查询,低延迟,KV 或关系型 |
选型总结
我建议你记住这个组合:Flink + Kafka + ClickHouse。这是目前国内互联网公司最主流的实时数仓技术栈。当然,如果你们公司有历史包袱,比如已经用了 Spark,那 Spark Streaming 也能用,只是有些坑要自己填。
我的建议:技术选型不要追求「最新」,要追求「最稳」。Flink 1.12 之后的版本都比较成熟,Kafka 2.4+ 也够用。别一上来就上 Flink 1.17,等社区验证半年再说。
本章小结
实时数仓不是离线数仓的替代品,而是互补品。它解决的是「快」的问题,离线解决的是「准」和「深」的问题。应用场景集中在实时大屏、实时风控、实时推荐这三个方向。技术选型上,Flink + Kafka + ClickHouse 是当前最稳妥的组合。