流处理Skill stream-processing

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

数据工程 0 次安装 0 次浏览 更新于 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模式 - 数据管道模式