目录
- 查看环境,寻找安装包
- 安装和部署
- 一、提前确认
- 二、解压并更名
- [三、建数据 / 日志目录](#三、建数据 / 日志目录)
- [四、Zookeeper 单节点配置](#四、Zookeeper 单节点配置)
- [五、准备 3 份 broker 配置](#五、准备 3 份 broker 配置)
- 六、创建并启动脚本(一次性复制即可用)
- [① 一键生成启动脚本(包含全部内容)](#① 一键生成启动脚本(包含全部内容))
- [② 赋可执行权限](#② 赋可执行权限)
- [③ 运行脚本](#③ 运行脚本)
- [④ 验证是否都起来了](#④ 验证是否都起来了)
*- [有偏差:你只看到 1 个
Kafka
进程,说明 3 个 broker 并没有全部成功启动(后面有我的解决和修改过程可以直接跳过,你也可以在这里逐步排查,可能问题不一样)](#有偏差:你只看到 1 个 Kafka 进程,说明 3 个 broker 并没有全部成功启动(后面有我的解决和修改过程可以直接跳过,你也可以在这里逐步排查,可能问题不一样))
- [有偏差:你只看到 1 个
- 下面是我的解决过程梳理和总结
- 1、完整报错链路(按时间线)
- 2、修复步骤(复制即用)
- [3、后续不再踩坑的 3 条建议](#3、后续不再踩坑的 3 条建议)
- [七、 一键关闭(可选备用脚本)](#七、 一键关闭(可选备用脚本))
- 八、开机自启(可选)
- 快速修复:
*- [① 第一次现象:只有 1 个 Kafka](#① 第一次现象:只有 1 个 Kafka)
- [② 立即查看 3 份日志尾](#② 立即查看 3 份日志尾)
- [③ 前台启动 2 号 broker,现场报错](#③ 前台启动 2 号 broker,现场报错)
- [④ 确认 9092 被谁占用](#④ 确认 9092 被谁占用)
- [⑤杀掉旧进程 & 清理锁文件](#⑤杀掉旧进程 & 清理锁文件)
- [⑥ 把 3 份配置端口改成不冲突的 9191/9192/9193](#⑥ 把 3 份配置端口改成不冲突的 9191/9192/9193)
- [⑦ 写死 JAVA_HOME 到所有 systemd 单元](#⑦ 写死 JAVA_HOME 到所有 systemd 单元)
- [⑧ 一键创建 4 个独立 systemd 单元(复制即用)](#⑧ 一键创建 4 个独立 systemd 单元(复制即用))
- [8.1 Zookeeper](#8.1 Zookeeper)
- [8.2 3 个 Kafka broker](#8.2 3 个 Kafka broker)
- [⑨ 重载 & 自启](#⑨ 重载 & 自启)
- [⑩ 最终验证](#⑩ 最终验证)
- 最后这里成功!!!
- [⑪ 重启整机测试(可选)](#⑪ 重启整机测试(可选))
查看环境,寻找安装包
官网寻找安装包
-
打开官方"存档"页面
3.3 系列已从首页的 Supported 区域下架,进入了 Archived releases 。
直接访问:https://kafka.apache.org/downloads
在页面最下方 "Archived releases" 区域即可看到
3.3.2 3.3.1 3.3.0
任选其一即可下载,例如:
kafka_2.13-3.3.2.tgz (asc, sha512)
-
校验文件(官方唯一验证方法)
① 下载同名的
.sha512
文件bashwget https://archive.apache.org/dist/kafka/3.3.2/kafka_2.13-3.3.2.tgz.sha512
② Linux/Mac 终端执行
bashsha512sum -c kafka_2.13-3.3.2.tgz.sha512
输出
OK
即通过验证。
附:官方 3.3 文档固定入口
https://kafka.apache.org/33/documentation.html
版本选择,要求高可用
一句话结论
只用 3.3.2(Scala 2.13 版) ,不要再纠结 3.3.0/3.3.1;单机 CentOS 7 也能跑"伪分布式三副本",只是三副本≠高可用------一台虚拟机挂了所有副本一起挂。下面给你完整可落地的"单机 3.3.2 三副本"步骤,先跑通,再考虑以后多机扩展。
一、3.3.2 为什么更合适
- 3.3.2 是 3.3 线的最后一个补丁版,修掉 20 个 bug(含潜在数据丢失/稳定性问题)。
- Scala 2.13 比 2.12 体积小一点点,官方也写 "建议使用 2.13"。
- 以后真要扩容到多机,同一版本直接复制配置即可,避免混版本。
二、CentOS 7 单机跑"伪分布式 3 副本"思路
- 用同一台机器开 3 个 Kafka 进程 ,每个进程一个
broker.id
和独立端口/目录,Zookeeper 仍用同一实例。 - 只能验证功能/调试用,真正高可用必须 ≥3 台物理机。
三、10 分钟落地步骤
-
前置依赖
bashsudo yum install -y java-11-openjdk-devel wget java -version # 确认 11+
-
目录规划
bashsudo mkdir -p /opt/kafka-cluster cd /opt/kafka-cluster
-
下载并解压 3.3.2
bashwget https://archive.apache.org/dist/kafka/3.3.2/kafka_2.13-3.3.2.tgz tar -xzf kafka_2.13-3.3.2.tgz mv kafka_2.13-3.3.2 kafka # 建 3 份配置 cp -r kafka kafka-1 kafka-2 kafka-3
-
起 Zookeeper(单节点)
bash# 用自带脚本即可 nohup kafka/bin/zookeeper-server-start.sh kafka/config/zookeeper.properties > zk.log 2>&1 &
-
为 3 个 broker 准备配置文件
把下面三段分别写进
kafka-1/config/server.properties
、kafka-2/config/server.properties
、kafka-3/config/server.properties
,只改差异项:配置项 broker 1 broker 2 broker 3 broker.id 1 2 3 listeners PLAINTEXT://:9092 PLAINTEXT://:9093 PLAINTEXT://:9094 log.dirs /tmp/kafka-logs-1 /tmp/kafka-logs-2 /tmp/kafka-logs-3 zookeeper.connect localhost:2181 localhost:2181 localhost:2181 其余保持默认即可。
-
启动 3 个 broker
bashnohup kafka-1/bin/kafka-server-start.sh kafka-1/config/server.properties > k1.log 2>&1 & nohup kafka-2/bin/kafka-server-start.sh kafka-2/config/server.properties > k2.log 2>&1 & nohup kafka-3/bin/kafka-server-start.sh kafka-3/config/server.properties > k3.log 2>&1 &
-
验证 3 副本 topic
bash# 建 topic,3 副本 3 分区 kafka/bin/kafka-topics.sh --create --topic test-ha \ --bootstrap-server localhost:9092 \ --partitions 3 --replication-factor 3 # 查看分区分布 kafka/bin/kafka-topics.sh --describe --topic test-ha --bootstrap-server localhost:9092
应当看到每个分区都有
Leader
,Replicas: 1,2,3
,Isr: 1,2,3
。 -
简单生产/消费测试
bash# 生产 kafka/bin/kafka-console-producer.sh --topic test-ha --bootstrap-server localhost:9092 # 消费 kafka/bin/kafka-console-consumer.sh --topic test-ha --bootstrap-server localhost:9092 --from-beginning
四、单机"三副本"的局限
- 高可用:❌ 一台机器挂了,三个进程一起死。
- 功能验证:✅ 可以跑通多副本、Leader 切换、ISR 列表变化。
- 后续扩容:把配置里的
listeners
改成各自主机名/IP,log.dirs
换成独立磁盘即可。
一句话总结
下载 kafka_2.13-3.3.2.tgz,单机起 3 个 broker 就能跑 3 副本测试;真正高可用还需再加两台机器。
注:/usr/local
是给"本地手工编译 "或"包管理器之外的系统级软件 "留的;Kafka 官方只提供二进制压缩包,解压即用,既不属于系统自带,也不走 make install
,所以社区习惯放到 /opt
(专门放大型第三方独立软件),避免日后系统升级或包管理器误碰。
安装和部署
下面给你一份面向 CentOS 7、虚拟机单机 的"一行不落"复制粘贴教程。
目标目录:/opt/kafka3.3.2
源包路径:/root/kafka_2.13-3.3.2.tgz
一、提前确认
bash
java -version # 需 11 以上
#输出
[root@localhost redis6.2.14]# java -version
java version "17.0.15" 2025-04-15 LTS
Java(TM) SE Runtime Environment (build 17.0.15+9-LTS-241)
Java HotSpot(TM) 64-Bit Server VM (build 17.0.15+9-LTS-241, mixed mode, sharing)
[root@localhost redis6.2.14]#
二、解压并更名
bash
sudo mkdir -p /opt/kafka3.3.2
sudo tar -xzf /root/kafka_2.13-3.3.2.tgz -C /opt/kafka3.3.2 --strip-components=1
解压后目录结构应为:
/opt/kafka3.3.2/bin
/opt/kafka3.3.2/config
...
三、建数据 / 日志目录
bash
sudo mkdir -p /opt/kafka3.3.2/data/zookeeper
sudo mkdir -p /opt/kafka3.3.2/data/kafka-logs-1 \
/opt/kafka3.3.2/data/kafka-logs-2 \
/opt/kafka3.3.2/data/kafka-logs-3
sudo chown -R $USER:$USER /opt/kafka3.3.2
四、Zookeeper 单节点配置
bash
cp /opt/kafka3.3.2/config/zookeeper.properties /opt/kafka3.3.2/config/zookeeper.properties.bak
编辑 /opt/kafka3.3.2/config/zookeeper.properties
只改两项(其余默认):
dataDir=/opt/kafka3.3.2/data/zookeeper
clientPort=2181
五、准备 3 份 broker 配置
bash
for i in 1 2 3; do
cp /opt/kafka3.3.2/config/server.properties /opt/kafka3.3.2/config/server-$i.properties
done
分别编辑 3 个文件,只改以下 4 行(操作在之后代码块):
文件 | broker.id | listeners | log.dirs | advertised.listeners |
---|---|---|---|---|
server-1.properties | 1 | PLAINTEXT://:9092 | /opt/kafka3.3.2/data/kafka-logs-1 | PLAINTEXT://localhost:9092 |
server-2.properties | 2 | PLAINTEXT://:9093 | /opt/kafka3.3.2/data/kafka-logs-2 | PLAINTEXT://localhost:9093 |
server-3.properties | 3 | PLAINTEXT://:9094 | /opt/kafka3.3.2/data/kafka-logs-3 | PLAINTEXT://localhost:9094 |
其余保持默认(尤其 zookeeper.connect=localhost:2181
)。
不需要手动打开图形编辑器。
用一条 sed 或 echo 命令就能一次改好,下面给出复制即用的三行脚本,把 4 个关键配置一次性写入对应文件:
下面给出一次可直接复制/粘贴的 修正版脚本,并逐条指出与旧脚本的区别。
可直接执行的脚本(已修复换行/引号问题)
bash
# 1 号 broker
sed -ri \
-e 's/^broker.id=.*/broker.id=1/' \
-e 's|^listeners[[:space:]]*=.*|listeners=PLAINTEXT://:9092|' \
-e 's|^log.dirs[[:space:]]*=.*|log.dirs=/opt/kafka3.3.2/data/kafka-logs-1|' \
-e 's|^#?advertised.listeners[[:space:]]*=.*|advertised.listeners=PLAINTEXT://localhost:9092|' \
/opt/kafka3.3.2/config/server-1.properties
# 2 号 broker
sed -ri \
-e 's/^broker.id=.*/broker.id=2/' \
-e 's|^listeners[[:space:]]*=.*|listeners=PLAINTEXT://:9093|' \
-e 's|^log.dirs[[:space:]]*=.*|log.dirs=/opt/kafka3.3.2/data/kafka-logs-2|' \
-e 's|^#?advertised.listeners[[:space:]]*=.*|advertised.listeners=PLAINTEXT://localhost:9093|' \
/opt/kafka3.3.2/config/server-2.properties
# 3 号 broker
sed -ri \
-e 's/^broker.id=.*/broker.id=3/' \
-e 's|^listeners[[:space:]]*=.*|listeners=PLAINTEXT://:9094|' \
-e 's|^log.dirs[[:space:]]*=.*|log.dirs=/opt/kafka3.3.2/data/kafka-logs-3|' \
-e 's|^#?advertised.listeners[[:space:]]*=.*|advertised.listeners=PLAINTEXT://localhost:9094|' \
/opt/kafka3.3.2/config/server-3.properties
与旧脚本的区别逐条说明(注意之前的报错,因为出现转义字符的问题,上面代码已经修改过。)
序号 | 旧问题 | 修正做法 | 说明 |
---|---|---|---|
1 | 单引号里跨行反斜杠续行 | 直接拆成 多段 -e 表达式 |
避免 sed 报 "未终止的正则" |
2 | 分隔符 / 与路径 /opt/... 冲突 |
统一用 ` | ` 作分隔符 |
3 | 正则 ^listeners=.* 可能匹配不到空格 |
写成 ^listeners[[:space:]]*= |
兼容 key=value 或 key = value |
4 | 只处理 #advertised.listeners 的注释行 |
改成 #? |
同时匹配已取消注释或仍注释的行 |
5 | 无 -r 扩展正则 |
加 -r (GNU sed) |
让 ? 、` |
把上面脚本一次性粘进终端即可,无需再手工编辑。
执行完后,三份配置就全部改好,无需再打开任何编辑器。
六、创建并启动脚本(一次性复制即可用)
下面给你一条命令一条命令的「复制-粘贴」版完整步骤,连脚本内容都帮你一次性生成,不用手写,跟着敲即可。
① 一键生成启动脚本(包含全部内容)
bash
cat > ~/start-kafka.sh <<'EOF' #这一步直接是创建脚本,就是把下面的代码保存成脚本'~/start-kafka.sh'
#!/bin/bash
# 启动 Zookeeper
nohup /opt/kafka3.3.2/bin/zookeeper-server-start.sh \
-daemon /opt/kafka3.3.2/config/zookeeper.properties \
> /opt/kafka3.3.2/zk.log 2>&1 &
sleep 5 # 等 Zookeeper 完全起来
# 启动 3 个 broker
for i in 1 2 3; do
nohup /opt/kafka3.3.2/bin/kafka-server-start.sh \
-daemon /opt/kafka3.3.2/config/server-$i.properties \
> /opt/kafka3.3.2/broker-$i.log 2>&1 &
done
echo "Zookeeper + 3 brokers started. Logs under /opt/kafka3.3.2/"
EOF
② 赋可执行权限
bash
chmod +x ~/start-kafka.sh
③ 运行脚本
bash
~/start-kafka.sh
#运行结果
Zookeeper + 3 brokers started. Logs under /opt/kafka3.3.2/#
④ 验证是否都起来了
bash
jps | egrep 'QuorumPeerMain|Kafka'
应看到 1 个 QuorumPeerMain
(Zookeeper)+ 3 个 Kafka
进程。
bash
#运行结果(有偏差)
27940 Kafka
26891 QuorumPeerMain
有偏差:你只看到 1 个 Kafka
进程,说明 3 个 broker 并没有全部成功启动(后面有我的解决和修改过程可以直接跳过,你也可以在这里逐步排查,可能问题不一样)
你只看到 1 个 Kafka
进程,说明 3 个 broker 并没有全部成功启动。
按下面 3 步排查并一次性修复:
- 立即查日志定位原因 ,然后这里我的是空目录
bash
# 看看每个 broker 日志末尾 20 行
tail -n 20 /opt/kafka3.3.2/broker-*.log
常见报错:端口被占用、目录权限不足、log.dirs
不存在、JMX 端口冲突等。
- 一键补齐缺失目录 & 权限
bash
mkdir -p /opt/kafka3.3.2/data/{kafka-logs-1,kafka-logs-2,kafka-logs-3}
chown -R $(whoami):$(whoami) /opt/kafka3.3.2
- 先停后启(干净重启)
bash
# 如果还有残存进程
pkill -f 'kafka\.Kafka' # 杀 Kafka
pkill -f QuorumPeerMain # 杀 Zookeeper
# 重新启动
~/start-kafka.sh
# 再验证
sleep 5
jps | egrep 'QuorumPeerMain|Kafka'
正常应看到 1 个 QuorumPeerMain
+ 3 个 Kafka
。
如果日志里出现 "Address already in use"
说明 9092/9093/9094 端口被系统占用,改脚本里的端口即可;
如果日志里出现 "No space left on device" 或 权限 denied,就回到第 2 步继续修正目录/权限。
下面是我的解决过程梳理和总结
【一句话总结错误原因】
"9092 被旧 broker 死死占着,导致 2、3 号 broker 起不来;把旧进程杀掉、把 3 台 broker 端口一次性改成 9191/9192/9193,再清掉 .lock 文件,就彻底 OK。"
1、完整报错链路(按时间线)
时间 | 现象 | 根因 | 日志关键行 |
---|---|---|---|
T0 | jps 只有 1 个 Kafka |
2、3 号没起来 | --- |
T1 | broker-2.log 报错 |
端口 9092 被占用 | Socket server failed to bind to 0.0.0.0:9092: 地址已在使用 |
T2 | ls -l /opt/kafka3.3.2/data 目录缺 |
log.dirs 没提前建 | --- |
T3 | .lock 已存在 |
旧进程没停干净 | Failed to acquire lock on file .lock |
2、修复步骤(复制即用)
- 杀干净所有残留进程
bash
pkill -9 -f 'kafka\.Kafka'
pkill -f QuorumPeerMain
- 一次性建目录 + 删 .lock
bash
mkdir -p /opt/kafka3.3.2/data/{kafka-logs-1,kafka-logs-2,kafka-logs-3}
chown -R $(whoami):$(whoami) /opt/kafka3.3.2/data
for i in 1 2 3; do rm -f /opt/kafka3.3.2/data/kafka-logs-$i/.lock; done
- 把 3 份配置端口全部改成 9191/9192/9193
bash
for i in 1 2 3; do
port=$((9190+i))
cfg="/opt/kafka3.3.2/config/server-$i.properties"
sed -ri \
-e "s#^listeners[[:space:]]*=.*#listeners=PLAINTEXT://:${port}#" \
-e "s#^advertised.listeners[[:space:]]*=.*#advertised.listeners=PLAINTEXT://localhost:${port}#" \
-e "s#^broker.id[[:space:]]*=.*#broker.id=$i#" \
"$cfg"
done
- 启动并验证
bash
~/start-kafka.sh
sleep 5 && jps | egrep 'QuorumPeerMain|Kafka'
实际输出结果,终于成功:
bash
[root@localhost ~]# ~/start-kafka.sh
Zookeeper + 3 brokers started. Logs under /opt/kafka3.3.2/
[root@localhost ~]# sleep 5 && jps | egrep 'QuorumPeerMain|Kafka'
36151 Kafka
36152 Kafka
36186 Kafka
26891 QuorumPeerMain
30317 Kafka
[root@localhost ~]#
[root@localhost ~]# ss -lntup | grep :9092
tcp LISTEN 0 50 [::]:9092 [::]:* users:(("java",pid=30317,fd=125))
[root@localhost ~]# # 会看到 PID 30317
[root@localhost ~]# kill -9 30317
[root@localhost ~]# sleep 2 && jps | egrep 'QuorumPeerMain|Kafka'
26891 QuorumPeerMain
[root@localhost ~]# for p in 9191 9192 9193; do echo "== $p =="; ss -lntup | grep ":$p"; done
== 9191 ==
== 9192 ==
== 9193 ==
- 确认 9092 已释放
bash
ss -lntup | grep :9092 # 应无结果
3、后续不再踩坑的 3 条建议
- 永远先杀干净旧进程再启动新配置。
- 端口批量错开(如 9191/9192/9193),避免手动改漏。
- 日志为空或报错时立即
tail -n 30
,定位关键字只用 10 秒。
七、 一键关闭(可选备用脚本)
如果想一次性关闭,再做一个 ~/stop-kafka.sh
:
bash
cat > ~/stop-kafka.sh <<'EOF'
#!/bin/bash
# 依次关闭 3 个 broker
for i in 1 2 3; do
/opt/kafka3.3.2/bin/kafka-server-stop.sh /opt/kafka3.3.2/config/server-$i.properties
done
# 关闭 Zookeeper
/opt/kafka3.3.2/bin/zookeeper-server-stop.sh /opt/kafka3.3.2/config/zookeeper.properties
echo "All stopped."
EOF
#赋权
chmod +x ~/stop-kafka.sh
全部完成,直接复制即可。
验证
bash
# 建 topic(3 分区 3 副本)
/opt/kafka3.3.2/bin/kafka-topics.sh --create --topic test-ha \
--bootstrap-server localhost:9092 --partitions 3 --replication-factor 3
# 查看
/opt/kafka3.3.2/bin/kafka-topics.sh --describe --topic test-ha --bootstrap-server localhost:9092
看到每个分区 Replicas: 1,2,3
且 Isr: 1,2,3
即成功。
八、开机自启(可选)
下面给出 CentOS 7 systemd 一键方案 ,复制即可用。
完成后执行 systemctl enable --now kafka
就能开机自启 + 立即启动。
① 创建 systemd 服务文件
bash
sudo tee /etc/systemd/system/kafka.service >/dev/null <<'EOF'
[Unit]
Description=Kafka 3.3.2 Cluster (3 brokers)
After=network.target
[Service]
Type=forking
User=root
ExecStart=/root/start-kafka.sh
ExecStop=/root/stop-kafka.sh
RemainAfterExit=yes
TimeoutStartSec=60
TimeoutStopSec=30
[Install]
WantedBy=multi-user.target
EOF
② 创建对应的 stop 脚本(如果还没有)
bash
sudo tee /root/stop-kafka.sh >/dev/null <<'EOF'
#!/bin/bash
# 依次停 3 个 broker
for i in 1 2 3; do
/opt/kafka3.3.2/bin/kafka-server-stop.sh
done
# 停 Zookeeper
/opt/kafka3.3.2/bin/zookeeper-server-stop.sh
EOF
sudo chmod +x /root/stop-kafka.sh
③ 重载并设为开机自启
bash
sudo systemctl daemon-reload
sudo systemctl enable --now kafka
④ 验证
bash
#一般检查到这一步就可以,出现active就成功,不用之后的重启
systemctl status kafka
⑤慎重验证
bash
# 重启后自动拉起,该命令用于重启整个Linux服务器就是整个机器!!慎用!!!
sudo reboot
# 登录后检查,jps用来列出所有java进程和主类名,后面用来确定Zookeeper和Kafka boker是否正常执行
jps | egrep 'QuorumPeerMain|Kafka'
看到 1 个 QuorumPeerMain
+ 3 个 Kafka
即成功。
这里我报错:
-
systemctl status kafka
显示 active (exited) ,说明 systemd 认为start-kafka.sh
已经执行完成并退出 ,但 它不负责守护进程。 -
而
jps
里 看不到任何 Zookeeper/Kafka 进程 → 3 个 broker 并没有真正跑起来。 -
根本原因
start-kafka.sh
里用了nohup ... &
把进程放到后台,systemd 默认Type=forking
需要主进程长期存活,而你的脚本瞬间结束,systemd 就认为服务已经"成功退出"。 -
问题概述:
start-kafka.sh
依旧是 "瞬间结束" 的脚本------它把 Zookeeper 和 3 个 Kafka 丢到后台 就退出了,systemd(Type=simple
)发现主进程退出,于是立即执行ExecStop
,然后整服务标记为 failed。解决思路:让 systemd 直接托管 Zookeeper + 3 个 Kafka,而不是托管一个"启动脚本"。最简做法是把它们拆成 4 个独立 service (1 Zookeeper + 3 Kafka),相互依赖即可。下面给出 "一条龙" 方案,复制即用。
-
之后又所有服务都报 status=127 ------ 典型"找不到可执行文件或脚本"错误。
90% 是 路径写错 或 没给执行权限 。原因是:1.JDK 不在 PATH (systemd 环境变量 ≠ 登录 shell)2.配置里缺 JAVA_HOME。
解决办法为下面的⑦,然后成功
快速修复:
下面是一份**"问题-定位-修复"** 的完整复盘,完全保留你运行过的每一个代码块 ,方便你后续直接复制使用或给团队做文档。
⏩ 从 第一次只看到 1 个 Kafka 开始,直到 真正 4 个进程常驻并成功开机自启。
① 第一次现象:只有 1 个 Kafka
bash
[root@localhost ~]# jps | egrep 'QuorumPeerMain|Kafka'
27940 Kafka
26891 QuorumPeerMain
② 立即查看 3 份日志尾
bash
[root@localhost ~]# tail -n 20 /opt/kafka3.3.2/broker-*.log
==> /opt/kafka3.3.2/broker-1.log <==
==> /opt/kafka3.3.2/broker-2.log <==
==> /opt/kafka3.3.2/broker-3.log <==
日志为空 → 说明根本没成功启动。
③ 前台启动 2 号 broker,现场报错
bash
# 先停干净
pkill -f 'kafka\.Kafka'
pkill -f QuorumPeerMain
# 前台跑 2 号
/opt/kafka3.3.2/bin/kafka-server-start.sh /opt/kafka3.3.2/config/server-2.properties
输出核心报错:
Socket server failed to bind to 0.0.0.0:9092: 地址已在使用.
④ 确认 9092 被谁占用
bash
[root@localhost ~]# ss -lntup|grep 9092
tcp LISTEN 0 50 [::]:9092 [::]:* users:(("java",pid=27940,fd=125))
⑤杀掉旧进程 & 清理锁文件
bash
# 杀掉所有残留
pkill -9 -f 'kafka\.Kafka'
# 清理 .lock
for i in 1 2 3; do
rm -f /opt/kafka3.3.2/data/kafka-logs-$i/.lock
done
⑥ 把 3 份配置端口改成不冲突的 9191/9192/9193
bash
for i in 1 2 3; do
port=$((9190+i))
cfg="/opt/kafka3.3.2/config/server-$i.properties"
sed -ri \
-e "s#^listeners[[:space:]]*=.*#listeners=PLAINTEXT://:${port}#" \
-e "s#^advertised.listeners[[:space:]]*=.*#advertised.listeners=PLAINTEXT://localhost:${port}#" \
-e "s#^broker.id[[:space:]]*=.*#broker.id=$i#" \
"$cfg"
done
⑦ 写死 JAVA_HOME 到所有 systemd 单元
bash
# 查出 JDK 路径
[root@localhost ~]# readlink -f $(which java)
/usr/local/jdk17/bin/java
# 写入环境变量
for f in /etc/systemd/system/{zookeeper,kafka-{1..3}}.service; do
sudo sed -i '/\[Service\]/a Environment=JAVA_HOME=/usr/local/jdk17' "$f"
done
⑧ 一键创建 4 个独立 systemd 单元(复制即用)
8.1 Zookeeper
bash
sudo tee /etc/systemd/system/zookeeper.service >/dev/null <<'EOF'
[Unit]
Description=Zookeeper for Kafka
After=network.target
[Service]
Type=simple
User=root
ExecStart=/opt/kafka3.3.2/bin/zookeeper-server-start.sh /opt/kafka3.3.2/config/zookeeper.properties
ExecStop=/opt/kafka3.3.2/bin/zookeeper-server-stop.sh
Environment=JAVA_HOME=/usr/local/jdk17
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
8.2 3 个 Kafka broker
bash
for i in 1 2 3; do
port=$((9190+i))
sudo tee /etc/systemd/system/kafka-${i}.service >/dev/null <<EOF
[Unit]
Description=Kafka Broker ${i}
After=zookeeper.service
Requires=zookeeper.service
[Service]
Type=simple
User=root
ExecStart=/opt/kafka3.3.2/bin/kafka-server-start.sh /opt/kafka3.3.2/config/server-${i}.properties
ExecStop=/opt/kafka3.3.2/bin/kafka-server-stop.sh
Environment=JAVA_HOME=/usr/local/jdk17
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
done
⑨ 重载 & 自启
bash
sudo systemctl daemon-reload
sudo systemctl enable --now zookeeper
for i in 1 2 3; do
sudo systemctl enable --now kafka-${i}
done
⑩ 最终验证
bash
[root@localhost ~]# systemctl status zookeeper kafka-{1..3}
# 四条均显示 active (running)
[root@localhost ~]# jps | egrep 'QuorumPeerMain|Kafka'
12288 Kafka
12289 Kafka
12286 QuorumPeerMain
12287 Kafka
最后这里成功!!!
bash
[root@localhost ~]# ls -l /opt/kafka3.3.2/bin/zookeeper-server-start.sh
-rwxr-xr-x. 1 root root 1393 12月 22 2022 /opt/kafka3.3.2/bin/zookeeper-server-start.sh
[root@localhost ~]# ls -l /opt/kafka3.3.2/bin/kafka-server-start.sh
-rwxr-xr-x. 1 root root 1376 12月 22 2022 /opt/kafka3.3.2/bin/kafka-server-start.sh
[root@localhost ~]# readlink -f $(which java)
/usr/local/jdk17/bin/java
[root@localhost ~]# for f in /etc/systemd/system/{zookeeper,kafka-{1..3}}.service; do
> sudo sed -i '/\[Service\]/a Environment=JAVA_HOME=/usr/local/jdk17' "$f"
> done
[root@localhost ~]# sudo systemctl daemon-reload
[root@localhost ~]# sudo systemctl restart zookeeper kafka-{1..3}
[root@localhost ~]# systemctl status zookeeper kafka-{1..3}
● zookeeper.service - Zookeeper for Kafka
Loaded: loaded (/etc/systemd/system/zookeeper.service; enabled; vendor preset: disabled)
Active: active (running) since 三 2025-08-13 11:49:54 CST; 5s ago
Main PID: 12286 (java)
CGroup: /system.slice/zookeeper.service
└─12286 /usr/local/jdk17/bin/java -Xmx512M -Xms512M -server -XX:+UseG1GC -XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:+ExplicitGCInvokesConcurrent -XX:MaxInlineLevel=15 -Djav...
8月 13 11:49:58 localhost.localdomain zookeeper-server-start.sh[12286]: [2025-08-13 11:49:58,318] INFO The digest value is empty in snapshot (org.apache.zookeeper.server.DataTree)
8月 13 11:49:58 localhost.localdomain zookeeper-server-start.sh[12286]: [2025-08-13 11:49:58,435] INFO ZooKeeper audit is disabled. (org.apache.zookeeper.audit.ZKAuditProvider)
8月 13 11:49:58 localhost.localdomain zookeeper-server-start.sh[12286]: [2025-08-13 11:49:58,448] INFO 325 txns loaded in 64 ms (org.apache.zookeeper.server.persistence.FileTxnSnapLog)
8月 13 11:49:58 localhost.localdomain zookeeper-server-start.sh[12286]: [2025-08-13 11:49:58,448] INFO Snapshot loaded in 214 ms, highest zxid is 0x145, digest is 44971706807 (org.apache.zookeep...ZKDatabase)
8月 13 11:49:58 localhost.localdomain zookeeper-server-start.sh[12286]: [2025-08-13 11:49:58,448] INFO Snapshotting: 0x145 to /tmp/zookeeper/version-2/snapshot.145 (org.apache.zookeeper.server.p...TxnSnapLog)
8月 13 11:49:58 localhost.localdomain zookeeper-server-start.sh[12286]: [2025-08-13 11:49:58,449] INFO Snapshot taken in 1 ms (org.apache.zookeeper.server.ZooKeeperServer)
8月 13 11:49:58 localhost.localdomain zookeeper-server-start.sh[12286]: [2025-08-13 11:49:58,507] INFO zookeeper.request_throttler.shutdownTimeout = 10000 (org.apache.zookeeper.server.RequestThrottler)
8月 13 11:49:58 localhost.localdomain zookeeper-server-start.sh[12286]: [2025-08-13 11:49:58,510] INFO PrepRequestProcessor (sid:0) started, reconfigEnabled=false (org.apache.zookeeper.server.Pr...tProcessor)
8月 13 11:49:58 localhost.localdomain zookeeper-server-start.sh[12286]: [2025-08-13 11:49:58,636] INFO Using checkIntervalMs=60000 maxPerMinute=10000 maxNeverUsedIntervalMs=0 (org.apache.zookeep...nerManager)
8月 13 11:49:59 localhost.localdomain zookeeper-server-start.sh[12286]: [2025-08-13 11:49:59,471] INFO Creating new log file: log.146 (org.apache.zookeeper.server.persistence.FileTxnLog)
● kafka-1.service - Kafka Broker 1
Loaded: loaded (/etc/systemd/system/kafka-1.service; enabled; vendor preset: disabled)
Active: active (running) since 三 2025-08-13 11:49:54 CST; 5s ago
Main PID: 12287 (java)
CGroup: /system.slice/kafka-1.service
└─12287 /usr/local/jdk17/bin/java -Xmx1G -Xms1G -server -XX:+UseG1GC -XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:+ExplicitGCInvokesConcurrent -XX:MaxInlineLevel=15 -Djava.aw...
8月 13 11:49:59 localhost.localdomain kafka-server-start.sh[12287]: [2025-08-13 11:49:59,407] INFO Client environment:os.memory.max=1024MB (org.apache.zookeeper.ZooKeeper)
8月 13 11:49:59 localhost.localdomain kafka-server-start.sh[12287]: [2025-08-13 11:49:59,407] INFO Client environment:os.memory.total=1024MB (org.apache.zookeeper.ZooKeeper)
8月 13 11:49:59 localhost.localdomain kafka-server-start.sh[12287]: [2025-08-13 11:49:59,410] INFO Initiating client connection, connectString=localhost:2181 sessionTimeout=18000 watcher=kafka.z....ZooKeeper)
8月 13 11:49:59 localhost.localdomain kafka-server-start.sh[12287]: [2025-08-13 11:49:59,419] INFO jute.maxbuffer value is 4194304 Bytes (org.apache.zookeeper.ClientCnxnSocket)
8月 13 11:49:59 localhost.localdomain kafka-server-start.sh[12287]: [2025-08-13 11:49:59,426] INFO zookeeper.request.timeout value is 0. feature enabled=false (org.apache.zookeeper.ClientCnxn)
8月 13 11:49:59 localhost.localdomain kafka-server-start.sh[12287]: [2025-08-13 11:49:59,456] INFO Opening socket connection to server localhost/[0:0:0:0:0:0:0:1]:2181. (org.apache.zookeeper.ClientCnxn)
8月 13 11:49:59 localhost.localdomain kafka-server-start.sh[12287]: [2025-08-13 11:49:59,462] INFO Socket connection established, initiating session, client: /[0:0:0:0:0:0:0:1]:41508, server: lo...ClientCnxn)
8月 13 11:49:59 localhost.localdomain kafka-server-start.sh[12287]: [2025-08-13 11:49:59,467] INFO [ZooKeeperClient Kafka server] Waiting until connected. (kafka.zookeeper.ZooKeeperClient)
8月 13 11:49:59 localhost.localdomain kafka-server-start.sh[12287]: [2025-08-13 11:49:59,560] INFO Session establishment complete on server localhost/[0:0:0:0:0:0:0:1]:2181, session id = 0x10000...ClientCnxn)
8月 13 11:49:59 localhost.localdomain kafka-server-start.sh[12287]: [2025-08-13 11:49:59,566] INFO [ZooKeeperClient Kafka server] Connected. (kafka.zookeeper.ZooKeeperClient)
● kafka-2.service - Kafka Broker 2
Loaded: loaded (/etc/systemd/system/kafka-2.service; enabled; vendor preset: disabled)
Active: active (running) since 三 2025-08-13 11:49:54 CST; 5s ago
Main PID: 12288 (java)
CGroup: /system.slice/kafka-2.service
└─12288 /usr/local/jdk17/bin/java -Xmx1G -Xms1G -server -XX:+UseG1GC -XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:+ExplicitGCInvokesConcurrent -XX:MaxInlineLevel=15 -Djava.aw...
8月 13 11:49:59 localhost.localdomain kafka-server-start.sh[12288]: [2025-08-13 11:49:59,370] INFO Client environment:os.memory.max=1024MB (org.apache.zookeeper.ZooKeeper)
8月 13 11:49:59 localhost.localdomain kafka-server-start.sh[12288]: [2025-08-13 11:49:59,370] INFO Client environment:os.memory.total=1024MB (org.apache.zookeeper.ZooKeeper)
8月 13 11:49:59 localhost.localdomain kafka-server-start.sh[12288]: [2025-08-13 11:49:59,374] INFO Initiating client connection, connectString=localhost:2181 sessionTimeout=18000 watcher=kafka.z....ZooKeeper)
8月 13 11:49:59 localhost.localdomain kafka-server-start.sh[12288]: [2025-08-13 11:49:59,401] INFO jute.maxbuffer value is 4194304 Bytes (org.apache.zookeeper.ClientCnxnSocket)
8月 13 11:49:59 localhost.localdomain kafka-server-start.sh[12288]: [2025-08-13 11:49:59,414] INFO zookeeper.request.timeout value is 0. feature enabled=false (org.apache.zookeeper.ClientCnxn)
8月 13 11:49:59 localhost.localdomain kafka-server-start.sh[12288]: [2025-08-13 11:49:59,430] INFO Opening socket connection to server localhost/[0:0:0:0:0:0:0:1]:2181. (org.apache.zookeeper.ClientCnxn)
8月 13 11:49:59 localhost.localdomain kafka-server-start.sh[12288]: [2025-08-13 11:49:59,436] INFO Socket connection established, initiating session, client: /[0:0:0:0:0:0:0:1]:41506, server: lo...ClientCnxn)
8月 13 11:49:59 localhost.localdomain kafka-server-start.sh[12288]: [2025-08-13 11:49:59,441] INFO [ZooKeeperClient Kafka server] Waiting until connected. (kafka.zookeeper.ZooKeeperClient)
8月 13 11:49:59 localhost.localdomain kafka-server-start.sh[12288]: [2025-08-13 11:49:59,525] INFO Session establishment complete on server localhost/[0:0:0:0:0:0:0:1]:2181, session id = 0x10000...ClientCnxn)
8月 13 11:49:59 localhost.localdomain kafka-server-start.sh[12288]: [2025-08-13 11:49:59,530] INFO [ZooKeeperClient Kafka server] Connected. (kafka.zookeeper.ZooKeeperClient)
● kafka-3.service - Kafka Broker 3
Loaded: loaded (/etc/systemd/system/kafka-3.service; enabled; vendor preset: disabled)
Active: active (running) since 三 2025-08-13 11:49:54 CST; 5s ago
Main PID: 12289 (java)
CGroup: /system.slice/kafka-3.service
└─12289 /usr/local/jdk17/bin/java -Xmx1G -Xms1G -server -XX:+UseG1GC -XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:+ExplicitGCInvokesConcurrent -XX:MaxInlineLevel=15 -Djava.aw...
8月 13 11:49:59 localhost.localdomain kafka-server-start.sh[12289]: [2025-08-13 11:49:59,456] INFO Client environment:os.memory.max=1024MB (org.apache.zookeeper.ZooKeeper)
8月 13 11:49:59 localhost.localdomain kafka-server-start.sh[12289]: [2025-08-13 11:49:59,456] INFO Client environment:os.memory.total=1024MB (org.apache.zookeeper.ZooKeeper)
8月 13 11:49:59 localhost.localdomain kafka-server-start.sh[12289]: [2025-08-13 11:49:59,459] INFO Initiating client connection, connectString=localhost:2181 sessionTimeout=18000 watcher=kafka.z....ZooKeeper)
8月 13 11:49:59 localhost.localdomain kafka-server-start.sh[12289]: [2025-08-13 11:49:59,487] INFO jute.maxbuffer value is 4194304 Bytes (org.apache.zookeeper.ClientCnxnSocket)
8月 13 11:49:59 localhost.localdomain kafka-server-start.sh[12289]: [2025-08-13 11:49:59,494] INFO zookeeper.request.timeout value is 0. feature enabled=false (org.apache.zookeeper.ClientCnxn)
8月 13 11:49:59 localhost.localdomain kafka-server-start.sh[12289]: [2025-08-13 11:49:59,500] INFO [ZooKeeperClient Kafka server] Waiting until connected. (kafka.zookeeper.ZooKeeperClient)
8月 13 11:49:59 localhost.localdomain kafka-server-start.sh[12289]: [2025-08-13 11:49:59,513] INFO Opening socket connection to server localhost/[0:0:0:0:0:0:0:1]:2181. (org.apache.zookeeper.ClientCnxn)
8月 13 11:49:59 localhost.localdomain kafka-server-start.sh[12289]: [2025-08-13 11:49:59,538] INFO Socket connection established, initiating session, client: /[0:0:0:0:0:0:0:1]:41510, server: lo...ClientCnxn)
8月 13 11:49:59 localhost.localdomain kafka-server-start.sh[12289]: [2025-08-13 11:49:59,558] INFO Session establishment complete on server localhost/[0:0:0:0:0:0:0:1]:2181, session id = 0x10000...ClientCnxn)
8月 13 11:49:59 localhost.localdomain kafka-server-start.sh[12289]: [2025-08-13 11:49:59,564] INFO [ZooKeeperClient Kafka server] Connected. (kafka.zookeeper.ZooKeeperClient)
Hint: Some lines were ellipsized, use -l to show in full.
[root@localhost ~]# jps | egrep 'QuorumPeerMain|Kafka'
12288 Kafka
12289 Kafka
12286 QuorumPeerMain
12287 Kafka
⑪ 重启整机测试(可选)
bash
sudo reboot
# 重新登录
jps | egrep 'QuorumPeerMain|Kafka'
再次看到 1 个 QuorumPeerMain
+ 3 个 Kafka
,开机自启完成。
一句话总结
复制上面 1~6 步即可在 /opt/kafka3.3.2
跑起单机 3 broker 3 副本环境,验证完功能后再考虑真正多机高可用。