ETL 指的是数据的抽取(Extract)、转换(Transform)和加载(Load)三个阶段:
一个高效的 ETL 流程不仅要保证数据的准确性和一致性,还要兼顾性能、可维护性和扩展性。
示例:
- 目标:每日汇总销售数据,供报表分析。
- 数据源:MySQL 订单表,增量同步。
- 目标存储:PostgreSQL 数据仓库。
Python 伪代码示例:
import pandas as pd
import sqlalchemy
# 假设 last_run_time 已知
last_run_time = '2023-01-01 00:00:00'
engine = sqlalchemy.create_engine('mysql+pymysql://user:pwd@host/db')
# 增量抽取
sql = f"SELECT * FROM orders WHERE last_updated > '{last_run_time}'"
df = pd.read_sql(sql, engine)
Python 伪代码示例:
# 缺失值填充
orders = df.fillna({'amount': 0})
# 去重
orders = orders.drop_duplicates()
# 日期格式标准化
orders['order_date'] = pd.to_datetime(orders['order_date'])
# 聚合:统计每日销售额
sales_daily = orders.groupby(orders['order_date'].dt.date)['amount'].sum().reset_index()
Python 伪代码示例:
# 假设目标为 PostgreSQL
engine_pg = sqlalchemy.create_engine('postgresql://user:pwd@host/db')
sales_daily.to_sql('sales_daily', engine_pg, if_exists='replace', index=False) # 全量覆盖
Airflow DAG 简单示例:
from airflow import DAG
from airflow.operators.python_operator import PythonOperator
from datetime import datetime
def extract():
pass # 数据抽取逻辑
def transform():
pass # 数据转换逻辑
def load():
pass # 数据加载逻辑
dag = DAG('simple_etl', start_date=datetime(2023, 1, 1), schedule_interval='@daily')
t1 = PythonOperator(task_id='extract', python_callable=extract, dag=dag)
t2 = PythonOperator(task_id='transform', python_callable=transform, dag=dag)
t3 = PythonOperator(task_id='load', python_callable=load, dag=dag)
t1 >> t2 >> t3
ETL流程根据业务需求和数据时效性,主要分为批处理、流式处理和Lambda架构三种模式。
流程图(Mermaid):
伪代码示例:
# 伪代码:每日定时批量处理
for day in days:
data = extract(day)
data_clean = transform(data)
load(data_clean)
流程图(Mermaid):
伪代码示例:
# 伪代码:流式处理框架
while True:
event = get_next_event()
event_clean = transform(event)
load(event_clean)
流程图(Mermaid):
伪代码示例:
# 实时层
for event in realtime_stream:
update_realtime_view(event)
# 批处理层(定期)
for batch in historical_data:
update_batch_view(batch)
# 查询时合并两层结果
result = merge(realtime_view, batch_view)
设计ETL流程时,合理选择技术栈至关重要。不同环节有多种开源工具和云服务可选,需结合业务需求、团队能力和预算综合考虑。
环节 | 开源工具 | 云服务(如 AWS) |
---|---|---|
调度 | Airflow, Dagster, Prefect | AWS Step Functions, MWAA |
计算 | Spark, Flink, Dask | AWS EMR, Databricks |
存储 | Delta Lake, Iceberg, PostgreSQL | S3 + Athena, Snowflake |
数据质量 | Great Expectations, dbt tests | AWS Deequ |
CDC | Debezium, Kafka Connect | AWS DMS |
技术选型没有绝对标准,建议结合团队技术栈、数据规模、预算和运维能力综合评估。
高效、可靠的ETL流程不仅依赖于技术选型,更离不开科学的工程实践。以下是业界常用的ETL最佳实践,以及一个典型的完整流程示例。
MERGE
/UPSERT
代替INSERT
,分区覆盖写入等。以下以Airflow调度Spark作业,最终写入Delta Lake为例,展示一个典型的现代ETL流程:
# Airflow DAG 示例(简化版)
from airflow import DAG
from airflow.operators.bash_operator import BashOperator
from datetime import datetime
def spark_submit_cmd(script):
return f"spark-submit --master yarn {script}"
dag = DAG(
"etl_pipeline",
start_date=datetime(2023, 1, 1),
schedule_interval="@daily"
)
extract = BashOperator(
task_id="extract",
bash_command=spark_submit_cmd("extract.py"), # 从MySQL抽取到S3
dag=dag
)
transform = BashOperator(
task_id="transform",
bash_command=spark_submit_cmd("transform.py"), # Spark清洗和聚合
dag=dag
)
load = BashOperator(
task_id="load",
bash_command=spark_submit_cmd("load.py"), # 写入Delta Lake
dag=dag
)
extract >> transform >> load
说明:
extract.py
:负责从MySQL等数据源抽取数据,落地到S3或HDFS。transform.py
:用Spark对原始数据进行清洗、聚合、分区等转换。load.py
:将处理好的数据写入Delta Lake,实现高效存储和后续分析。即使采用了最佳实践,ETL流程在实际落地中仍会遇到各种挑战。以下是常见问题及应对思路:
挑战1:数据量大导致性能瓶颈
挑战2:源系统 Schema 变更
挑战3:依赖任务失败或数据延迟
挑战4:数据质量问题
挑战5:多源异构数据整合难
ETL流程是现代数据工程的基石。高效、可靠的ETL设计需要:
无论是初学者还是有经验的数据工程师,都应重视ETL流程的规范化和自动化。建议从简单的Airflow+dbt或Spark+Delta Lake组合入手,逐步扩展到更复杂的实时和大数据场景。
希望本文能帮助你系统理解ETL流程的设计与落地,助力数据驱动业务发展!