Kafka + Flink + OLAP:一套实时分析架构是怎么跑起来的
实时分析架构的核心不是堆组件,而是把业务事件稳定地采集、缓冲、计算并写入适合查询的分析型数据库。
Kafka + Flink + OLAP:一套实时分析架构是怎么跑起来的
很多业务一开始用定时任务跑报表。每天凌晨从业务库抽数据,算出昨天的 GMV、订单量、活跃用户和转化率。这种方式简单、稳定,也足够支撑早期需求。
但当业务开始要求分钟级甚至秒级指标时,离线任务就不够了。运营想看实时大屏,风控想实时识别异常,推荐想实时更新用户行为,业务方想知道活动刚上线后的转化情况。此时就需要实时分析架构。
整体架构
一套常见实时分析链路是:
业务系统 / 埋点日志 / CDC
↓
Kafka
↓
Flink
↓
ClickHouse / Doris / StarRocks
↓
BI / Dashboard / API
这条链路里,Kafka 负责缓冲和解耦,Flink 负责实时计算,OLAP 数据库负责分析查询。
数据从哪里来
实时数据一般有三类来源。
第一类是业务事件。比如下单、支付、退款、发货、注册、登录。这些事件通常由业务服务主动发送到 Kafka。
第二类是用户行为日志。比如页面访问、点击、曝光、搜索、加购。这类数据通常由前端 SDK、服务端网关或日志采集系统上报。
第三类是 CDC,也就是从 MySQL、PostgreSQL 等业务库的变更日志里捕获数据变化。订单表 insert、支付表 update,都可以被捕获为数据流。
Kafka 的角色
Kafka 最重要的价值是解耦。业务服务只需要把事件写入 Kafka,不需要关心后面有几个消费方。
Kafka 还负责削峰填谷。活动高峰期,事件量可能突然变大,Kafka 可以先把数据堆住,让下游按自己的能力消费。
Kafka 也提供可回放能力。如果 Flink 任务逻辑有问题,可以从某个 offset 重新消费,修复历史指标。
Topic 设计要围绕业务域。订单事件、支付事件、用户行为事件、商品事件可以拆成不同 Topic。分区数则影响并行度和吞吐,但也会影响顺序性和运维成本。
Kafka 里的订单事件可以设计成这样的 JSON:
{
"event_id": "evt_202605170001",
"event_name": "order_paid",
"order_id": "o_10001",
"user_id": "u_90001",
"pay_amount": 199.00,
"channel": "app",
"event_time": "2026-05-17T20:30:00+08:00"
}
Flink 的角色
Flink 负责把原始事件变成可查询的数据。
它可以做清洗,比如过滤无效事件、补齐字段、转换时间格式、解析 JSON。
它可以做维表关联,比如把订单事件里的 sku_id 关联到商品类目,把用户 ID 关联到用户等级。
它可以做窗口聚合,比如每分钟 GMV、每五分钟 UV、每小时接口错误率。
它还可以维护状态,比如用户会话、去重集合、漏斗步骤、累计指标。
Flink 的难点通常在状态和一致性。Checkpoint、Savepoint、状态后端、乱序数据、延迟事件,都需要认真设计。
用 Flink SQL 做一个简单的分钟级 GMV 聚合,大概会长这样:
CREATE TABLE order_events (
order_id STRING,
user_id STRING,
pay_amount DECIMAL(12, 2),
event_time TIMESTAMP(3),
WATERMARK FOR event_time AS event_time - INTERVAL '10' SECOND
) WITH (
'connector' = 'kafka',
'topic' = 'order-events',
'properties.bootstrap.servers' = 'kafka:9092',
'format' = 'json'
);
SELECT
TUMBLE_START(event_time, INTERVAL '1' MINUTE) AS window_start,
TUMBLE_END(event_time, INTERVAL '1' MINUTE) AS window_end,
SUM(pay_amount) AS gmv
FROM order_events
GROUP BY TUMBLE(event_time, INTERVAL '1' MINUTE);
OLAP 数据库的角色
OLAP 数据库负责让指标被快速查询。
如果写入的是明细数据,OLAP 可以支持灵活的多维分析,比如按时间、渠道、城市、商品类目筛选。
如果写入的是聚合结果,查询会更快,更适合实时大屏和固定报表。
常见选择包括 ClickHouse、Doris、StarRocks。ClickHouse 适合高吞吐列式分析,Doris 和 StarRocks 在实时数仓、更新、物化视图和高并发报表上也很常见。
明细表和聚合表
实时分析系统通常不要只保留一种表。
明细表用于追溯和灵活分析。它保存事件级数据,比如每一条订单事件、点击事件、支付事件。
聚合表用于服务高频查询。比如按分钟统计 GMV、按渠道统计 UV、按商品统计销量排行。
明细表更灵活,但查询成本高。聚合表更快,但查询维度固定。两者结合,系统才既能排查问题,也能支撑稳定报表。
一致性问题
实时系统最容易被低估的是一致性。
Kafka 可能重复投递,Flink 可能重启,OLAP 写入可能失败,业务事件可能乱序,客户端上报可能延迟。
因此事件最好有唯一 ID。写入 OLAP 时尽量支持幂等或去重。指标计算要明确窗口、延迟容忍和补偿策略。
很多系统会采用“实时 + 离线校准”的方式。实时链路给出趋势,离线任务在 T+1 重新计算权威结果,修正因为迟到数据或异常重启造成的偏差。
常见问题
Kafka 堆积通常说明下游消费能力不足。可能是 Flink 并行度不够,也可能是外部维表查询太慢,还可能是 OLAP 写入成为瓶颈。
Flink 反压通常说明某个算子处理不过来。需要看算子链路、状态大小、Checkpoint 时间和外部依赖。
OLAP 查询慢通常不是单点原因。可能是分区不合理、排序键不合适、明细表太宽、没有聚合表,也可能是并发和资源隔离问题。
什么时候不需要这套架构
如果数据量不大,指标允许小时级或天级延迟,用定时任务同步到报表库就够了。
如果团队没有流计算运维经验,不要一开始就把 Kafka、Flink、OLAP、数据湖全部堆上来。实时架构的复杂度不仅在开发,更在长期维护。
小结
Kafka + Flink + OLAP 的本质是三段分工:
- Kafka 负责承接数据流。
- Flink 负责实时计算。
- OLAP 数据库负责分析查询。
它适合实时指标、实时大屏、行为分析和实时数仓。但它不是银弹。真正决定系统质量的,是事件模型、数据质量、一致性策略和表设计。