1. 实时数仓概述

大家好,我是老张。做大数据这行十几年了,从离线数仓到实时数仓,踩过的坑不少。今天咱们聊聊实时数仓的入门话题——它到底是什么,跟离线数仓有啥区别,用在哪儿,以及技术选型怎么选。

说实话,我刚接触实时数仓那会儿,也觉得不就是把批处理改成流处理嘛。后来真正上手才发现,事情没那么简单。

1.1 实时数仓 vs 传统离线数仓

先看一张对比图,帮你快速建立整体认知。

实时数仓 vs 离线数仓 核心差异 传统离线数仓 T+1 延迟,按天/小时调度 批处理引擎(Hive/Spark SQL) 数据量大,全量/增量合并 适合历史分析、报表、BI 实时数仓 秒级/分钟级延迟,持续计算 流处理引擎(Flink/Spark Streaming) 数据量适中,增量流式处理 适合实时大屏、风控、推荐 核心区别:离线数仓追求“准”,实时数仓追求“快” 两者不是替代关系,而是互补——离线做深度分析,实时做敏捷响应

离线数仓,说白了就是 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 是当前最稳妥的组合。