3. Flink 开发环境搭建:从本地到集群

本章将引导你完成 Flink 开发环境的完整搭建,涵盖本地开发环境(IDEA + Maven)、三种主流集群模式(Standalone / YARN / K8s),并通过经典的 WordCount 程序验证环境可用性。这是后续构建实时风控规则引擎的基础设施层。

3.1 本地开发环境:IDEA + Maven

本地开发环境是编码、调试和单元测试的核心场所。推荐使用 IntelliJ IDEA(Community 或 Ultimate 版)配合 Maven 进行项目管理。

3.1.1 环境准备清单

组件 推荐版本 说明
JDK 1.8 / 11 (LTS) Flink 1.14+ 对 JDK 11 支持更好;风控场景建议 JDK 8
Maven 3.6.3+ 用于依赖管理和构建打包
IntelliJ IDEA 2023.x 安装 Scala 插件(如使用 Scala API)
Flink 1.17.x 当前稳定版,兼容性最佳

3.1.2 Maven 项目骨架与核心依赖

在 IDEA 中创建 Maven 项目后,pom.xml 需引入 Flink 核心依赖。以下为最小化配置:

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

<dependencies>
    <!-- Flink Java 核心 -->
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-java</artifactId>
        <version>${flink.version}</version>
        <scope>provided</scope>
    </dependency>
    <!-- Flink Streaming -->
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-streaming-java</artifactId>
        <version>${flink.version}</version>
        <scope>provided</scope>
    </dependency>
    <!-- Flink 客户端(本地执行用) -->
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-clients</artifactId>
        <version>${flink.version}</version>
        <scope>provided</scope>
    </dependency>
</dependencies>
作用域说明: 上述依赖使用 provided 作用域,因为 Flink 集群运行时已包含这些 jar 包。本地 IDEA 运行时会自动从 classpath 加载,无需额外配置。

3.2 Flink 集群模式:Standalone / YARN / K8s

生产环境中的 Flink 集群部署有三种主流模式,每种模式在资源管理、隔离性和运维复杂度上各有侧重。风控场景通常优先选择 YARN 或 K8s 模式以获得更好的资源弹性。

3.2.1 三种模式对比

特性 Standalone YARN Kubernetes (K8s)
资源管理 Flink 自身管理 YARN ResourceManager K8s Scheduler
启动速度 快(常驻进程) 中等(按需申请) 中等(Pod 启动)
资源隔离 弱(进程级) 中(Container) 强(Pod + cgroup)
运维复杂度 低 中 高
适用场景 开发测试、小规模 生产环境(Hadoop 生态) 云原生、微服务架构

3.2.2 Standalone 模式快速启动

Standalone 模式适合本地调试和功能验证。下载 Flink 二进制包后,执行以下命令即可启动单节点集群:

# 启动集群(默认 1 个 JobManager + 1 个 TaskManager)
./bin/start-cluster.sh

# 访问 Web UI
http://localhost:8081

# 停止集群
./bin/stop-cluster.sh

3.2.3 YARN 模式(推荐生产)

YARN 模式将 Flink 作业作为 YARN 应用运行,资源由 YARN 统一管理。支持两种提交方式:

  • Session 模式: 预先启动一个常驻 Flink 集群,多个作业共享资源。
  • Per-Job 模式: 每个作业独立启动一个集群,作业结束后自动释放资源。
# Per-Job 模式提交作业
./bin/flink run -m yarn-cluster \
  -yjm 1024 -ytm 2048 \
  -c com.example.WordCount \
  ./target/flink-demo-1.0.jar

3.2.4 Kubernetes 模式(云原生)

K8s 模式提供容器级隔离和自动扩缩容能力。Flink 官方提供 flink-kubernetes-operator 简化部署。以下为原生 K8s Session 集群启动示例:

# 创建 ConfigMap 和 Deployment
kubectl create configmap flink-config --from-file=conf/
kubectl apply -f flink-jobmanager-deployment.yaml
kubectl apply -f flink-taskmanager-deployment.yaml

# 暴露 JobManager 服务
kubectl expose deployment flink-jobmanager --type=NodePort --port=8081
风控场景建议: 若公司已有 Hadoop 集群,优先选择 YARN Per-Job 模式;若正在推进容器化,则选择 K8s 模式。Standalone 模式仅用于开发测试,不建议用于生产风控推理。

3.3 第一个 Flink 程序:WordCount

WordCount 是 Flink 的 "Hello World",用于验证环境搭建是否正确。以下实现基于 DataStream API,模拟实时流处理。

3.3.1 程序结构

下图展示了 WordCount 在 Flink 中的执行流程:

Flink WordCount 数据流图 Socket 数据源 FlatMap 分词 KeyBy 分组 Sum 累加 Print 输出 说明:数据从 Socket 读取 → 分词为 (word, 1) → 按 word 分组 → 累加计数 → 控制台输出

3.3.2 完整代码实现

在 IDEA 中创建 WordCount.java,代码如下:

import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.util.Collector;

public class WordCount {
    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(new Tokenizer())
            .keyBy(value -> value.f0)
            .sum(1);

        // 4. 输出结果到控制台
        counts.print();

        // 5. 执行作业
        env.execute("Flink WordCount");
    }

    // 自定义 FlatMap 函数:将每行文本拆分为单词
    public static class Tokenizer implements FlatMapFunction<String, Tuple2<String, Integer>> {
        @Override
        public void flatMap(String value, Collector<Tuple2<String, Integer>> out) {
            String[] words = value.toLowerCase().split("\\W+");
            for (String word : words) {
                if (word.length() > 0) {
                    out.collect(new Tuple2<>(word, 1));
                }
            }
        }
    }
}

3.3.3 运行与验证

按以下步骤验证环境:

  1. 启动数据源: 在终端执行 nc -lk 9999(Linux/Mac)或安装 netcat 后执行。
  2. 运行程序: 在 IDEA 中直接右键运行 WordCount.main()。
  3. 输入数据: 在 nc 终端输入 hello flink hello world。
  4. 观察输出: IDEA 控制台应打印类似 (hello,1) (flink,1) (hello,2) (world,1) 的结果。
验证成功标志: 控制台输出增量更新的单词计数,且无异常堆栈。若使用 Standalone 集群,可在 Web UI(localhost:8081)中看到作业状态。

3.4 开发环境常见问题与避坑

问题现象 可能原因 解决方案
IDEA 运行报 ClassNotFoundException 依赖 scope 为 provided,IDEA 未包含 在 Run Configuration 中勾选 "Include dependencies with 'Provided' scope"
Socket 连接被拒绝 nc 未启动或端口被占用 检查端口:lsof -i:9999,确保 nc 已启动
YARN 提交失败 Hadoop 配置未加载或版本不兼容 设置 HADOOP_CONF_DIR 环境变量,检查 Flink 与 Hadoop 版本矩阵
K8s Pod 启动后 CrashLoopBackOff 资源限制过小或 ConfigMap 配置错误 检查 TaskManager 内存请求,查看 kubectl logs

3.5 本章小结

通过本章学习,你应掌握:

  • 使用 IDEA + Maven 搭建 Flink 开发项目,理解 provided 作用域的含义。
  • 区分 Standalone / YARN / K8s 三种集群模式的适用场景和启动方式。
  • 编写并运行第一个 Flink DataStream 程序 WordCount,验证环境可用性。