要设计一个既能处理批量数据又能处理流式数据的 ETL 过程,首先要为每种数据类型创建独立但集成的管道,同时维护一个统一的存储层。批量处理以预定间隔(例如,每日销售报告)处理大型静态数据集,而流式处理则持续处理实时数据(例如,物联网传感器数据)。使用混合架构,例如结合了批量层和流式层的“Lambda 架构”,或者现代替代方案如“Kappa 架构”,后者对批量和流式处理都使用单个流处理引擎。关键是确保这两个管道都写入一个通用的存储系统(例如,数据湖或 Lakehouse),以便将结果合并进行查询。例如,批量作业可能计算每日汇总数据,而流式处理负责分钟级指标,两者都存储在 Apache Iceberg 表中以确保一致性。
选择原生支持批量和流式处理的工具。Apache Spark(带有 Structured Streaming)或 Apache Flink 可以使用相似的 API 处理这两种数据类型,从而减少代码重复。对于数据摄取,流式处理使用 Kafka,批量处理使用 Sqoop 或 AWS Glue 等工具。将原始数据存储在云存储(例如,S3)或分布式文件系统(HDFS)中,并使用元数据存储(例如,Hive)来统一元数据。在流式处理中实现幂等操作和精确一次处理(通过 Kafka 事务或 Flink 检查点)以避免重复。对于数据转换,创建可重用模块(例如,共享的 Python 库或 SQL 模板)以应用一致的业务规则。例如,一个作为 Spark UDF 编写的用户会话计算可以在每日批量作业和 Flink 流式作业中重复使用,确保逻辑一致。
在实践中,零售公司可以使用 Kafka 摄取实时网站点击数据,并使用 AWS Glue 从 SQL 数据库拉取每日订单数据。Flink 流式作业用用户数据丰富点击数据,而夜间 Spark 批量作业汇总订单。这两个输出都落入按日期分区的 Delta Lake 表中。Trino 这样的服务层查询这两个数据集,将实时点击流与历史订单相结合进行分析。Airflow 等编排工具可以通过 Kubernetes 操作符触发批量作业并监控流式管道。为了处理延迟到达的数据,流式管道使用带有水印的事件时间窗口,而批量作业则回填更正数据。这种方法平衡了低延迟洞察与准确的历史报告,并使用共享基础设施来降低复杂性。