4、数据集成基础:数据集成概念、ETL与ELT流程、批处理与流处理的基本概念
4.1 数据集成的本质与核心挑战
数据集成是将分散在不同数据源、不同格式、不同时效要求的数据,按照统一的标准进行抽取、转换、加载,从而形成可供分析、决策或应用直接使用的数据资产的过程。在湖仓架构中,数据集成的目标不仅是“把数据搬过来”,更是要建立一条可靠、可追溯、低延迟的数据管道,让数据从产生到消费的路径清晰可控。
理解数据集成的核心,需要抓住三个关键维度:
- 多样性(Variety):数据源可能是关系型数据库(MySQL、PostgreSQL)、日志文件(Nginx、Flume)、消息队列(Kafka、Pulsar)、NoSQL(MongoDB、HBase),甚至SaaS API。每种源的协议、字段语义、更新机制都不同。
- 时效性(Velocity):有的报表只需T+1更新,有的风控规则需要秒级响应。集成架构必须能同时容纳批量与实时两类通道。
- 一致性(Consistency):跨源数据在合并时可能遇到主键冲突、时区差异、精度丢失、删除标记不一致等问题。集成过程必须定义明确的冲突解决策略。
4.2 ETL 与 ELT:两种流程范式的取舍
ETL(Extract-Transform-Load)与 ELT(Extract-Load-Transform)是数据集成最经典的两种流程编排方式。它们的核心差异在于“转换发生在哪里”——是在数据进入目标系统之前,还是之后。
ETL 流程(传统数仓):数据先经过独立的转换引擎(如 Informatica、DataStage)完成清洗、关联、聚合,再将结果加载到目标库。这种方式适合计算资源受限、目标库能力较弱的时代,但缺点是转换逻辑与数据源耦合紧密,扩展性差。
ELT 流程(云原生/湖仓):数据先以原始格式快速加载到数据湖或云数仓(如 Snowflake、Redshift、Iceberg),转换动作交给目标系统内部的强大计算引擎(如 Spark、Presto)按需执行。这种方式充分利用了湖仓的弹性算力,让原始数据得以保留,支持事后回溯与灵活建模。
| 对比维度 | ETL(先转换后加载) | ELT(先加载后转换) |
|---|---|---|
| 适用场景 | 传统企业数仓、强监管报表 | 数据湖、云数仓、敏捷分析 |
| 数据保留 | 仅保留转换后结果,原始数据易丢失 | 原始数据完整保留,可追溯 |
| 转换成本 | 需要独立ETL服务器,硬件成本高 | 利用目标端弹性算力,按需付费 |
| 开发效率 | 转换逻辑需预先定义,变更周期长 | 数据到位后随时定义转换,迭代快 |
| 典型工具 | Informatica、DataStage、Kettle | Flink、Spark、dbt、Airbyte |
4.3 批处理与流处理:时间维度的两种世界观
批处理(Batch Processing)与流处理(Stream Processing)的差异,本质上是“处理时间窗口”的不同。批处理假设数据是“有界的”(Bounded),即一批数据有明确的开始和结束;流处理则假设数据是“无界的”(Unbounded),数据像水流一样持续到达,永不停歇。
批处理适合对历史数据进行全量重算或周期汇总。例如每天凌晨计算前一天的GMV、每周生成用户活跃报表。批处理的优势是逻辑简单、易于重试,缺点是数据延迟高(至少等待一个调度周期)。
流处理则强调“记录一到即处理”,常用于实时风控、实时大屏、异常监控等场景。流处理需要额外考虑事件时间(Event Time)与处理时间(Processing Time)的区别,以及乱序数据的处理策略(Watermark机制)。
-- 批处理典型调度(以SQL表达)
INSERT INTO dws_order_daily
SELECT order_date, SUM(amount)
FROM ods_orders
WHERE order_date = CURRENT_DATE - 1
GROUP BY order_date;
-- 流处理典型逻辑(以Flink SQL表达)
CREATE STREAM orders_stream (order_id STRING, amount DOUBLE, ts TIMESTAMP)
WITH ('connector' = 'kafka', 'topic' = 'orders', 'format' = 'json');
INSERT INTO dws_order_realtime
SELECT TUMBLE_START(ts, INTERVAL '1' MINUTE) AS window_start,
SUM(amount) AS total_amount
FROM orders_stream
GROUP BY TUMBLE(ts, INTERVAL '1' MINUTE);
在湖仓架构中,批与流并非互斥,而是通过Lambda架构或Kappa架构进行统一。Lambda架构同时维护批量层与速度层,最终在服务层合并结果;Kappa架构则只用一套流处理引擎,将历史数据“回放”到Kafka中重新计算,简化了运维复杂度。
4.4 案例:电商订单实时同步与离线补数
某电商平台需要将订单数据从业务库同步到湖仓,同时满足运营报表(T+1)和实时大屏(秒级)两类需求。其集成方案如下:
- 实时通道:通过Canal监听MySQL Binlog,将订单变更事件发送至Kafka。Flink消费Kafka数据,进行简单的字段映射和金额单位统一后,写入Doris的实时明细表,同时更新Redis中的今日实时GMV。
- 批量通道:每天凌晨,由调度系统触发Spark任务,从MySQL直接全量抽取前一天订单(或从Iceberg快照读取),进行复杂的维度关联(用户、商品、优惠券)和去重后,覆盖写入DWD层。
- 数据校验:每日9点运行比对任务,核对实时通道与批量通道的订单总数和金额差异,差异率超过0.1%则触发告警并自动重跑批量任务。
4.5 集成设计中的关键复盘
在数据集成项目落地后,团队常会复盘出以下几条经验,值得在架构设计初期就纳入考量:
- 先定义数据契约,再开发管道:每个数据源应有明确的Schema版本、字段含义、更新频率和负责人。没有契约的集成,后期维护成本会指数级上升。
- 监控必须覆盖“数据质量”而非仅“任务状态”:任务跑成功不代表数据正确。要设置行数波动告警、空值率告警、主键唯一性校验等质量规则。
- 重视幂等性设计:无论是批处理重跑还是流处理重启,都要保证结果一致。批量写入时使用分区覆盖或主键去重;流处理使用Kafka Offset管理加事务性输出。
- 不要忽略元数据管理:当管道数量超过50条时,手动维护字段映射关系将变得不可行。应尽早引入元数据中心,自动采集血缘关系。