用途
ETL/ELT Patterns 用于在以下场景提供指导:在 ETL 与 ELT 方案之间做选择、设计数据管道、实现数据转换、构建现代数据栈、处理管道中的数据质量问题。
ETL 与 ELT 对比
ETL(Extract, Transform, Load):先转换后加载,需要独立的 ETL 服务器或工具,采用 schema-on-write,属于传统方案。适合复杂转换、目标存储有限、严格数据质量要求、遗留系统。
ELT(Extract, Load, Transform):先加载后转换,使用目标系统的计算能力,采用 schema-on-read,属于现代方案。适合云数据仓库、灵活探索、迭代开发、大数据量。
对比维度包括:转换时机(加载前/加载后)、计算位置(独立服务器/目标系统)、原始数据访问(有限/完整)、灵活性(低/高)、延迟(较高/较低)、成本模型(ETL 服务器+存储/存储+目标计算)、适用场景(复杂预定义/探索迭代)。
现代数据栈
典型分层:Extract(Fivetran、Airbyte、Stitch、自定义)→ Load(云仓库:Snowflake、BigQuery、Redshift)→ Transform(dbt、Dataform、SQLMesh)→ Visualize(Looker、Tableau、Metabase)。
dbt(Data Build Tool)核心概念:Models(定义转换的 SQL SELECT 语句)、Tests(数据质量断言)、Documentation(内联文档与血缘)、Macros(可复用 SQL 片段)。示例模型使用 {{ ref('stg_customers') }} 引用其他模型。
管道模式
全量刷新:删除并重建整张表。流程为提取全部数据、清空目标表、加载全部数据。优点是简单一致,缺点是大表慢且无法处理删除。适合小维度表、参考数据。
增量加载:只处理新增或变更记录。流程为跟踪高水位线(最后处理的时间戳/ID)、提取大于水位的记录、合并到目标。优点是快速高效,缺点是复杂且可能遗漏更新。适合大事实表、事件数据。
变更数据捕获(CDC)三种方式:基于日志(Debezium、AWS DMS,读取数据库事务日志,捕获插入/更新/删除,无需修改源表);基于触发器(数据库触发器写入变更表,增加源负载);基于时间戳(按 updated_at 查询,简单但会遗漏硬删除)。
合并(Upsert)模式:使用 MERGE 语句,匹配时更新、不匹配时插入。
数据质量模式
校验门:管道中设置质量门,如 Extract → Validate → Load → Transform → Validate → Serve,失败记录进入隔离区或触发告警/阻断。
质量检查包括:模式校验(必填字段、数据类型、字段长度)、数据校验(空值、范围、格式如日期与邮箱、引用完整性)、统计校验(行数范围、值分布、意外重复)。
数据契约:定义生产者与消费者之间的期望,包含 contract_version、schema(字段类型与必填)、quality(新鲜度、完整性、行数范围)。
管道架构
批处理管道:基于调度处理,如 Cron → Spark → DW。适合非实时、大数据量。工具:Airflow、Dagster、Prefect。
流处理管道:实时处理,如 Kafka → Flink → DW。适合实时分析、事件驱动。工具:Kafka Streams、Flink、Spark Streaming。
Lambda 架构:批处理层+速度层,优点是完整且实时,缺点是复杂、逻辑重复。
Kappa 架构:仅流处理,可从日志重放重新处理,优点是简单、单一代码库,缺点是需要可重放日志。
编排
基于 DAG 的编排:有向无环图任务,如 extract_a 与 extract_b 汇入 transform 再到 load。工具:Airflow、Dagster、Prefect。
编排最佳实践:幂等任务(可安全重试)、清晰依赖、适当粒度、监控告警、回填支持、参数化运行。
错误处理
重试策略:瞬时错误(网络、超时)采用指数退避、最大重试次数、熔断器;数据错误(校验失败)隔离坏记录、继续处理好记录、告警待审。
死信队列:失败记录 → DLQ → 人工审查 → 重新处理。捕获原始记录、错误消息、时间戳、重试次数。
最佳实践
管道设计:幂等转换、清晰血缘跟踪、适当检查点、优雅失败处理、全面日志、数据质量门。
性能:适当分区、尽可能增量处理、并行提取、高效文件格式(Parquet、ORC)、压缩、资源规模调整。
相关技能
data-architecture(数据平台设计)、stream-processing(实时处理)、ml-system-design(特征工程)。