第2章 环境准备:Flink 1.17 + Iceberg 1.5 + Hadoop 3.3 + MinIO 本地集群搭建

说实话,很多同学学 Iceberg 与 Flink 集成,卡就卡在环境搭建上。

版本不匹配、依赖冲突、MinIO 连不上……我当年第一次搭的时候,折腾了整整两天。后来我把这套组合拳打熟了,基本 30 分钟就能拉起一个可用的本地集群。

这一章,我就带你走一遍完整的搭建流程。你跟着做,保证能跑起来。

2.1 版本选型与兼容性说明

先定版本。我个人的习惯是:选稳定版,别追最新。最新版往往有坑,等社区踩完了再上不迟。

这套组合我验证过多次,兼容性没问题:

组件 版本 说明
Flink 1.17.2 支持 Iceberg 1.5 的 Flink 集成
Iceberg 1.5.0 最新稳定版,支持 Flink 1.17
Hadoop 3.3.6 提供文件系统抽象,MinIO 依赖它
MinIO RELEASE.2024-01-16 S3 兼容对象存储,替代 HDFS
Java 11 Flink 1.17 推荐 Java 11
注意:Iceberg 1.5 要求 Flink 最低版本为 1.14。如果你用 Flink 1.13 或更早,请升级。我曾经在 1.13 上硬跑 Iceberg 1.4,结果一堆序列化异常,后来老老实实升了级。

2.2 整体架构图

先看一张图,搞清楚各个组件怎么协作的。这样你搭的时候心里有数。

本地集群架构图 Flink 1.17 JobManager + TaskManager Iceberg 1.5 Hadoop 3.3 MinIO S3 兼容对象存储 数据流说明 1. Flink 提交 Iceberg 写入/读取任务 2. Iceberg 通过 Hadoop FileIO 访问存储 3. Hadoop 使用 S3A 协议连接 MinIO 4. MinIO 提供对象存储能力 部署方式 • 单机模式(本章) • 所有进程在同一台机器 • 适合开发测试

说白了,数据流向就是:Flink → Iceberg → Hadoop → MinIO。每一层都有明确的职责,别搞混了。

2.3 安装 MinIO

MinIO 是最简单的一环。我建议用 Docker 启动,省心。

# 拉取镜像
docker pull minio/minio:RELEASE.2024-01-16

# 启动 MinIO 服务
docker run -d \
  --name minio \
  -p 9000:9000 \
  -p 9001:9001 \
  -e MINIO_ROOT_USER=admin \
  -e MINIO_ROOT_PASSWORD=password \
  -v /data/minio:/data \
  minio/minio server /data --console-address ":9001"

启动后,访问 http://localhost:9001,用 admin/password 登录。

小技巧:记得创建一个 bucket,名字叫 iceberg-warehouse。我习惯把 Iceberg 的表数据都放在这个桶里,方便管理。

2.4 安装 Hadoop 3.3

Hadoop 在这里的角色是提供 S3AFileSystem,让 Iceberg 能通过 S3 协议读写 MinIO。

你不需要启动 HDFS 集群,只需要把 Hadoop 的 JAR 包放到 Flink 的 lib 目录下就行。

# 下载 Hadoop 3.3.6
wget https://archive.apache.org/dist/hadoop/common/hadoop-3.3.6/hadoop-3.3.6.tar.gz

# 解压
tar -xzf hadoop-3.3.6.tar.gz -C /opt/

# 设置环境变量
export HADOOP_HOME=/opt/hadoop-3.3.6
export PATH=$PATH:$HADOOP_HOME/bin

关键文件是 hadoop-aws-3.3.6.jar 和 aws-java-sdk-bundle-1.12.262.jar。这两个缺一不可。

踩坑提醒:我曾经只放了 hadoop-aws,没放 aws-sdk,结果 Flink 任务启动时报 ClassNotFoundException: com.amazonaws.services.s3.AmazonS3。嗯,这种低级错误犯一次就够了。

2.5 安装 Flink 1.17

Flink 的安装中规中矩。下载、解压、配置。

# 下载 Flink 1.17.2
wget https://archive.apache.org/dist/flink/flink-1.17.2/flink-1.17.2-bin-scala_2.12.tgz

# 解压
tar -xzf flink-1.17.2-bin-scala_2.12.tgz -C /opt/

# 设置环境变量
export FLINK_HOME=/opt/flink-1.17.2
export PATH=$PATH:$FLINK_HOME/bin

然后修改 conf/flink-conf.yaml,加上 MinIO 相关的配置:

# Flink 配置
jobmanager.rpc.address: localhost
jobmanager.memory.process.size: 2048m
taskmanager.memory.process.size: 2048m
taskmanager.numberOfTaskSlots: 4

# S3 配置
s3.endpoint: http://localhost:9000
s3.access-key: admin
s3.secret-key: password
s3.path.style.access: true

关键点:s3.path.style.access: true 必须设置。MinIO 使用路径风格访问,不是虚拟主机风格。不设这个,Iceberg 连不上 MinIO。

2.6 集成 Iceberg 1.5

Iceberg 不需要单独安装。你只需要把它的 JAR 包放到 Flink 的 lib 目录下。

我建议直接下载 iceberg-flink-runtime-1.17-1.5.0.jar,这个包包含了所有依赖,省事。

# 下载 Iceberg Flink Runtime
wget https://repo1.maven.org/maven2/org/apache/iceberg/iceberg-flink-runtime-1.17/1.5.0/iceberg-flink-runtime-1.17-1.5.0.jar

# 复制到 Flink lib 目录
cp iceberg-flink-runtime-1.17-1.5.0.jar $FLINK_HOME/lib/

# 同时复制 Hadoop 相关 JAR
cp $HADOOP_HOME/share/hadoop/tools/lib/hadoop-aws-3.3.6.jar $FLINK_HOME/lib/
cp $HADOOP_HOME/share/hadoop/tools/lib/aws-java-sdk-bundle-1.12.262.jar $FLINK_HOME/lib/

你想想看,这样 Flink 启动时就会自动加载 Iceberg 的 Catalog 和 Table API。

2.7 验证集群

启动 Flink 集群:

# 启动 Flink
$FLINK_HOME/bin/start-cluster.sh

# 检查进程
jps
# 应该看到:
# 12345 StandaloneSessionClusterEntrypoint
# 12346 TaskManagerRunner

然后跑一个简单的 SQL 验证:

# 启动 SQL Client
$FLINK_HOME/bin/sql-client.sh

# 在 SQL Client 中执行
CREATE CATALOG iceberg_catalog WITH (
  'type' = 'iceberg',
  'catalog-type' = 'hadoop',
  'warehouse' = 's3a://iceberg-warehouse/',
  's3.endpoint' = 'http://localhost:9000',
  's3.access-key-id' = 'admin',
  's3.secret-access-key' = 'password'
);

USE CATALOG iceberg_catalog;

CREATE TABLE test_table (
  id INT,
  name STRING
) WITH (
  'format-version' = '2'
);

INSERT INTO test_table VALUES (1, 'hello'), (2, 'world');

SELECT * FROM test_table;

如果能看到两行数据,恭喜你,环境搭好了。

验证小技巧:去 MinIO 控制台看看 iceberg-warehouse 桶里是不是多了目录。Iceberg 的元数据文件和数据文件都在那里。我每次搭完环境都会看一眼,确认数据确实写进去了。

2.8 常见问题与避坑

这里列几个我踩过的坑,你遇到了直接对照:

问题 原因 解决方案
连接 MinIO 超时 MinIO 未启动或端口不对 检查 docker ps,确认 9000 端口映射
权限拒绝 Access Key / Secret Key 错误 检查 flink-conf.yaml 中的配置
ClassNotFoundException 缺少 JAR 包 确认 hadoop-aws 和 aws-sdk 在 lib 目录
路径风格错误 未设置 s3.path.style.access 在配置中加上 s3.path.style.access: true
Iceberg 版本不兼容 Flink 与 Iceberg 版本不匹配 使用 iceberg-flink-runtime-1.17

嗯,基本上就这些。环境搭好了,后面的事情就顺了。