4. 环境搭建与准备:JDK、Maven、MySQL、Kafka、Flink集群的安装与配置

说实话,做实时数据管道这件事,环境搭不好,后面全是坑。我见过太多人把时间耗在版本冲突上,最后连个 Hello World 都跑不起来。这一章,咱们就把地基打牢。

我会带你一步步装好 JDK、Maven、MySQL、Kafka 和 Flink 集群。每个环节我都会告诉你「为什么这么配」,而不是扔给你一堆命令就跑。

核心原则:所有组件版本必须提前对齐。我习惯用一张表格锁死版本号,避免「装到一半发现不兼容」的尴尬。

4.1 版本选型与对齐

先看这张表。这是我目前在生产环境验证过的组合,你照着来就行。

组件 推荐版本 说明
JDK 1.8.0_202 或 11.0.x Flink 1.14+ 对 JDK 11 支持更好,但 1.8 依然稳定
Maven 3.6.3 或 3.8.x 3.6.3 最稳,3.8.x 对依赖解析更严格
MySQL 8.0.28+ CDC 需要开启 binlog,8.0 默认 row 格式
Kafka 2.8.1 或 3.2.0 2.8.1 去掉了 ZK 依赖,但 3.2.0 更成熟
Flink 1.14.6 或 1.16.0 1.14 生态最全,1.16 性能有提升
我的习惯:本地开发用 JDK 8 + Flink 1.14,生产用 JDK 11 + Flink 1.16。为什么?JDK 8 的 G1GC 在低内存场景下更友好,调试方便。

4.2 JDK 安装与配置

这一步太基础了,但我要强调一个细节:JAVA_HOME 必须指向 JDK 根目录,不是 JRE。 我之前帮一个同事排查问题,他配的是 JRE 路径,Flink 启动直接报 ClassNotFoundException。

安装步骤很简单,我列一下关键点:

  1. 下载 tar.gz 包,解压到 /usr/local/jdk1.8.0_202
  2. 编辑 /etc/profile,添加环境变量
  3. 执行 source /etc/profile 使其生效
  4. 验证:java -version 和 javac -version
# /etc/profile 追加内容
export JAVA_HOME=/usr/local/jdk1.8.0_202
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
注意:不要用系统自带的 OpenJDK,除非你确定它包含完整的 JavaFX 和 Nashorn 引擎。Flink 的 Table API 在某些场景下会用到这些。

4.3 Maven 安装与仓库配置

Maven 这东西,说白了就是个依赖管家。但很多人忽略了一个关键点:settings.xml 里的 mirror 配置。 国内网络环境你懂的,不配阿里云镜像,一个 Flink CDC 依赖能下载半小时。

我一般这样配:

<mirrors>
  <mirror>
    <id>aliyunmaven</id>
    <mirrorOf>central</mirrorOf>
    <name>阿里云公共仓库</name>
    <url>https://maven.aliyun.com/repository/public</url>
  </mirror>
</mirrors>

另外,记得把 localRepository 指向一个非系统盘路径。我习惯用 /opt/maven/repo,这样重装系统后仓库还在。

4.4 MySQL 安装与 CDC 前置配置

MySQL 的安装本身不复杂,但为了 CDC,你必须做两件事:

  • 开启 binlog:在 my.cnf 中配置 log_bin=mysql-bin 和 binlog_format=ROW
  • 创建 CDC 专用用户:赋予 REPLICATION SLAVE 和 REPLICATION CLIENT 权限

我曾经踩过一个坑:binlog 格式配成了 STATEMENT,结果 Debezium 捕获到的数据全是 SQL 语句,根本没法用。你想想看,实时管道要的是「某行数据变了」,而不是「执行了什么 SQL」。

# my.cnf 关键配置
[mysqld]
server_id=1
log_bin=mysql-bin
binlog_format=ROW
expire_logs_days=7
max_binlog_size=100M

# 创建 CDC 用户
CREATE USER 'cdc_user'@'%' IDENTIFIED BY 'cdc_pass';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'cdc_user'@'%';
FLUSH PRIVILEGES;
避坑指南:MySQL 8.0 默认使用 caching_sha2_password 插件,Flink CDC 连接时可能报认证错误。我建议在创建用户时指定 IDENTIFIED WITH mysql_native_password BY '...'。

4.5 Kafka 集群搭建

Kafka 的安装其实就三步:解压、改配置、启动。但集群模式下,broker.id 和 advertised.listeners 这两个参数最容易出错。

我一般用三台机器搭集群,每台机器的配置差异只有 broker.id 和 listeners 的 IP 地址。

# server.properties 关键配置(以 broker 1 为例)
broker.id=1
listeners=PLAINTEXT://192.168.1.101:9092
advertised.listeners=PLAINTEXT://192.168.1.101:9092
log.dirs=/data/kafka/logs
zookeeper.connect=192.168.1.101:2181,192.168.1.102:2181,192.168.1.103:2181

启动命令很简单:

# 先启动 ZK(如果使用独立 ZK)
bin/zookeeper-server-start.sh config/zookeeper.properties

# 再启动 Kafka
bin/kafka-server-start.sh config/server.properties
注意:生产环境不要用 Kafka 自带的 ZK。我见过有人图省事直接用内置 ZK,结果集群重启时 ZK 和 Kafka 同时挂掉,数据全丢了。独立部署 ZK 集群是底线。

4.6 Flink 集群部署

Flink 支持多种部署模式,咱们课程里用 Standalone Cluster,因为最直观,方便调试。

配置 Flink 集群,核心是 flink-conf.yaml 和 masters、workers 文件。

# flink-conf.yaml 关键配置
jobmanager.rpc.address: 192.168.1.101
jobmanager.rpc.port: 6123
jobmanager.memory.process.size: 2048m
taskmanager.memory.process.size: 4096m
taskmanager.numberOfTaskSlots: 4
parallelism.default: 2

# masters 文件
192.168.1.101:8081

# workers 文件
192.168.1.101
192.168.1.102
192.168.1.103

启动集群:

bin/start-cluster.sh

访问 http://192.168.1.101:8081,看到 Web UI 就说明成功了。

4.7 整体架构图

下面这张图展示了我们搭建好的环境全貌。你可以看到数据从 MySQL 流出,经过 Kafka,最终被 Flink 消费。

实时数据管道环境架构图 MySQL 8.0 binlog=ROW Debezium CDC Flink CDC Connector Kafka 2.8.1 3 节点集群 Flink 1.14.6 Standalone 集群 读取 binlog 发送 CDC 事件 消费数据流 环境依赖关系 • JDK 1.8 / 11 是所有组件的运行基础 • Maven 用于编译 Flink 作业,需要配置阿里云镜像加速 • MySQL 必须开启 binlog=ROW 模式,CDC 才能正常工作

4.8 验证环境

装完别急着高兴,跑个简单的验证脚本,确保所有组件能正常通信。

# 1. 验证 MySQL binlog 是否开启
mysql -u cdc_user -p -e "SHOW VARIABLES LIKE 'log_bin%';"

# 2. 验证 Kafka 能否收发消息
bin/kafka-console-producer.sh --broker-list localhost:9092 --topic test
bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test --from-beginning

# 3. 验证 Flink 集群状态
curl http://192.168.1.101:8081/overview
我的经验:如果 Kafka 消费端收不到消息,先检查 advertised.listeners 是否配置正确。很多人在云服务器上部署,内网 IP 和公网 IP 混用,导致客户端连不上。

嗯,到这里环境就全部就绪了。你可能会问:「为什么不用 Docker Compose 一键部署?」我的回答是:手动搭一遍,你才能理解每个组件的配置含义。后面遇到问题,你才知道去哪里排查。