数据工程实战课程 · 流处理阶段
实时ETL将传统批处理的延迟从小时级降到秒级,是现代数据平台的核心能力。
# 实时ETL引擎
import time, random, hashlib
from datetime import datetime
from collections import defaultdict
class CDCEvent:
def __init__(self, operation, table, before, after, timestamp):
self.operation = operation; self.table = table; self.before = before; self.after = after; self.timestamp = timestamp
class RealtimeETLEngine:
def __init__(self):
self.sources = {}; self.transformers = []; self.sinks = {}
self.metrics = defaultdict(int); self.state = {}
def add_source(self, name, source): self.sources[name] = source
def add_transformer(self, fn): self.transformers.append(fn)
def add_sink(self, name, sink): self.sinks[name] = sink
def process(self, events):
results = []
for event in events:
self.metrics['input'] += 1
record = event.after
# Apply transformations
for transformer in self.transformers:
record = transformer(record)
if record is None: break
if record:
results.append(record)
self.metrics['output'] += 1
# Write to sinks
for sink in self.sinks.values():
sink.write(record)
return results
def get_metrics(self): return dict(self.metrics)
class CDCSimulator:
def __init__(self): self.tables = {}
def register_table(self, name, schema): self.tables[name] = {'schema':schema,'data':[]}
def generate_changes(self, table, count=10):
events = []
for _ in range(count):
op = random.choices(['INSERT','UPDATE','DELETE'], weights=[0.6,0.3,0.1])[0]
after = {k: random.randint(1,1000) if t=='int' else round(random.uniform(10,1000),2) if t=='float' else f"val_{random.randint(1,100)}" for k,t in self.tables[table]['schema'].items()}
before = after.copy() if op == 'UPDATE' else None
if op == 'DELETE': after = None
events.append(CDCEvent(op, table, before, after, datetime.now().isoformat()))
return events
class RealtimeAggregator:
def __init__(self, window_sec=60):
self.window = window_sec; self.buffers = defaultdict(list)
def add(self, record):
key = record.get('category','unknown')
self.buffers[key].append(record)
def get_aggregates(self):
return {k: {'count':len(v),'sum':round(sum(r.get('value',0) for r in v),2)} for k,v in self.buffers.items()}
engine = RealtimeETLEngine()
cdc = CDCSimulator()
cdc.register_table('orders', {'id':'int','amount':'float','category':'str'})
engine.add_transformer(lambda r: {**r,'amount_tier':'high' if r.get('amount',0)>500 else 'low'} if r else None)
engine.add_transformer(lambda r: {**r,'processed_at':datetime.now().isoformat()} if r else None)
aggregator = RealtimeAggregator()
engine.add_sink('aggregator', aggregator)
events = cdc.generate_changes('orders', 100)
results = engine.process(events)
print("实时ETL引擎:")
print(f" 输入: {engine.get_metrics()['input']}, 输出: {engine.get_metrics()['output']}")
print(f" 聚合结果: {aggregator.get_aggregates()}")
print(f" 示例输出: {results[0] if results else 'none'}")
print("✅ 验证通过 - 实时ETL引擎运行正常")
🎁 下一课预告:Airflow调度!
| 维度 | Flink | Spark Streaming | Kafka Streams |
|---|---|---|---|
| 延迟 | 毫秒级 | 秒级(微批) | 毫秒级 |
| Exactly-Once | 原生支持 | 需配置 | 支持 |
| 状态管理 | 丰富 | 有限 | 本地Store |
| 窗口支持 | 全面 | 全面 | 基本 |
| 部署复杂度 | 高 | 中 | 低 |
在生产环境中,我们经常遇到教科书不会告诉你的问题。以下是常见的实战经验和解决方案:
| 指标 | 告警阈值 | 监控方式 |
|---|---|---|
| 管道延迟 | 超过SLA 120% | 端到端时间戳追踪 |
| 数据量偏差 | 日均偏差超过30% | 与历史同期对比 |
| 错误率 | 超过0.1% | 错误计数/总记录数 |
| 数据新鲜度 | 超过SLA 150% | 最新数据时间戳 |
| 资源利用率 | CPU持续>80% | 系统监控 |
A: 根据业务延迟要求决定:秒级用流处理、分钟级用微批、小时级用批处理。大部分场景批处理足够,流处理用于实时业务场景(风控、监控、推荐)。
A: 不会完全取代,但边界在模糊。湖仓一体(如Iceberg/Delta Lake)正在融合两者优势。未来趋势是统一存储+多引擎计算。
A: 先用云原生服务(BigQuery/Snowflake + Fivetran + dbt + Looker),验证业务后再考虑自建。过早优化是万恶之源。
A: 用钱说话:数据质量问题的直接经济损失(错误决策、合规罚款、重复劳动)远大于治理投入。量化问题是第一步。
| 角色 | 职责 | 交付物 |
|---|---|---|
| 数据工程师 | 管道开发与维护 | 数据管道、基础设施 |
| 数据分析师 | 数据分析与报表 | SQL查询、BI报表 |
| 数据科学家 | 模型与实验 | ML模型、实验报告 |
| 数据产品经理 | 需求与优先级 | PRD、数据产品规划 |
| 数据管家 | 数据质量与治理 | 质量规则、数据字典 |