3. ELT架构深度解析
聊完ETL和ELT的宏观对比,咱们这一章就扎进ELT的细节里。说实话,我第一次从ETL转向ELT时,心里是有点打鼓的——把数据先扔进去再处理,这不等于把厨房弄乱了再收拾吗?但真正上手后才发现,这恰恰是ELT的精髓所在。
3.1 ELT处理流程:Extract → Load → Transform
ELT的流程,说白了就三步:先把数据从源头抽出来,一股脑儿加载到目标平台,最后再在平台里做转换。跟ETL最大的区别在哪?你想想看,ETL是在路上就把饭做好,ELT是把食材先搬进厨房再开火。
3.1.1 Extract(数据抽取)
这一步跟ETL的抽取差别不大,但有个关键点——ELT的抽取通常更“粗糙”。
- 全量抽取:适合小表或初次加载,我习惯在凌晨业务低峰期跑。
- 增量抽取:用时间戳、CDC(变更数据捕获)或日志解析。我在项目中遇到过,用Debezium抓MySQL的binlog,实时性很好,但要注意binlog的保留时长。
- API抽取:调用REST或GraphQL接口,注意限流和分页策略。
3.1.2 Load(数据加载)
这是ELT最核心的一步——把原始数据原封不动地加载到目标存储中。我见过不少团队在这一步翻车,原因就是“想太多”。
加载策略:
- Staging区:先加载到临时表或原始层(Raw Layer),保持数据原样。
- 分区与分桶:按日期或业务键分区,提升后续查询性能。我在Snowflake里常用按天分区,查询效率能提升3-5倍。
- 列式存储:Parquet或ORC格式,压缩率高,扫描快。
3.1.3 Transform(数据转换)
转换发生在目标平台内部,利用平台的计算能力(如Snowflake的虚拟仓库、BigQuery的Slot)。这一步是ELT的“重头戏”。
典型转换操作:
- 清洗:去重、空值处理、格式统一。
- 聚合:按维度汇总,生成宽表或指标。
- 业务逻辑:计算毛利率、客户生命周期价值等。
- 数据建模:星型模型、雪花模型或Data Vault。
嗯,这里要注意:转换的粒度可以很细。我习惯把转换拆成多个SQL或dbt模型,每个模型只做一件事,方便调试和复用。
ELT流程的核心原则:
- Extract:轻量、快速、保留原始
- Load:高效、可靠、分层存储
- Transform:按需、增量、可重复
3.2 ELT典型工具:dbt、Snowflake、BigQuery
工具选对了,ELT就成功了一半。我这些年用过不少组合,最顺手的还是下面这三驾马车。
3.2.1 dbt(数据构建工具)
dbt是ELT生态里的“明星”。它不负责抽取和加载,只做转换——而且是基于SQL的转换。说白了,dbt就是帮你把SQL脚本管理起来,做成可复用、可测试、可版本控制的模型。
dbt的核心概念:
| 概念 | 说明 | 我的用法 |
|---|---|---|
| Model | 一个SQL文件,定义一次转换 | 每个模型只做一件事,比如“计算日活用户” |
| Source | 原始数据表的声明 | 统一管理所有上游表,方便追踪血缘 |
| Test | 数据质量检查 | 我习惯对每个模型加not_null和unique测试 |
| Documentation | 自动生成数据字典 | 团队新人上手快,不用反复问字段含义 |
一个简单的dbt模型示例:
-- models/daily_active_users.sql
WITH base AS (
SELECT
user_id,
DATE(event_time) AS event_date
FROM {{ source('app', 'user_events') }}
WHERE event_type = 'login'
)
SELECT
event_date,
COUNT(DISTINCT user_id) AS dau
FROM base
GROUP BY event_date
ORDER BY event_date
is_incremental()判断。
3.2.2 Snowflake
Snowflake是云原生数据仓库的代表。它的ELT友好性体现在哪?我觉得是“计算与存储分离”和“自动扩缩容”。
Snowflake的ELT优势:
- 虚拟仓库:按需启动,用完即停。我经常给不同的dbt模型分配不同大小的仓库,小模型用X-Small,大模型用Large。
- 零拷贝克隆:秒级复制数据,适合做开发测试环境。
- Time Travel:可以查询过去任意时间点的数据,误删了也不怕。
一个典型的Snowflake加载示例:
-- 创建原始数据表
CREATE OR REPLACE TABLE raw.user_events (
raw_data VARIANT
);
-- 从外部Stage加载JSON数据
COPY INTO raw.user_events
FROM @my_stage/user_events/
FILE_FORMAT = (TYPE = JSON);
-- 使用LATERAL FLATTEN解析嵌套数据
SELECT
raw_data:user_id::STRING AS user_id,
raw_data:event_type::STRING AS event_type,
raw_data:event_time::TIMESTAMP AS event_time
FROM raw.user_events,
LATERAL FLATTEN(input => raw_data);
3.2.3 BigQuery
BigQuery是Google Cloud的Serverless数据仓库。它的ELT能力很强,尤其是“按需计费”和“自动优化”。
BigQuery的ELT特点:
- 列式存储 + 自动压缩:查询只扫描需要的列,成本可控。
- BigQuery ML:直接在数据仓库里跑机器学习模型,省去数据搬运。
- 分区与聚簇:按时间分区,按常用字段聚簇,查询效率翻倍。
一个BigQuery的ELT转换示例:
-- 创建分区表
CREATE TABLE IF NOT EXISTS analytics.daily_metrics
PARTITION BY DATE(event_date)
CLUSTER BY user_id
AS
SELECT
user_id,
event_date,
COUNT(*) AS event_count
FROM raw.user_events
WHERE event_date >= '2024-01-01'
GROUP BY user_id, event_date;
query_queue_timeout_ms参数,或者改用预留Slot。
3.3 ELT适用场景
ELT不是万能的,但在某些场景下,它比ETL顺手得多。我根据自己的项目经验,总结了几个典型场景。
3.3.1 海量数据场景
当数据量达到TB甚至PB级别时,ETL的中间存储和传输会成为瓶颈。ELT直接把数据加载到目标平台,利用平台的分布式计算能力做转换,省去了数据搬运的麻烦。
3.3.2 数据湖与数据仓库结合
我做过一个项目,用S3做数据湖,Snowflake做数据仓库。ELT流程是:先把原始数据加载到S3(Extract + Load),然后在Snowflake里用External Table查询,最后用dbt做转换。这样既保留了原始数据,又利用了数据仓库的性能。
3.3.3 敏捷数据团队
如果团队规模小、需求变化快,ELT更灵活。你想想看,ETL需要提前设计好转换逻辑,一旦业务变了,ETL作业就得重写。而ELT可以先把数据存起来,等需求明确了再写转换SQL。我带的团队现在都采用“先加载,后建模”的策略。
3.3.4 实时或近实时场景
ELT配合流式加载(如Kafka + Snowpipe),可以实现分钟级的延迟。我在一个电商项目中,用这种方式做实时用户画像,效果很好。
ELT不适用的场景:
- 源系统性能差,无法承受频繁抽取
- 目标平台计算资源有限,无法支撑大规模转换
- 数据质量要求极高,需要在加载前完成清洗
3.4 ELT架构流程图
下面这张图是我自己画的ELT核心流程,你可以对照着理解。
这张图把ELT的流程拆得很清楚:数据从源头出来,经过抽取和加载直接进目标存储,转换在存储内部完成,最后输出给下游使用。你想想看,整个过程没有中间件,没有数据搬运,是不是比ETL清爽多了?
3.5 小结
ELT的核心思想就是“先存后算”。它把计算压力从ETL服务器转移到了目标数据平台,适合数据量大、需求变化快的场景。我个人觉得,ELT不是要取代ETL,而是给数据工程师多了一个选择——就像工具箱里既有扳手又有螺丝刀,看情况用哪个顺手。