ETL基础

第03课:数据提取-API-数据库与文件

数据工程实战课程 · ETL基础阶段

📥 数据提取-API-数据库与文件

数据提取是ETL第一步,负责从各种异构数据源中获取原始数据。优秀的提取策略需要平衡完整性、时效性和资源消耗。

数据源分类

数据源提取方式增量策略
REST API分页请求时间戳/游标
关系数据库SQL/CDC自增ID/时间列
CSV/JSON文件读取修改时间

🐍 数据库数据提取

# 数据库提取(SQLite实机)
import sqlite3, time, random
from datetime import datetime, timedelta

conn = sqlite3.connect(':memory:')
conn.row_factory = sqlite3.Row
c = conn.cursor()
c.execute('CREATE TABLE orders (id INTEGER PRIMARY KEY AUTOINCREMENT, customer_id TEXT, amount REAL, status TEXT, region TEXT, created_at TIMESTAMP)')
regions = ['华东','华南','华北','西南','东北']
for i in range(1000):
    c.execute("INSERT INTO orders VALUES (?,?,?,?,?,?)",
        (None, f"客户_{random.randint(1,200)}", round(random.uniform(10,5000),2),
         random.choice(['pending','shipped','delivered']), random.choice(regions),
         (datetime.now()-timedelta(days=random.randint(0,30))).isoformat()))
conn.commit()
print(f"测试库: 1000订单")

# 全量提取
start = time.perf_counter()
rows = [dict(r) for r in c.execute("SELECT * FROM orders").fetchall()]
print(f"全量: {len(rows)}条, {(time.perf_counter()-start)*1000:.2f}ms")

# 增量提取(id>990)
start = time.perf_counter()
rows = [dict(r) for r in c.execute("SELECT * FROM orders WHERE id > 990").fetchall()]
print(f"增量(id>990): {len(rows)}条, {(time.perf_counter()-start)*1000:.2f}ms")

# 并行提取(4分区)
for s,e in [(1,250),(251,500),(501,750),(751,1000)]:
    rows = c.execute("SELECT COUNT(*) FROM orders WHERE id BETWEEN ? AND ?", (s,e)).fetchone()[0]
    print(f"  分区[{s},{e}]: {rows}条")

print("✅ 验证通过 - 数据库提取运行正常")

📐 提取性能优化

策略场景提升
并行提取多数据源2-8x
增量替代全量大数据低变更10-100x
谓词下推分区+过滤5-50x
# 文件提取:CSV/JSON
import csv, json, io, random

class FileExtractor:
    def extract_csv(self, content, delimiter=','):
        reader = csv.DictReader(io.StringIO(content), delimiter=delimiter)
        return [dict((k, float(v) if v.replace('.','',1).isdigit() else v.strip())
            for k,v in row.items() if v.strip()) for row in reader]
    def extract_json(self, content):
        data = json.loads(content)
        if isinstance(data, list): return data
        for key in ['data','records','items']:
            if key in data and isinstance(data[key], list): return data[key]
        return [data]

csv_content = "id,name,amount,category\n"
for i in range(1, 51):
    csv_content += f"{i},商品_{i},{round(random.uniform(10,500),2)},{random.choice(['A','B','C'])}\n"

json_content = json.dumps({'data':[
    {'id':i,'sensor':f"sensor_{random.randint(1,20)}",'value':round(random.uniform(0,100),2)}
    for i in range(1,31)]}, ensure_ascii=False)

ext = FileExtractor()
csv_r = ext.extract_csv(csv_content)
json_r = ext.extract_json(json_content)
print(f"CSV: {len(csv_r)}条, JSON: {len(json_r)}条")
print(f"CSV示例: {csv_r[0]}")
print("✅ 验证通过 - 文件提取运行正常")
💡 实战建议:动手实现本课代码示例,修改参数观察输出变化。生产环境还需考虑错误处理、监控告警和数据安全。

🎯 多源提取管道

  1. 并行提取多数据源
  2. 健康检查
  3. 进度追踪

🎯 API限速处理

  1. 令牌桶限速器
  2. 突发流量支持

🏆 第3课成就解锁

🎁 下一课预告:数据转换!

📖 原理深入:ETL设计核心原则

数据管道设计五原则

  1. 幂等性原则:同一输入无论执行多少次,输出结果完全一致。这是重试机制的基础,也是管道可恢复性的保证。
  2. 原子性原则:一个批次的数据要么全部成功,要么全部回滚。使用事务或两阶段提交确保原子性。
  3. 可观测性原则:每个步骤都有明确的输入输出指标、执行日志和错误追踪。当管道出现问题时,能在5分钟内定位到故障点。
  4. 可扩展性原则:管道能水平扩展以应对数据量增长。避免单点瓶颈,使用分区并行处理,设计无状态的计算节点。
  5. 自愈性原则:管道能自动处理常见故障,无需人工干预即可恢复。

ETL性能优化清单

优化项方法预期效果
I/O优化批量读写、列式存储、压缩3-10x
计算优化向量化执行、谓词下推、列裁剪2-5x
并行化分区并行、流水线并行线性扩展
缓存维度表缓存、结果缓存2-10x
增量处理只处理变更数据10-100x

🏆 最佳实践:生产环境ETL检查清单

🔬 深度案例:生产环境实战经验

踩坑与解决方案

在生产环境中,我们经常遇到教科书不会告诉你的问题。以下是常见的实战经验和解决方案:

监控与运维指标

指标告警阈值监控方式
管道延迟超过SLA 120%端到端时间戳追踪
数据量偏差日均偏差超过30%与历史同期对比
错误率超过0.1%错误计数/总记录数
数据新鲜度超过SLA 150%最新数据时间戳
资源利用率CPU持续>80%系统监控
⚠️ 常见反模式
💡 架构演进建议:不要一开始就追求完美架构。从MVP开始,随业务增长逐步演进。每次演进都要回答三个问题:当前瓶颈是什么?解决它的投入产出比如何?是否为后续扩展留了空间?

📚 延伸阅读与参考

推荐资源

🤔 常见问题与解答

Q1: 如何选择批处理还是流处理?

A: 根据业务延迟要求决定:秒级用流处理、分钟级用微批、小时级用批处理。大部分场景批处理足够,流处理用于实时业务场景(风控、监控、推荐)。

Q2: 数据湖会取代数据仓库吗?

A: 不会完全取代,但边界在模糊。湖仓一体(如Iceberg/Delta Lake)正在融合两者优势。未来趋势是统一存储+多引擎计算。

Q3: 初创公司如何选择数据技术栈?

A: 先用云原生服务(BigQuery/Snowflake + Fivetran + dbt + Looker),验证业务后再考虑自建。过早优化是万恶之源。

Q4: 如何说服业务方投资数据治理?

A: 用钱说话:数据质量问题的直接经济损失(错误决策、合规罚款、重复劳动)远大于治理投入。量化问题是第一步。

性能调优实战技巧

数据工程团队协作模式

角色职责交付物
数据工程师管道开发与维护数据管道、基础设施
数据分析师数据分析与报表SQL查询、BI报表
数据科学家模型与实验ML模型、实验报告
数据产品经理需求与优先级PRD、数据产品规划
数据管家数据质量与治理质量规则、数据字典
💡 职业发展建议:数据工程是一个快速发展的领域。保持学习的关键是:1)理解原理而非仅会工具;2)动手实践而非仅看文档;3)关注社区动态,了解最新趋势;4)建立个人项目,积累实战经验。