从 0 到 1Flink DataStream API 入门与上手实战

一、为什么选择 DataStream API?

DataStream API 是 Flink 处理连续数据流的核心编程接口,具备:

  • 低延迟高吞吐:天然面向流处理的执行引擎。
  • 强大的序列化与类型系统:原生支持基本类型、Tuples、POJOs;其他类型回退 Kryo;也可用 Avro 等外部序列化器。
  • 灵活的数据接入与输出:从文件到 Kafka/Kinesis,再到数据库、对象存储、消息系统。

一句话:只要能被序列化,就能被 DataStream 流式处理。

二、可流式处理的数据类型与序列化

1)基础与复合类型

  • 基本类型:String / Long / Integer / Boolean / Array
  • 复合类型:TuplesPOJOs
  • 其他类型默认回退 Kryo ;也可替换为 Avro 等(推荐在跨语言/严格 schema 场景下使用)。

2)Java Tuples

Flink 在 Java 中定义了 Tuple0 ~ Tuple25

java 复制代码
Tuple2<String, Integer> person = Tuple2.of("Fred", 35);
// 注意:下标从 0 开始
String name = person.f0;
Integer age  = person.f1;

适用场景:原型/临时任务、字段不复杂时;大型项目建议用 POJO/Avro 以提升可读性与演进性。

3)POJOs(强烈推荐)

Flink 将满足以下条件的类识别为 POJO,并支持按字段名 访问与schema 演进

  • 类是 public独立(不是非静态内部类)
  • 具有 public 无参构造方法
  • 所有非静态非 transient 字段要么 publicfinal,要么有符合 JavaBeans 规范的 getter/setter
    示例:
java 复制代码
public class Person {
    public String name;
    public Integer age;
    public Person() {}
    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
}
Person person = new Person("Fred Flintstone", 35);

最佳实践:POJO 字段改动、顺序调整等常见 schema 演进,Flink 原生序列化器可平滑处理。

三、首个 DataStream 示例:过滤成年人

下面的最小示例会在本地构建一个人员流,只保留年龄 ≥ 18 的元素,并打印输出。

java 复制代码
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.api.common.functions.FilterFunction;

public class Example {

    public static void main(String[] args) throws Exception {
        final StreamExecutionEnvironment env =
                StreamExecutionEnvironment.getExecutionEnvironment();

        DataStream<Person> flintstones = env.fromData(
                new Person("Fred", 35),
                new Person("Wilma", 35),
                new Person("Pebbles", 2));

        DataStream<Person> adults = flintstones.filter(new FilterFunction<Person>() {
            @Override
            public boolean filter(Person person) {
                return person.age >= 18;
            }
        });

        // 输出到 TaskManager 日志(IDE 控制台可见)
        adults.print();

        // 别忘了执行!
        env.execute("Adults Filter");
    }

    public static class Person {
        public String name;
        public Integer age;
        public Person() {}
        public Person(String name, Integer age) {
            this.name = name;
            this.age = age;
        }
        @Override
        public String toString() {
            return name + ": age " + age;
        }
    }
}

输出示例:

复制代码
1> Fred: age 35
2> Wilma: age 35

前缀 1> / 2> 表示由哪个并行子任务打印(线程/子任务编号)。

四、执行环境与作业提交流程(你在代码里做了什么)

  • 每个 Flink 应用都需要一个 StreamExecutionEnvironment(流式程序必须使用此环境)。
  • 你在代码里调用的 DataStream API(source → transform → sink)会构建作业图 并绑定在 env 上。
  • 调用 env.execute() 后,作业图被打包交给 JobManager ,由其并行化 并分发到多个 TaskManager 上运行,每个task slot承担作业的一段。

重要提醒 :不调用 execute(),作业不会运行。

五、常用输入 Source(从原型到生产)

1)快速原型

  • fromData:快速构造小数据流(如上例)
  • Socket :配合 nc -lk 9999 快速进数据
java 复制代码
DataStream<String> lines = env.socketTextStream("localhost", 9999);

2)文件/目录

java 复制代码
import org.apache.flink.connector.file.src.FileSource;
import org.apache.flink.connector.file.src.reader.TextLineInputFormat;
import org.apache.flink.api.common.eventtime.WatermarkStrategy;
import org.apache.flink.core.fs.Path;

FileSource<String> fileSource = FileSource.forRecordStreamFormat(
    new TextLineInputFormat(), new Path("file:///path")
).build();

DataStream<String> lines = env.fromSource(
    fileSource,
    WatermarkStrategy.noWatermarks(),
    "file-input"
);

3)生产级数据源(推荐)

  • Kafka / Kinesis / 各类分布式文件系统 :低延迟、高吞吐、支持回溯与重放,是高性能与容错的基础。
  • REST / 数据库 :常用于维表/画像流式富化(可配合 Async I/O 或 CDC)。

六、常用输出 Sink(打印只是开始)

  • 打印print() 便于开发期查看。
  • 生产常见FileSink、各类数据库 sink(JDBC/NoSQL)、消息中间件(Kafka 等)。
  • 注意语义保证(At-least-once / Exactly-once)与端到端一致性的配置与成本。

七、开发/调试:先在本地跑顺畅

  • 本地 IDE 调试 :设置断点、查看本地变量、逐句执行。必要时直接 Step Into Flink 源码,理解内部机制。
  • 远程/容器集群排障:借助 Web UI、JobManager/TaskManager 日志定位异常。
  • 依赖与可序列化 :作业分布式运行要求对象可序列化依赖在各节点可用(例如通过 fat JAR/shade 打包)。

八、最佳实践与易错点

  1. 别忘了 env.execute():常见"空跑"问题。
  2. 类型与序列化:POJO 要满足 Flink 规则;自定义类型确认可序列化;必要时切换 Avro 并管理 schema。
  3. 并行度与输出日志:打印输出前缀编号就是并行子任务 ID;输出乱序是正常的。
  4. Source/Sink 语义:生产中关注端到端一致性(尤其是 Kafka → Flink → 外部存储)。
  5. 事件时间与水位线:原型阶段可用处理时间,真实乱序场景需事件时间 + watermark(本文未展开,后续进阶)。

九、动手练习(Hands-on 建议)

  • 从官方 training repo 开始,按 README 拉起环境。
  • 第一练:Filtering a Stream(Ride Cleansing)
    重点体会:类型建模、算子组合、IDE 调试、Web UI 观察拓扑与并行度。

练习时请尝试:把 fromData 替换为 socketTextStream,或加上 map → keyBy → reduce 的小链路,感受 DataStream 的"搭积木"思路。

十、参考路线与延伸阅读

  • 选择序列化器性能调优(优先 POJO/Avro,能定 schema 就别回退到通用 Kryo)
  • 一个 Flink 程序的解剖:从 env 到 job graph、并行度、checkpoint
  • Data Sources / Sinks / Connectors:根据你的基础设施选型
  • 状态、时间与一致性(下一阶段重点):Keyed State、Timer、Watermark、Checkpoint、Exactly-once
相关推荐
wudl55665 小时前
Flink 1.20 flink-config.yml 配置详解
大数据·flink
华东数交5 小时前
企业与国有数据资产:入表全流程管理及资产化闭环理论解析
大数据·人工智能
B站_计算机毕业设计之家10 小时前
计算机毕业设计:Python农业数据可视化分析系统 气象数据 农业生产 粮食数据 播种数据 爬虫 Django框架 天气数据 降水量(源码+文档)✅
大数据·爬虫·python·机器学习·信息可视化·课程设计·农业
Apache Flink12 小时前
Flink Agents 0.1.0 发布公告
大数据·flink
潘达斯奈基~14 小时前
在使用spark的applyInPandas方法过程中,遇到类型冲突问题如何解决
大数据·笔记
火星资讯15 小时前
腾多多数字零售模式:从成本转嫁到全生态共赢的破局实践
大数据
望获linux16 小时前
【实时Linux实战系列】实时 Linux 的自动化基准测试框架
java·大数据·linux·运维·网络·elasticsearch·搜索引擎
金宗汉16 小时前
《宇宙递归拓扑学:基于自指性与拓扑流形的无限逼近模型》
大数据·人工智能·笔记·算法·观察者模式
直有两条腿16 小时前
【数据迁移】HBase Bulkload批量加载原理
大数据·数据库·hbase
Joy T16 小时前
海南蓝碳:生态财富与科技驱动的新未来
大数据·人工智能·红树林·海南省·生态区建设