Apache Flink 2.2.0 源码编译从环境准备到 PyFlink 打包一次讲清

先说一个很现实的问题:

已经有官方二进制包了,为什么还要自己编译?

原因通常有下面几种。

1. 想读源码、打断点调试

如果你要研究 Flink 内部执行流程,比如:

  • JobGraph 如何生成
  • Checkpoint 如何触发
  • Task 是怎么运行的
  • 调度和 failover 是怎么实现的

那么只看源码还不够,很多时候你必须能在本地把工程编译起来,甚至跑起来。

2. 想做二次开发

例如你可能想:

  • 修改某个 connector
  • 调整某段 runtime 逻辑
  • 增加公司内部定制能力
  • 改造提交流程或运行机制

这时候,自己编译源码就是基础能力。

3. 想参与社区开发

如果你打算给 Flink 提 PR,源码编译几乎是第一道门槛。

你必须保证自己本地能够完成构建,否则后面的调试、改动、测试都很难继续。

很多人一开始只关注 Java / Scala 侧,但当你需要构建可安装的 PyFlink 包时,源码编译也绕不开。

所以说,Flink 源码编译并不是"高级玩法",而是深入学习和开发 Flink 的基本功。

在正式开始之前,先把基础环境准备好。

这一步看着简单,但其实决定了你后面会不会疯狂踩坑。

1. 源码

你需要先拿到 Flink 源码。

可以下载 release source,也可以直接从 Git 仓库 clone:

bash 复制代码
git clone https://github.com/apache/flink.git

如果你只是学习最新开发分支,可以直接 clone。

如果你是针对 Flink 2.2.0 做研究,建议切到对应版本分支或 tag,避免源码版本与文档描述不一致。

2. Maven

Flink 2.2.0 要求:

  • Maven 3.8.6

注意,这不是"差不多就行"的地方。

大型 Maven 工程里,版本不合适时,可能不会立刻给你一个很明确的报错,而是各种诡异行为。

所以,比较稳妥的做法是先检查一下版本:

bash 复制代码
mvn -version

确保输出中 Maven 版本是 3.8.6。

3. JDK

Flink 2.2.0 源码编译要求:

  • Java 11

这一点很重要。

不是"JDK 8 也许能试试",也不是"JDK 17 看起来更高版本应该也行"。

官方明确要求构建使用 Java 11,所以最稳妥的方案就是直接使用 JDK 11。

同样建议先检查:

bash 复制代码
java -version
javac -version

确保当前 shell 环境里生效的版本确实是 Java 11。

如果你只想先把 Flink 编译成功,最简单的方法就是在源码根目录执行:

bash 复制代码
mvn clean install -DskipTests

这个命令可以拆开理解:

1. clean

先清理历史构建产物。

也就是把之前编译出来的内容先删掉,避免旧文件干扰当前构建。

2. install

执行完整构建,并把产物安装到本地 Maven 仓库。

这样后续本地模块之间的依赖也能正常解析。

3. -DskipTests

跳过测试。

对于第一次构建,或者你只是想尽快把工程编出来,这个参数非常实用。

因为 Flink 的测试量不少,如果全量跑测试,整体耗时会明显上升。

所以,这条命令其实就是在做一件事:

先别管测试,优先把整个 Flink 工程干净地编译出来。

四、为什么第一次建议先用这条最朴素的命令?

很多人一上来就想加各种优化参数,比如:

  • 并行编译
  • 跳过 WebUI
  • fast profile
  • 只编某些模块

这些都没错,但我还是建议第一次先用:

bash 复制代码
mvn clean install -DskipTests

原因很简单:

先确认"能不能正常编",再考虑"怎么编得更快"。

如果你一开始就把参数加满,后面一旦失败,你会很难判断问题到底出在:

  • 环境没配对
  • Maven 版本不对
  • JDK 不对
  • 某个 profile 冲突
  • 某个优化参数带来的副作用

所以第一轮构建,建议尽量朴素。

只要这一步过了,后面再追求编译提速就会更踏实。

等你确认基础构建没问题之后,就可以开始考虑"速度"了。

因为 Flink 工程体量不小,完整构建时间并不短。

尤其在机械硬盘、普通 SSD、内存较小或者 CPU 核心较少的机器上,等待会更加明显。

官方给了几种典型加速方式。

1. 跳过测试

这一点前面已经提到过了:

bash 复制代码
-DskipTests

这通常是最直接的提速方式。

2. 使用 fast Maven Profile

可以通过:

bash 复制代码
-Dfast

跳过一些 QA 插件和 javadoc 生成。

这对构建速度影响非常明显,尤其是本地开发场景。

因为你本地频繁编译时,通常并不需要每次都完整跑 QA 和文档生成。

3. 跳过 WebUI 构建

Flink 提供了一个专门的 profile:

bash 复制代码
-Pskip-webui-build

这个参数用于跳过 WebUI 编译。

为什么这个参数很有用?

因为 WebUI 构建往往会带来额外文件读写,而这些读写在慢存储设备上尤其耗时。

如果你当前根本不关心 Web UI,只是做 runtime 或 API 层开发,那完全可以跳过。

4. 使用 Maven 并行构建

例如:

bash 复制代码
-T 1C

表示按 CPU 核心数并行构建模块。

如果你的机器核心数较多,这个参数能明显提高速度。

例如一个推荐的加速命令是:

bash 复制代码
mvn clean install -DskipTests -Dfast -Pskip-webui-build -T 1C

这条命令的思路很明确:

  • 清理旧构建
  • 执行安装
  • 跳过测试
  • 跳过额外 QA / javadoc
  • 跳过 WebUI
  • 尽量并行利用 CPU

对于日常本地开发,这已经是一个很实用的高频命令组合。

六、并行构建虽然快,但为什么官方提醒要小心?

这里有一个特别值得注意的点。

虽然 Maven 并行构建能提速,但官方也明确提醒:

并行构建可能因为 maven-shade-plugin 的问题出现死锁。

也就是说,-T 1C 虽然好用,但它不是永远安全的。

1. 为什么会这样?

因为 Flink 是大型多模块项目,shade、打包、聚合这些过程本身就比较复杂。

在并行场景下,某些插件组合可能会触发死锁或不稳定行为。

2. 官方更推荐的做法

更稳妥的思路是分两步走:

第一步:前置阶段并行执行

例如:

  • validate
  • test-compile
  • test

这些前置阶段可以考虑并行跑。

第二步:最终打包阶段单线程执行

例如:

  • package
  • verify
  • install

这些最终产物阶段尽量单线程,减少插件死锁概率。

也就是说,官方态度并不是"不让你并行",而是提醒你:

并行构建适合加速前置阶段,但最终打包阶段最好保守一点。

如果你只是日常本地开发,偶尔用并行构建通常问题不大;

但如果你追求稳定、尤其在 CI 或关键构建里,还是要更谨慎。

七、fastskip-webui-build 为什么能明显提升速度?

这一点官方也特别强调了。

fastskip-webui-build 对构建时间影响很大,尤其在 较慢的存储设备 上更明显。

原因在于它们会减少大量:

  • 小文件读写
  • QA 相关处理
  • javadoc 生成
  • WebUI 构建相关中间文件操作

而小文件 IO,恰恰是很多存储设备最容易拖慢整体速度的地方。

所以你会发现一个很有意思的现象:

  • CPU 并不是一直满载
  • Maven 也不是一直卡死
  • 但整体构建时间就是长

这背后往往不是"算不动",而是"文件系统折腾太多"。

因此在本地开发阶段,-Dfast -Pskip-webui-build 往往是非常划算的优化。

八、如果你还要构建 PyFlink,事情会稍微复杂一点

主工程编译完成之后,如果你还需要构建可供 pip 安装的 PyFlink 包,就还得继续准备 Python 相关环境。

这部分很多 Java 开发者第一次会有点陌生,但其实不算特别难。

PyFlink 构建的前提条件主要有两类。

这一点非常关键。

如果你想打包 PyFlink,必须先完成 Flink 主工程构建。

也就是说,前面的:

bash 复制代码
mvn clean install -DskipTests

不是可选项,而是前置条件。

2. 准备 Python 环境

官方要求 Python 版本为以下之一:

  • Python 3.9
  • Python 3.10
  • Python 3.11
  • Python 3.12

可以先检查版本:

bash 复制代码
python --version

如果版本不在这个范围内,后续很可能会遇到兼容性问题。

十、如果想启用 Cython 扩展支持,还需要 C 编译器

PyFlink 支持可选的 Cython 扩展构建。

如果你想构建带 Cython 扩展支持的 PyFlink,那么还需要系统具备 C 编译器。

不同操作系统的准备方式不同。

1. Linux

很多 Linux 发行版本身已经有 GCC。

如果没有,可以手动安装。

例如 Ubuntu / Debian 下:

bash 复制代码
sudo apt-get install build-essential

2. macOS

macOS 上一般需要安装:

  • Xcode Command Line Tools

这样系统才会具备 GCC 相关工具链能力。

3. Windows

原文这部分没有展开写 Windows,但实际开发里,Windows 通常需要额外准备本地 C/C++ 编译工具链。

如果只是普通 PyFlink 打包,不强依赖 Cython 扩展,也可以先不走这条路径。

在准备构建 PyFlink 之前,还需要安装开发依赖。

可以执行:

bash 复制代码
python -m pip install --group flink-python/pyproject.toml:dev

这条命令的作用可以理解为:

根据 Flink 源码中 flink-python 的开发依赖声明,安装构建和开发所需依赖。

对于 PyFlink 打包来说,这一步很重要。

如果依赖没装齐,后面 setup.py 构建阶段很容易直接报错。

十二、如何正式打包 PyFlink?

准备工作完成后,进入 Flink 源码根目录,执行官方给出的这一组命令:

bash 复制代码
cd flink-python
python setup.py sdist bdist_wheel
cd apache-flink-libraries
python setup.py sdist
cd ..

这组命令本质上是在做两件事。

会生成:

  • sdist 包
  • wheel 包

也就是说,既会生成源码分发包,也会生成 wheel 二进制安装包。

这里会生成 sdist 包。

构建完成后,产物位置如下。

会出现在:

text 复制代码
./flink-python/apache-flink-libraries/dist/

安装方式例如:

bash 复制代码
python -m pip install apache-flink-libraries/dist/*.tar.gz

会出现在:

text 复制代码
./flink-python/dist/

可以安装 wheel 包,例如:

bash 复制代码
python -m pip install dist/*.whl

或者使用 sdist 包安装。

对于大多数本地测试和开发场景,直接安装 .whl 往往更方便。

十四、Scala 版本问题:Java 用户可以忽略,但 Scala 用户必须关心

这一节很多纯 Java 用户看到会自动略过,这完全没问题。

因为如果你只使用 Java API 和 Java 相关库,Scala 版本一般不是你最关心的事情。

但如果你涉及:

  • Scala API
  • Scala 编写的 Flink 模块
  • 依赖 Scala 二进制兼容性的项目

那么这一节就必须认真看。

1. 为什么 Scala 版本要匹配?

因为 Scala 和 Java 不一样。

Java 很强调向后兼容,而 Scala 的二进制兼容性并没有那么"宽松"。

所以,如果你的项目依赖某个特定 Scala 二进制版本,而 Flink 默认构建出来的版本不同,就可能带来依赖冲突或者运行问题。

从 Flink 1.15 开始:

  • 不再支持 Scala 2.11
  • 默认使用 Scala 2.12 构建

这意味着大多数场景下,你看到的默认 Flink 构建结果都和 Scala 2.12 绑定。

3. 如果想指定 Scala 版本怎么做?

可以使用:

bash 复制代码
mvn clean install -DskipTests -Dscala.version=<scala version>

例如你有特殊依赖场景,需要明确控制 Scala 版本,就可以通过这个参数切换。

不过这里也要提醒一点:

不是所有随便写一个 Scala 版本号都能工作。

要确保所选版本确实是 Flink 当前版本支持的二进制 Scala 版本。

十五、加密文件系统下的一个隐藏坑:File name too long

这一节很容易被忽略,但真碰上了会让人非常迷惑。

如果你的 home 目录位于某些加密文件系统中,比如某些 Linux 环境下使用的 encfs,那么在构建 Flink 时,可能遇到:

text 复制代码
java.io.IOException: File name too long

很多人第一次看到这个错误时,会以为:

  • 是路径写错了
  • 是 Maven 缓存坏了
  • 是插件生成文件异常

其实未必。

有时候问题根源就是:加密文件系统对文件名长度有限制。

而 Flink 构建过程里的某些生成类名、编译产物路径,可能正好超过这个限制。

1. 解决思路

官方给出的 workaround 是,在出问题模块的 pom.xml 中,给相关编译器配置添加:

xml 复制代码
<args>
    <arg>-Xmax-classfile-name</arg>
    <arg>128</arg>
</args>

例如如果问题出在 flink-yarn 模块,那么就把这段配置加到该模块 pom.xmlscala-maven-plugin<configuration> 里。

2. 这个问题说明了什么?

这其实也从侧面说明 Flink 工程编译不是"小打小闹"的项目。

模块多、插件多、生成过程复杂,底层文件系统特性都可能影响构建结果。

所以如果你在一些特殊环境下编译失败,不要只盯着 Java 和 Maven,也要考虑是不是操作系统层面的限制。

如果你问我,日常开发时最常用哪几类命令,我会比较推荐下面几种分层用法。

1. 第一轮验证环境是否正常

bash 复制代码
mvn clean install -DskipTests

用途:

  • 验证 Maven / JDK / 工程依赖是否都正常
  • 获取一个最标准的初始构建结果

2. 日常本地提速构建

bash 复制代码
mvn clean install -DskipTests -Dfast -Pskip-webui-build

用途:

  • 提高日常开发效率
  • 跳过不必要的额外开销
  • 适合本地频繁修改后快速验证

3. 想尝试更快时加并行

bash 复制代码
mvn clean install -DskipTests -Dfast -Pskip-webui-build -T 1C

用途:

  • 进一步榨取本机 CPU 并行能力
  • 适合机器配置较高时使用

注意:

  • 有概率遇到 maven-shade-plugin 相关死锁
  • 关键构建时不要完全迷信并行参数

先完成主工程编译,再执行:

bash 复制代码
cd flink-python
python setup.py sdist bdist_wheel
cd apache-flink-libraries
python setup.py sdist
cd ..

这一节很适合拿来做"自查清单"。

1. JDK 版本不对

这是最常见问题之一。

Flink 2.2.0 要求 Java 11 构建,不要想当然用别的版本直接顶上。

2. Maven 版本不匹配

大型项目对 Maven 版本是比较敏感的,别忽视这一点。

3. 一上来就全开并行参数

这样虽然可能快,但一旦失败,定位会很麻烦。

建议先用最基础命令确认环境无误。

PyFlink 依赖主工程结果,顺序别搞反。

5. Python 版本超出支持范围

PyFlink 当前支持的是 3.9 到 3.12,太老或太新的版本都可能有问题。

6. 忽略系统层面的限制

例如加密文件系统、路径太长、权限问题,这些都可能成为构建失败的根源。

回头看这篇文章,你会发现 Flink 源码编译这件事,本质上并不复杂,核心就是几件事:

  • 准备正确的源码
  • 使用 Maven 3.8.6
  • 使用 Java 11
  • 先跑通基础构建
  • 再根据需要优化构建速度
  • 构建 PyFlink 时准备 Python 与可选 C 编译环境
  • 特殊场景下关注 Scala 版本与文件系统限制

但另一方面,它又绝不只是"敲一句 Maven 命令"这么简单。

因为当你真的开始自己编译 Flink 源码时,说明你已经不满足于"会用 Flink"了。

你正在往更深一层走:

  • 想理解它怎么工作
  • 想调试它的内部机制
  • 想定制它
  • 想贡献它
  • 想把它变成真正可控的工程能力

而源码编译,正是这一切的起点。

相关推荐
黑客说2 小时前
独领无限流赛道:白日梦科技,重新定义AI时代的互动娱乐标杆
大数据·人工智能
综合热讯2 小时前
同健梦社区计划正式发布!
大数据
武子康2 小时前
大数据-247 离线数仓 - 电商分析 Hive 拉链表实战:订单历史状态增量刷新、闭链逻辑与错误排查
大数据·后端·apache hive
APO Research2 小时前
Virtual Commissioning产业趋势:数字孪生驱动的虚拟调试如何重塑工业自动化工程体系
大数据·自动化·智能制造·数字孪生·工业自动化·工程数字化
悢七2 小时前
flink-yarn提交任务,application无限次appattempt
flink·yarn
言午说数据2 小时前
数仓入门篇-数仓分层
大数据·面试
IPHWT 零软网络2 小时前
让前厅更高效,让服务更暖心——HWT2.0酒店话务台,重构宾客体验新范式
大数据·重构
源码技术栈2 小时前
整合物联网、大数据、人工智能等技术的Java智慧工地项目管理系统源码
大数据·人工智能·物联网·源码·二次开发·项目·智慧工地
掘根3 小时前
【即时通讯系统】环境搭建4——Elasticsearch(ES)
大数据·elasticsearch·搜索引擎