1. Flink 基础与环境搭建

各位同学,咱们正式开始这门《Flink 实时规则特征计算》课程。第一节课,我不会直接扔给你一堆晦涩的概念。咱们先聊聊 Flink 是什么,它从哪来,以及怎么把开发环境跑起来。这部分是地基,地基不稳,后面盖楼会塌。

1.1 Flink 发展史:从学术项目到实时计算标配

Flink 的故事挺有意思。它最早是柏林工业大学的一个研究项目,叫 Stratosphere。那时候还没多少人知道它。我记得 2014 年 Flink 成为 Apache 顶级项目时,圈子里还在争论「流处理到底有没有未来」。

转折点出现在 2016 年左右。当时阿里开始大规模用 Flink 替换 Storm,做双十一大屏的实时计算。为什么选 Flink?说白了,Storm 的「At-Least-Once」语义在金融场景下根本不敢用,丢数据或者重复计算都是大事故。Flink 的「Exactly-Once」和「事件时间」语义,正好戳中了痛点。

后来阿里把内部的 Blink 分支回馈给社区,Flink 1.9 之后性能直接起飞。到现在,Flink 已经是实时计算的事实标准。你去看招聘网站,大数据岗位十个有八个要求 Flink 经验。

核心时间线:

  • 2009年:柏林工业大学启动 Stratosphere 项目
  • 2014年:成为 Apache 顶级项目,改名 Flink
  • 2016年:阿里引入 Flink 替代 Storm
  • 2019年:Flink 1.9 合并 Blink 特性,批流一体成熟
  • 2023年:Flink 2.0 预览版发布,存算分离架构

1.2 核心概念:DataStream 与 DataSet

Flink 最核心的两个抽象,就是 DataStream 和 DataSet。你想想看,一个处理无限流数据,一个处理有限批数据。

DataStream 是实时计算的主角。数据源源不断进来,你没法等所有数据到齐再处理。比如监控用户点击行为,每秒钟几万条日志,必须来一条处理一条。DataStream 就是干这个的。

DataSet 是批处理的老大哥。数据已经完整存在,比如 HDFS 上的历史日志文件,一次性读进来做全量分析。不过从 Flink 1.12 开始,官方主推「批流一体」,DataSet API 逐渐被 DataStream 统一。我个人建议,新项目直接上手 DataStream,批处理也用它。

我的经验: 很多初学者纠结「什么时候用 DataStream,什么时候用 DataSet」。其实很简单——数据源是 Kafka、Pulsar、Socket 这种持续产生的,用 DataStream;数据源是 HDFS、本地文件这种固定大小的,用 DataStream 的批模式就行。DataSet 你了解一下概念就够了。

1.3 Flink vs Spark Streaming:到底选哪个?

这个问题我几乎每次技术交流都会被问到。咱们直接上对比表,一目了然。

对比维度 Flink Spark Streaming
处理模型 真正的逐条流处理 微批次(Micro-Batch)
延迟 毫秒级 秒级(取决于批次间隔)
事件时间语义 原生支持,精确到毫秒 支持但实现复杂
状态管理 内置状态后端,支持增量快照 依赖外部存储(如 Redis)
Exactly-Once 端到端保证 需要配置才能实现
SQL 支持 Flink SQL 成熟度高 Spark SQL 生态更丰富

说白了,如果你的业务对延迟敏感(比如风控、实时大屏、规则引擎),Flink 是唯一选择。如果你们团队 Spark 技术栈已经很成熟,批处理为主,偶尔做做准实时,Spark Streaming 也能凑合。

我曾经帮一家金融公司做过选型评估。他们原来用 Spark Streaming 做交易反欺诈,批次间隔设到 500 毫秒,结果还是漏了几笔异常交易。换成 Flink 后,延迟降到 50 毫秒以内,规则命中率提升了 30%。嗯,这就是架构选型带来的差距。

1.4 本地开发环境搭建:IDEA + Maven + Flink 集群

光说不练假把式。咱们现在就把环境搭起来。我习惯用 IDEA + Maven + Flink Standalone 集群 这套组合,轻量、可控、适合学习。

1.4.1 前置准备

  • JDK 8 或 11(推荐 JDK 8,兼容性最好)
  • Maven 3.6+
  • IDEA(社区版足够)
  • Flink 1.17.2(当前稳定版)

1.4.2 创建 Maven 项目

在 IDEA 里新建 Maven 项目,groupId 填 com.flink,artifactId 填 flink-course。然后修改 pom.xml,加入 Flink 依赖:

<properties>
    <flink.version>1.17.2</flink.version>
    <scala.binary.version>2.12</scala.binary.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-java</artifactId>
        <version>${flink.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-streaming-java</artifactId>
        <version>${flink.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-clients</artifactId>
        <version>${flink.version}</version>
    </dependency>
</dependencies>

注意: 依赖版本一定要统一。我见过有人 flink-java 用 1.14,flink-streaming-java 用 1.17,结果运行时各种 NoSuchMethodError。所有 Flink 相关依赖保持同一个版本号。

1.4.3 第一个 Flink 程序:WordCount

写一个最简单的流式 WordCount,验证环境是否通:

public class StreamingWordCount {
    public static void main(String[] args) throws Exception {
        // 1. 创建执行环境
        StreamExecutionEnvironment env = 
            StreamExecutionEnvironment.getExecutionEnvironment();

        // 2. 从 socket 读取数据(先启动 nc -lk 9999)
        DataStream<String> text = env.socketTextStream("localhost", 9999);

        // 3. 转换逻辑
        DataStream<Tuple2<String, Integer>> counts = text
            .flatMap((String line, Collector<Tuple2<String, Integer>> out) -> {
                for (String word : line.split(" ")) {
                    out.collect(new Tuple2<>(word, 1));
                }
            })
            .keyBy(value -> value.f0)
            .sum(1);

        // 4. 打印结果
        counts.print();

        // 5. 启动任务
        env.execute("Streaming WordCount");
    }
}

运行前记得在终端执行 nc -lk 9999。然后随便输入几个单词,你就能看到实时统计结果了。

1.4.4 启动本地 Flink 集群

下载 Flink 压缩包,解压后进入 bin/ 目录:

./start-cluster.sh

打开浏览器访问 http://localhost:8081,看到 Flink Web UI 就说明集群起来了。你可以把刚才的 WordCount 打成 jar 包,通过 Web UI 提交运行。

避坑指南: 我曾经在 Windows 上启动集群时,发现 Web UI 一直连不上。查了半天,原来是 Windows 的防火墙把 8081 端口拦了。如果你也遇到类似问题,先检查防火墙,或者临时关掉试试。

1.5 本章知识体系总览

下面这张图帮你把本章的核心脉络串起来。你可以把它当作一张「地图」,后面每学一个新知识点,都能在这张图上找到位置。

第1章:Flink基础与环境搭建 - 知识体系 Flink 基础 发展史 核心概念 Flink vs Spark 环境搭建 Stratosphere Blink 合并 DataStream / DataSet 微批次 vs 逐条 IDEA + Maven + 集群 说明:本章覆盖 Flink 发展脉络、核心抽象、竞品对比以及开发环境搭建 后续章节将在此基础上深入 DataStream API、状态管理和时间语义

好了,环境搭好,概念理清,咱们就可以正式开始写代码了。记住,Flink 的学习曲线不算陡,但需要你动手敲、动手跑。光看文档是学不会的。