Flink之DataStream

Apache Flink 的 DataStream API 是用于 处理无限(流)或有限(批)数据流的核心编程模型,适用于事件驱动、实时分析、ETL 等场景。相比 Flink Table API,DataStream API 提供了更强的灵活性和底层控制能力。


一、基本概念

1.1 DataStream

DataStream 是 Flink 中的核心抽象,用于表示一个元素流(event stream),可以是:

  • 无限流(unbounded):例如传感器数据、Kafka 日志等。

  • 有限流(bounded):例如读取的文件或已结束的 Kafka topic。

1.2 类型

  • DataStream<T>:表示非键控的数据流。

  • KeyedStream<K, T>:对 DataStream 使用 .keyBy(...) 进行分区后得到的键控流。

  • SingleOutputStreamOperator<T>:表示有后续操作(如 map/filter)后的流。


二、核心组件和操作

2.1 数据源(Sources)

通过 StreamExecutionEnvironment 创建流数据来源:

复制代码
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

DataStream<String> stream = env.fromElements("a", "b", "c");
DataStream<String> kafkaStream = env.addSource(new FlinkKafkaConsumer<>(...));

2.2 转换操作(Transformations)

常用操作包括:

操作 说明
map 一对一转换
flatMap 一对多转换
filter 过滤数据
keyBy 按 key 分区
reduce 增量聚合
window 定义窗口
process 更底层的流处理接口

示例:

复制代码
DataStream<String> words = stream.flatMap((String line, Collector<String> out) -> {
    for (String word : line.split(" ")) out.collect(word);
}).returns(Types.STRING);

2.3 窗口操作(Windowing)

Flink 的窗口机制可用于将无限流"划分"为有限数据组:

复制代码
stream.keyBy(value -> value.key)
      .window(TumblingEventTimeWindows.of(Time.seconds(10)))
      .reduce((v1, v2) -> ...);
  • 支持类型:

    • 滚动窗口(Tumbling)

    • 滑动窗口(Sliding)

    • 会话窗口(Session)

2.4 时间语义

支持 3 种时间语义:

  • 处理时间(Processing Time)

  • 事件时间(Event Time)

  • 摄取时间(Ingestion Time)

配合 Watermark 使用事件时间:

复制代码
stream.assignTimestampsAndWatermarks(WatermarkStrategy.forBoundedOutOfOrderness(...));

三、状态管理(State Management)

DataStream API 支持保存状态用于:

  • 聚合

  • 去重

  • CEP 等复杂场景

使用 KeyedProcessFunction 或 RichFunction 可以访问状态 API:

复制代码
ValueState<Integer> state;

@Override
public void open(Configuration parameters) {
    state = getRuntimeContext().getState(new ValueStateDescriptor<>("myState", Integer.class));
}

四、容错与一致性

Flink 提供:

  • 精确一次(Exactly-once)或至少一次(At-least-once)语义

  • 基于 Checkpointing 实现

    env.enableCheckpointing(10000); // 每 10 秒做一次 checkpoint


五、连接操作(Stream Joins)

支持不同类型流之间的连接:

  • connect: 将两个不同类型流合并处理

  • union: 合并同类型流

  • interval join: 基于时间范围连接两个流

  • CoProcessFunction: 对 connect 的结果使用不同逻辑处理两个流


六、输出(Sinks)

支持输出到:

  • Kafka

  • Redis

  • HDFS

  • MySQL / JDBC

  • ElasticSearch 等

示例:

复制代码
stream.addSink(new FlinkKafkaProducer<>(...));

七、DataStream 和 Table API 的对比

特性 DataStream API Table API / SQL
灵活性 高(更底层) 中(更偏向声明式)
使用场景 自定义复杂逻辑、状态处理 结构化数据处理、简洁分析
容错一致性 支持 支持
状态控制 细粒度控制 抽象封装

八、示例:从 Kafka 读取并统计词频

复制代码
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

DataStream<String> input = env.addSource(new FlinkKafkaConsumer<>("topic", new SimpleStringSchema(), props));

input.flatMap(new FlatMapFunction<String, Tuple2<String, Integer>>() {
    public void flatMap(String value, Collector<Tuple2<String, Integer>> out) {
        for (String word : value.split(" ")) {
            out.collect(new Tuple2<>(word, 1));
        }
    }
})
.keyBy(t -> t.f0)
.sum(1)
.print();

env.execute();
相关推荐
智码看视界10 小时前
技术选型指南:Kafka Streams vs Flink:流处理框架选型实战对比与性能压测
flink·实时计算·状态管理·流处理·大数据架构·kafkastreams·流处理选型
用户3610588626121 天前
Flink 配置深度剖析:从配置加载到参数调优的完整指南
大数据·flink
云边有个稻草人2 天前
不止于时序存储:DolphinDB 如何成为 AI 时代的工业智能底座
时序数据库·实时计算·工业物联网·流批一体·dolphindb·数据库选型·工业大数据
Irene19912 天前
Flink 学习日志 01:前端转大数据的实战避坑指南
java·jvm·flink
Gl�ria3 天前
Flink Yarn-Session Job 相关常用脚本
flink
Norris Huang3 天前
Kafka Connect 与 Flink CDC 写入 Iceberg:Upsert 的代价,以及 S3 Tables 的真正价值
分布式·flink·kafka
用户3610588626124 天前
Flink 优化之 CheckPoint 优化及参数详解:从原理到生产环境调优的完整指南
大数据·flink
用户3610588626125 天前
Flink SQL 之 Flink SQL 企业级案例分析:从实时大屏到用户画像与风控告警的生产实践
大数据·flink
用户3610588626125 天前
Flink SQL 之 Table Window 原理及代码实现:从滚动窗口到窗口 TopN 与窗口 Join 实战
大数据·flink
nvd117 天前
深入剖析 Apache Flink 流批双引擎的动态扩缩容架构:机制演进、状态重对齐与生产落地推导
架构·flink·apache