考察点
这道题出自京东大数据开发一面,是项目题里最经典的开场。面试官用一道题同时考察三件事:你是否真的完整做过一条实时链路(而不是只负责过其中一段)、技术选型有没有自己的思考(为什么用 Flink 不用 Spark,为什么用 ClickHouse 不用 MySQL)、架构设计有没有踩过坑后的取舍。答法关键是"总-分-选型理由":先一张架构图式的总览,再逐层讲数据怎么流,每层把选型理由说清楚。追问常往"实时和离线口径怎么对齐"、"Kafka topic 怎么分层"、"ClickHouse 更新场景怎么办"走。
参考答案
架构总览
以电商实时数仓为例,整条链路分四段:数据采集、消息缓冲、实时计算、数据服务。数据源有两类:业务库(订单、支付、商品)走 MySQL binlog,用 Canal 或 Flink CDC 接入;用户行为日志(浏览、点击、加购)由埋点 SDK 上报,经日志服务进 Kafka。Kafka 做统一消息缓冲并承担实时数仓的"ODS"。Flink 做实时加工,按 ODS→DWD→DWS 分层产出。结果数据按用途分流:需要明细查询和报表分析的进 ClickHouse 或 Doris,需要高并发点查的进 Redis/HBase,需要告警的进告警引擎。BI 报表、实时大屏、运营系统在最上层消费。
逐层展开
ODS 层就是 Kafka 里的原始 topic,按数据源分 topic:订单 binlog 一个、支付 binlog 一个、行为日志一个。保留 3-7 天,供回溯和重放。
DWD 层在 Flink 里完成:binlog 解析成统一格式(表名、操作类型、前后镜像),按业务主键去重(binlog 可能重复投递),多流关联补维度——比如订单流关联商品维表。维表关联用 lookup join,维表放 HBase 或 Redis,配 LRU 缓存加异步 IO 扛住流量;行为日志做清洗、过滤爬虫、session 切分。产出写回 Kafka 的 dwd topic。
DWS 层是实时汇总:基于事件时间开窗,产出"分钟级/小时级的类目 GMV"、"实时累计订单量"这类指标,窗口状态放 RocksDB。这一层的取舍值得主动讲:实时 DWS 的维度组合不能像离线那么全,只沉淀最核心的几组(类目、渠道、省份),因为维度爆炸意味着状态爆炸。
服务层分流存放:报表分析进 ClickHouse(明细)和 Doris(聚合,支持更新);点查场景(实时用户标签)进 Redis;告警指标走规则引擎。
技术选型的理由
计算引擎选 Flink 而不是 Spark Streaming,三条理由:毫秒级延迟满足实时大屏和风控场景;事件时间 + watermark 原生支持,订单跨零点、数据乱序场景口径准确;checkpoint + 两阶段提交保证状态一致性,配合 Kafka 事务能做到端到端 exactly-once。京东这种订单链路,跨零点大促的口径准确性是硬需求,这一条基本就锁定了 Flink。
消息中间件选 Kafka:吞吐是硬指标(大促峰值流量是日常的几十倍),分区扩展、消费组多路复用(同一份订单数据,数仓、风控、推荐各消费各的)都是刚需。topic 数会膨胀,要有命名规范和审批。
OLAP 引擎选 ClickHouse 存明细:列存加向量化的聚合性能强,亿级明细秒级出结果,硬件成本比 ES 低一个量级。但 ClickHouse 不擅长更新,所以聚合表、需要回刷修正的数据放 Doris(Unique Key 模型支持 upsert)——两个引擎搭配用是当下的常见组合。点查不用 ClickHouse,它的 QPS 上限和合并压力不适合,高并发点查就该用 Redis/HBase。
接入层 binlog 用 Flink CDC 而不是 Canal + Kafka 中转,理由是少一跳:CDC connector 直接读 binlog,全量 + 增量无缝切换,省掉 Canal 的运维成本和 Kafka 里的中转 topic。存量老系统用 Canal 的继续跑着,新链路直接上 CDC。
实时与离线的一致性
这是实时数仓最大的工程难题,要主动讲。实时链路为了时效性做取舍(维表是当前快照不是历史、迟到数据截断),离线链路是 T+1 全量精算,两边口径天然有差。标准做法是 Lambda 架构的收敛版:实时链路供当天看趋势,离线链路 T+1 修正并覆盖前一日结果,报表系统按日期切换数据源。对账机制要有:每天比对实时与离线的核心指标差异率,稳定在千分之几以内算健康,超过就排查(通常是维表变化或迟到数据导致)。
踩过的坑讲一个
大促时 Kafka 分区数不足导致消费延迟飙升:日常流量下 24 个分区够用,大促峰值写入打满单分区上限,Flink 消费 lag 涨、checkpoint 超时连锁失败。教训是分区数按峰值流量的 1.5 倍规划、大促前压测全链路、以及给核心 topic 配独立的消费组隔离。讲一个真实的坑比罗列十条架构优点更能证明你做过。
可能的追问
- 为什么不用 Kappa 架构彻底替代 Lambda?想法好但前提是所有口径都能用实时重算解决,历史数据重放在 Kafka 保留期、计算成本上都受限;实操是"实时增量 + 离线校准"混合。
- 维表 join 的时效性怎么处理?维表变化敏感的场景(如商品类目调整),把维表变更也做成一条流,用 temporal join 按事件时间匹配当时的维度版本,而不是 lookup 当前值。
- 状态多大、checkpoint 怎么配的?讲出量级(比如 RocksDB 状态几百 GB、checkpoint 间隔 3 分钟、开启增量快照和非对齐),数字不必精确但要有量级感。