⚡

流处理Skill stream-processing

流处理技能专注于实时数据处理技术,用于构建事件驱动系统和流分析应用。它涉及使用框架如Apache Kafka、Apache Flink等处理无界数据流,支持低延迟响应、窗口操作、状态管理和精确一次交付。关键词:流处理、实时数据、事件流、Kafka、Flink、流分析、数据管道、事件驱动架构。

数据工程 0 次安装 47 次浏览 更新于 3/11/2026

名称: 流处理 描述: 用于设计实时数据处理系统、选择流处理框架或实现事件驱动架构。涵盖Kafka、Flink和流处理模式。 允许工具: Read, Glob, Grep

流处理

用于实时数据处理、事件流和流分析的模式和技术。

何时使用此技能

  • 设计实时数据管道
  • 选择流处理框架
  • 实现事件驱动架构
  • 构建实时分析
  • 理解流处理与批处理的权衡

批处理 vs 流处理

比较

方面 批处理 流处理
延迟 分钟到小时 毫秒到秒
数据 有界(有限) 无界(无限)
处理 一次性处理所有 数据到达时处理
状态 每次运行重新计算 持续维护
复杂度 较低 较高
成本 通常较低 通常较高

何时使用流处理

使用流处理当:
- 需要实时响应(<1分钟)
- 事件需要立即行动(欺诈、警报)
- 数据持续到达
- 用户期望实时更新
- 时间敏感的业务决策

使用批处理当:
- 每日/每小时报告足够
- 需要复杂转换
- 成本优化优先
- 历史分析
- 一次性处理

流处理概念

事件时间 vs 处理时间

事件时间:事件实际发生的时间
处理时间:事件被处理的时间

示例:
┌─────────────────────────────────────────────────────────┐
│ 事件:10:00:00的购买(事件时间)                       │
│ 网络延迟:5秒                                           │
│ 处理时间:10:00:05(处理时间)                         │
└─────────────────────────────────────────────────────────┘

为什么重要:
- 需要处理迟到事件
- 顺序不保证
- 水印跟踪进度

水印

水印 = "此时间之前的所有事件都已到达"

事件流:
──[10:01]──[10:02]──[10:00]──[10:03]──[水印: 10:00]──

允许系统:
- 知道窗口何时完成
- 处理迟到事件
- 平衡延迟与完整性

窗口

翻滚窗口(固定,不重叠):
|─────|─────|─────|
0     5    10    15(秒)

滑动窗口(固定,重叠):
|─────|
  |─────|
    |─────|
大小:5秒,滑动:2秒

会话窗口(基于活动):
|──────|     |───────────|    |───|
用户活动间隙定义窗口

计数窗口:
每N个事件处理一次

状态管理

有状态操作需要维护状态:
- 聚合(和、计数、平均)
- 流之间的连接
- 模式检测
- 去重

状态后端:
- 内存中(快速,有限)
- RocksDB(较大,持久)
- 外部(Redis、数据库)

流处理框架

Apache Kafka Streams

特点:
- 库(非集群)
- 精确一次语义
- Kafka原生
- Java/Scala

最佳用于:
- Kafka中心架构
- 简单转换
- 微服务

示例拓扑:
源 → 过滤 → 映射 → 聚合 → 汇

Apache Flink

特点:
- 分布式集群
- 真正流处理(非微批)
- 高级状态管理
- SQL支持

最佳用于:
- 复杂事件处理
- 大规模流处理
- 低延迟需求

示例:
DataStream<Event> events = env.addSource(kafkaSource);
events
    .keyBy(e -> e.getUserId())
    .window(TumblingEventTimeWindows.of(Time.minutes(5)))
    .aggregate(new CountAggregator())
    .addSink(sink);

Apache Spark Streaming

特点:
- 微批处理
- 统一批处理 + 流处理API
- 广泛生态系统
- Python, Scala, Java, R

最佳用于:
- 有Spark经验的团队
- 批处理 + 流处理统一
- 机器学习集成

延迟:秒(微批)

Kafka Streams vs Flink vs Spark

因素 Kafka Streams Flink Spark Streaming
部署 库 集群 集群
延迟 低 最低 中等
状态 好 优秀 好
精确一次 是 是 是
复杂度 低 高 中等
扩展 随Kafka 独立 独立
SQL 有限 是 是
ML集成 有限 有限 优秀

流处理模式

过滤

输入:所有事件
输出:匹配条件的事件

示例:仅处理金额 > 1000的事件

映射/转换

输入:事件类型A
输出:事件类型B

示例:用客户数据丰富订单事件

聚合

输入:多个事件
输出:单个聚合结果

示例:
- 每个窗口的事件计数
- 每个用户的金额总和
- 每个端点的平均延迟

连接模式

流-流连接:
┌─────────────┐     ┌─────────────┐
│   订单      │ ──► │    连接     │
└─────────────┘     │ (按订单号   │
┌─────────────┐     │  在窗口中) │
│   发货      │ ──► │             │
└─────────────┘     └─────────────┘

流-表连接(丰富):
┌─────────────┐     ┌─────────────┐
│   事件      │ ──► │    连接     │
└─────────────┘     │ (按客户查找 │
┌─────────────┐     │   )        │
│   客户      │ ──► │             │
│    表       │     └─────────────┘
└─────────────┘

去重

问题:至少一次交付的重复事件

解决方案:
1. 在状态中跟踪已见ID(带TTL)
2. 如果已见,丢弃
3. 如果新,处理并存储ID

状态:{事件ID: 时间戳}
TTL:基于预期重复窗口

事件交付保证

最多一次

可能丢失事件,从不重复
处理 → 提交 → (如果失败,事件丢失)

使用当:可接受丢失,偏好简单性

至少一次

从不丢失,可能有重复
提交 → 处理 → (如果失败,重新处理)

使用当:不允许丢失,下游处理重复

精确一次

从不丢失,从不重复
要求:
- 幂等操作,或
- 事务处理

工作原理:
1. 从事务性源读取
2. 处理并更新状态
3. 一起写入输出和提交

Flink:检查点 + 两阶段提交
Kafka Streams:事务生产者 + EOS

迟到事件处理

策略

1. 丢弃迟到事件
   简单,可能丢失数据

2. 允许迟到事件(允许延迟)
   如果在延迟阈值内,处理

3. 侧输出迟到事件
   主流处理准时事件
   侧流单独处理迟到事件

4. 重新处理历史
   批处理作业修复迟到数据影响

水印策略

有界乱序:
水印 = 最大事件时间 - 最大延迟

示例:
最大事件时间 = 10:00:00
最大延迟 = 5秒
水印 = 09:59:55

09:59:55之前的事件视为完成

可扩展性模式

分区

按键分区以并行处理:

┌─────────────────────────────────────────────────────┐
│ Kafka主题(3个分区)                                │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐│
│ │ 分区0       │ │ 分区1       │ │ 分区2           ││
│ │ 用户a, b    │ │ 用户c, d    │ │ 用户e, f        ││
│ └─────────────┘ └─────────────┘ └─────────────────┘│
└─────────────────────────────────────────────────────┘
         │               │               │
         ▼               ▼               ▼
    ┌─────────┐    ┌─────────┐    ┌─────────┐
    │工人0    │    │工人1    │    │工人2    │
    └─────────┘    └─────────┘    └─────────┘

背压

当下游无法跟上时:

1. 缓冲(风险:内存溢出)
2. 丢弃(风险:数据丢失)
3. 背压(减慢源)

Flink:背压自动传播
Kafka:消费者滞后指示背压

监控流处理应用

关键指标

吞吐量:
- 每秒事件数
- 每秒字节数

延迟:
- 处理延迟
- 端到端延迟

健康度:
- 消费者滞后
- 检查点时长
- 背压率
- 错误率

消费者滞后

滞后 = 最新偏移量 - 消费者偏移量

高滞后指示:
- 处理太慢
- 需要更多并行度
- 下游瓶颈

监控:设置警报阈值

最佳实践

1. 需要时设计为精确一次
2. 明确处理迟到事件
3. 使用事件时间,而非处理时间
4. 密切监控消费者滞后
5. 规划状态恢复
6. 用实际数据量测试
7. 实现背压处理
8. 尽可能保持处理幂等

相关技能

  • 消息队列 - 消息模式
  • 数据架构 - 数据平台设计
  • ETL-ELT模式 - 数据管道模式