2. Kafka 安装与配置:单机模式安装、集群模式安装、ZooKeeper 依赖、关键配置文件详解、启动与验证
好,咱们直接动手。这一章我会带你从零搭一套 Kafka 环境。单机、集群都会讲,配置文件也会掰开揉碎说清楚。你跟着走一遍,后面写流处理应用的时候就不会被环境问题卡住。
核心要点:Kafka 强依赖 ZooKeeper 做元数据管理和选主。2.8 版本之后虽然有了 KRaft 模式,但生产环境主流还是 ZooKeeper 模式。本章全部基于 ZooKeeper 模式讲解。
2.1 环境准备与版本选择
我建议你直接用 Kafka 3.5.x 搭配 ZooKeeper 3.8.x。这个组合我去年在三个项目里用过,稳定性没问题。
| 组件 | 推荐版本 | 说明 |
|---|---|---|
| Kafka | 3.5.0 | 内置 ZooKeeper 脚本,兼容性好 |
| ZooKeeper | 3.8.3 | 独立部署,生产环境不要用内置的 |
| JDK | 11 或 17 | Kafka 3.x 强制要求 JDK 11+ |
| 操作系统 | CentOS 7+ / Ubuntu 20.04+ | Linux 优先,Windows 仅用于开发测试 |
注意:不要用 Kafka 自带的 ZooKeeper 跑生产。我曾经见过一个团队图省事直接用内置 ZooKeeper,结果集群重启时 ZooKeeper 日志把磁盘撑爆了——因为内置版本没配自动清理。
2.2 单机模式安装
单机模式说白了就是「先跑起来看看」。适合学习、调试、写 Demo。
2.2.1 下载与解压
# 下载 Kafka(二进制包,不要下载源码)
wget https://downloads.apache.org/kafka/3.5.0/kafka_2.13-3.5.0.tgz
# 解压
tar -xzf kafka_2.13-3.5.0.tgz
cd kafka_2.13-3.5.0
解压后目录结构是这样的:
kafka_2.13-3.5.0/
├── bin/ # 启动脚本
├── config/ # 配置文件
├── libs/ # 依赖 JAR 包
├── logs/ # 运行日志(首次启动后生成)
└── site-docs/ # 文档
2.2.2 启动 ZooKeeper
单机模式我习惯用 Kafka 自带的 ZooKeeper 脚本,省事。
# 启动 ZooKeeper(默认端口 2181)
bin/zookeeper-server-start.sh config/zookeeper.properties
看到 binding to port 0.0.0.0/0.0.0.0:2181 就说明起来了。
2.2.3 启动 Kafka Broker
# 启动 Kafka(默认端口 9092)
bin/kafka-server-start.sh config/server.properties
日志里出现 started (kafka.server.KafkaServer) 就成功了。
小技巧:第一次启动时可以用 bin/kafka-server-start.sh -daemon config/server.properties 后台运行,这样终端不会被占住。
2.3 集群模式安装
生产环境至少 3 个 Broker。为什么是 3?因为 Kafka 的 ISR(In-Sync Replica)机制需要多数派才能正常工作。2 个节点挂 1 个就废了,3 个挂 1 个还能跑。
2.3.1 集群规划
假设我们有 3 台机器:
| 节点 | IP | Broker ID | ZooKeeper 角色 |
|---|---|---|---|
| node1 | 192.168.1.101 | 1 | Leader / Follower |
| node2 | 192.168.1.102 | 2 | Leader / Follower |
| node3 | 192.168.1.103 | 3 | Leader / Follower |
2.3.2 ZooKeeper 集群部署
ZooKeeper 集群需要奇数个节点。3 个是最低配。
每台机器上做同样的操作:
# 1. 下载 ZooKeeper
wget https://downloads.apache.org/zookeeper/zookeeper-3.8.3/apache-zookeeper-3.8.3-bin.tar.gz
tar -xzf apache-zookeeper-3.8.3-bin.tar.gz
cd apache-zookeeper-3.8.3
# 2. 创建数据目录
mkdir -p /data/zookeeper
# 3. 配置 zoo.cfg
cp conf/zoo_sample.cfg conf/zoo.cfg
编辑 conf/zoo.cfg:
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/data/zookeeper
clientPort=2181
# 集群节点列表
server.1=192.168.1.101:2888:3888
server.2=192.168.1.102:2888:3888
server.3=192.168.1.103:2888:3888
然后在每台机器的 /data/zookeeper 目录下创建 myid 文件:
# node1 上执行
echo "1" > /data/zookeeper/myid
# node2 上执行
echo "2" > /data/zookeeper/myid
# node3 上执行
echo "3" > /data/zookeeper/myid
启动 ZooKeeper 集群:
bin/zkServer.sh start
检查状态:
bin/zkServer.sh status
# 会显示 Mode: leader 或 Mode: follower
2.3.3 Kafka Broker 集群配置
每台机器上修改 config/server.properties:
# 每个节点不同
broker.id=1
# 监听地址
listeners=PLAINTEXT://192.168.1.101:9092
# 日志目录
log.dirs=/data/kafka/logs
# ZooKeeper 连接串(所有节点写全)
zookeeper.connect=192.168.1.101:2181,192.168.1.102:2181,192.168.1.103:2181
# 副本因子(生产环境建议 3)
default.replication.factor=3
# ISR 最小副本数
min.insync.replicas=2
启动所有 Broker:
bin/kafka-server-start.sh -daemon config/server.properties
我曾经踩过的坑:broker.id 必须全局唯一。有一次我复制配置文件忘了改,两个 Broker 用同一个 ID,结果第二个启动时直接把第一个踢下线了。排查了半天才发现是 ID 冲突。
2.4 关键配置文件详解
配置文件是 Kafka 的命门。我挑几个最重要的说。
2.4.1 server.properties 核心参数
| 参数 | 默认值 | 说明 |
|---|---|---|
broker.id |
0 | 集群内唯一标识,不能重复 |
listeners |
PLAINTEXT://:9092 | 客户端连接地址,生产环境建议绑定内网 IP |
log.dirs |
/tmp/kafka-logs | 数据存储目录,不要用 /tmp,重启会丢数据 |
num.partitions |
1 | Topic 默认分区数,生产环境建议 3-6 |
log.retention.hours |
168 | 数据保留时间(7 天),按业务调整 |
zookeeper.connect |
localhost:2181 | ZooKeeper 连接串,集群模式写全 |
2.4.2 producer.properties 与 consumer.properties
这两个文件是客户端配置的模板。实际开发中我们会在代码里配,但了解文件里的参数有助于排查问题。
# producer.properties 关键参数
bootstrap.servers=localhost:9092
acks=all # 等待所有副本确认
retries=3 # 重试次数
batch.size=16384 # 批次大小(字节)
linger.ms=1 # 延迟发送时间(毫秒)
# consumer.properties 关键参数
bootstrap.servers=localhost:9092
group.id=test-consumer-group
enable.auto.commit=true
auto.commit.interval.ms=1000
auto.offset.reset=earliest # 从最早的消息开始消费
2.5 启动与验证
环境搭好了,怎么确认它真的能跑?我一般做三步验证。
2.5.1 验证 ZooKeeper
# 连接 ZooKeeper
bin/zkCli.sh -server 192.168.1.101:2181
# 查看 Kafka 相关节点
ls /brokers/ids
# 应该能看到 [1, 2, 3] 三个 Broker ID
2.5.2 创建 Topic 并生产消费
# 创建 Topic(3 分区,3 副本)
bin/kafka-topics.sh --create \
--bootstrap-server 192.168.1.101:9092 \
--replication-factor 3 \
--partitions 3 \
--topic test-topic
# 查看 Topic 详情
bin/kafka-topics.sh --describe \
--bootstrap-server 192.168.1.101:9092 \
--topic test-topic
输出应该类似这样:
Topic: test-topic PartitionCount: 3 ReplicationFactor: 3
Topic: test-topic Partition: 0 Leader: 1 Replicas: [1,2,3] Isr: [1,2,3]
Topic: test-topic Partition: 1 Leader: 2 Replicas: [2,3,1] Isr: [2,3,1]
Topic: test-topic Partition: 2 Leader: 3 Replicas: [3,1,2] Isr: [3,1,2]
看到 Isr 列三个节点都在,说明副本同步正常。
2.5.3 生产与消费消息
# 启动生产者(输入消息后回车发送)
bin/kafka-console-producer.sh \
--bootstrap-server 192.168.1.101:9092 \
--topic test-topic
# 启动消费者(实时接收消息)
bin/kafka-console-consumer.sh \
--bootstrap-server 192.168.1.101:9092 \
--topic test-topic \
--from-beginning
在生产者窗口输入 hello kafka,消费者窗口能收到,就说明整个链路通了。
我的习惯:验证通过后,我会用 bin/kafka-dump-log.sh 看一眼日志文件里的实际数据格式。这能帮你理解 Kafka 底层是怎么存消息的。
2.6 知识体系总览
下面这张图把本章的核心逻辑串起来了。你安装配置的时候可以对照着看,心里有个全局图景。
2.7 常见问题与避坑
- 端口被占用:
lsof -i:9092查一下,Kafka 默认 9092,ZooKeeper 默认 2181。 - 磁盘空间不足:Kafka 日志默认保留 7 天。如果 Topic 数据量大,记得调小
log.retention.hours或配置定时清理。 - 防火墙没关:集群节点之间需要互通 9092、2181、2888、3888 端口。我一般先
systemctl stop firewalld排除网络问题。 - ZooKeeper 选主超时:检查
initLimit和syncLimit。网络抖动大的环境适当调大这两个值。
重要提醒:生产环境不要用 PLAINTEXT 协议。至少配 SSL 加密,或者用 SASL 做认证。我见过不止一次因为裸奔导致数据泄露的事故。
好了,环境搭好、验证通过,接下来就可以真正开始写流处理应用了。记住:环境是地基,地基稳了,上面盖多高的楼都不怕。