Kafka 3.9.1 三节点集群部署方案(ZooKeeper 模式)
目录
- 文档说明
- 部署规划
- 2.1 节点与角色规划
- 2.2 软件版本规划
- 2.3 目录与端口规划
- 2.4 资源与容量规划
- 2.5 安装连接
- 环境准备
- 3.1 创建运行用户与目录
- 3.2 防火墙与 SELinux
- 安装 JDK
- ZooKeeper 集群部署
- 5.1 解压安装包
- 5.2 配置 zoo.cfg
- 5.3 配置 myid
- 5.4 启动集群
- 5.5 客户端读写验证
- 5.6 Systemd 管理
- 5.7 客户端读写验证
- Kafka 集群部署
- 6.1 解压安装包
- 6.2 配置文件
- 6.3 客户端凭据文件
- 6.4 启动测试
- 6.5 Systemd 管理
- 集群功能验证
- 7.1 创建测试 Topic
- 7.2 生产消费连通性
1 文档说明
本文采用 ZooKeeper 模式部署 Kafka 三节点集群:集群元数据(Topic、分区、副本分配、ACL、controller 归属)存放在独立 ZooKeeper 集群的 znode 下。
| 组件 | 部署位置 | 作用 |
|---|---|---|
| JDK 17 | 三台均装 | ZooKeeper 与 Kafka 的共同运行环境 |
| ZooKeeper 3.9.3 | 三台均装 | 元数据存储与 controller 选举协调 |
| Kafka Broker | 三台均装 | 消息收发、副本同步、分区管理 |
2 部署规划
2.1 节点与角色规划
| 节点 | IP 地址 | broker.id | ZooKeeper myid |
|---|---|---|---|
| 节点一 | 10.0.0.101 | 0 | 1 |
| 节点二 | 10.0.0.102 | 1 | 2 |
| 节点三 | 10.0.0.103 | 2 | 3 |
节点标识对应 ZooKeeper 模式的 broker.id,取值为 0/1/2;ZooKeeper 的 myid 取值 1/2/3,两者相互独立,不可混用。
2.2 软件版本规划
| 软件 | 版本 | 说明 |
|---|---|---|
| JDK | OpenJDK 17 | 3.9.1 亦可在 8/11 运行,但两者均已弃用,新建集群直接用 17 |
| Kafka | 3.9.1 (Scala 2.13) | 安装包 kafka_2.13-3.9.1.tgz |
| ZooKeeper | 3.9.3 | 安装包 apache-zookeeper-3.9.3-bin.tar.gz |
2.3 目录与端口规划
| 项目 | 路径/端口 | 说明 |
|---|---|---|
| Kafka 安装目录 | /opt/kafka/kafka_2.13-3.9.1 |
解压后的真实目录,三台一致 |
| Kafka 数据目录 | /opt/kafka/data |
存放分区日志,建议独立数据盘 |
| ZooKeeper 安装目录 | /opt/zookeeper/apache-zookeeper-3.9.3-bin |
官方 bin 包解压目录 |
| ZooKeeper 数据目录 | /opt/zookeeper/data |
快照与 myid |
| ZooKeeper 事务日志 | /opt/zookeeper/datalog |
建议与数据目录分盘 |
| Kafka Broker 端口 | 9092 | 客户端接入(SASL_PLAINTEXT) |
| ZK 客户端端口 | 2181 | Broker 与运维工具连接 |
| ZK 集群端口 | 2888/3888 | 数据同步与 leader 选举 |
2.4 资源与容量规划
| 资源项 | 建议配置 | 说明 |
|---|---|---|
| CPU | 8 核及以上 | num.io.threads 取核数的 1/2,上限 8 |
| 内存 | 16 GB 及以上 | 堆 4 GB + 直接内存 2 GB + 页缓存余量 |
| 数据盘 | SSD,单节点 ≥ 500 GB | 按下方公式估算后再定 |
磁盘容量按以下公式估算,交付前必须完成这一步,否则上线后大概率因磁盘写满导致节点退出 ISR:
单节点数据量 = 日均写入量 × 副本数 ÷ Broker数 × 保留天数 × 余系数
= W × R ÷ N × D × 1.3
示例:日写入 200GB,副本数 3,节点数 3,保留 7 天
单节点 = 200 × 3 ÷ 3 × 7 × 1.3 ≈ 1820 GB
结论:单盘 500GB 不满足,需 ≥ 2 TB 或把保留天数降到 1.5 天。
2.5 安装连接
- JDK:
https://download.oracle.com/otn/java/jdk/17.0.17+8/afc1ee993f444e1e811718bc63156b9f/jdk-17.0.17_linux-x64_bin.tar.gz - ZooKeeper:
https://archive.apache.org/dist/zookeeper/zookeeper-3.9.3/apache-zookeeper-3.9.3-bin.tar.gz - Kafka:
https://archive.apache.org/dist/kafka/3.9.1/kafka_2.13-3.9.1.tgz
3 环境准备
3.1 创建运行用户与目录
bash
useradd -r -m -s /sbin/nologin kafka
useradd -r -m -s /sbin/nologin zookeeper
mkdir -p /opt/kafka
mkdir -p /opt/kafka/data
mkdir -p /opt/zookeeper
mkdir -p /opt/zookeeper/data
mkdir -p /opt/zookeeper/datalog
chown -R kafka:kafka /opt/kafka
chown -R zookeeper:zookeeper /opt/zookeeper
ls -ld /opt/kafka /opt/kafka/data /opt/zookeeper
3.2 防火墙与 SELinux
需要端口放通与关闭防火墙中选择,根据实际环境进行调整。
bash
# 端口放通
firewall-cmd --permanent --add-port=9092/tcp
firewall-cmd --permanent --add-port=2181/tcp
firewall-cmd --permanent --add-port=2888/tcp
firewall-cmd --permanent --add-port=3888/tcp
firewall-cmd --reload
firewall-cmd --list-ports
# 关闭防火墙
systemctl disable --now firewalld
setenforce 0
sed -i 's/^SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config
getenforce
4 安装 JDK
三台执行。以下为压缩包方式:
bash
mkdir -p /usr/local/jdk17
tar xf /tmp/jdk-17.0.17_linux-x64_bin.tar.gz -C /usr/local/jdk17/
写入环境变量,三台内容一致:
bash
cat > /etc/profile.d/jdk17.sh << 'EOF'
export JAVA_HOME=/usr/local/jdk17/jdk-17.0.17
export PATH=$JAVA_HOME/bin:$PATH
EOF
chmod 644 /etc/profile.d/jdk17.sh
source /etc/profile.d/jdk17.sh
java -version
5 ZooKeeper 集群部署
本章全部步骤在三台执行,命令相同但 myid 与 server.N 对应的取值不同。ZooKeeper 必须在 Kafka 之前完成部署并确认多数派可用,否则 Kafka 启动后会反复重连。
5.1 解压安装包
bash
tar xf /tmp/apache-zookeeper-3.9.3-bin.tar.gz -C /opt/zookeeper/
chown -R zookeeper:zookeeper /opt/zookeeper/apache-zookeeper-3.9.3-bin
5.2 配置 zoo.cfg
bash
cd /opt/zookeeper/apache-zookeeper-3.9.3-bin/conf/
cp zoo_sample.cfg zoo.cfg
cat > zoo.cfg << 'EOF'
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/opt/zookeeper/data
dataLogDir=/opt/zookeeper/datalog
clientPort=2181
admin.enableServer=false
server.1=10.0.0.101:2888:3888
server.2=10.0.0.102:2888:3888
server.3=10.0.0.103:2888:3888
autopurge.snapRetainCount=3
autopurge.purgeInterval=24
4lw.commands.whitelist=srvr,ruok,stat,mntr
maxClientCnxns=600
EOF
chown zookeeper:zookeeper zoo.cfg
cat zoo.cfg
5.3 配置 myid
myid 文件内容必须与 zoo.cfg 中 server.N 的 N 对应。三台分别执行对应命令:
bash
# 节点一
echo 1 > /opt/zookeeper/data/myid
# 节点二
echo 2 > /opt/zookeeper/data/myid
# 节点三
echo 3 > /opt/zookeeper/data/myid
chown -R zookeeper:zookeeper /opt/zookeeper/data
cat /opt/zookeeper/data/myid
5.4 启动集群
bash
/opt/zookeeper/apache-zookeeper-3.9.3-bin/bin/zkServer.sh start
/opt/zookeeper/apache-zookeeper-3.9.3-bin/bin/zkServer.sh status
ss -lntp | grep -E '2181|2888|3888'
5.5 客户端读写验证
bash
/opt/zookeeper/apache-zookeeper-3.9.3-bin/bin/zkCli.sh -server 10.0.0.103:2181 create /zk-test check
/opt/zookeeper/apache-zookeeper-3.9.3-bin/bin/zkCli.sh -server 10.0.0.102:2181 ls /
/opt/zookeeper/apache-zookeeper-3.9.3-bin/bin/zkCli.sh -server 10.0.0.101:2181 delete /zk-test
/opt/zookeeper/apache-zookeeper-3.9.3-bin/bin/zkCli.sh -server 10.0.0.102:2181 ls /
5.6 Systemd 管理
bash
/opt/zookeeper/apache-zookeeper-3.9.3-bin/bin/zkServer.sh stop
chown -R zookeeper:zookeeper /opt/zookeeper
cat > /etc/systemd/system/zookeeper.service << 'EOF'
[Unit]
Description=Apache ZooKeeper 3.9.3
After=network.target
[Service]
Type=simple
User=zookeeper
Group=zookeeper
Environment="JAVA_HOME=/usr/local/jdk17/jdk-17.0.17"
Environment="ZOO_LOG_DIR=/opt/zookeeper/apache-zookeeper-3.9.3-bin/logs"
Environment="SERVER_JVMFLAGS=-Xms2g -Xmx2g -XX:+UseG1GC"
ExecStart=/opt/zookeeper/apache-zookeeper-3.9.3-bin/bin/zkServer.sh start-foreground
Restart=on-failure
RestartSec=10
LimitNOFILE=100000
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl start zookeeper
systemctl status zookeeper --no-pager
/opt/zookeeper/apache-zookeeper-3.9.3-bin/bin/zkServer.sh status
5.7 客户端读写验证
bash
/opt/zookeeper/apache-zookeeper-3.9.3-bin/bin/zkCli.sh -server 10.0.0.103:2181 create /zk-test check2
/opt/zookeeper/apache-zookeeper-3.9.3-bin/bin/zkCli.sh -server 10.0.0.102:2181 ls /
/opt/zookeeper/apache-zookeeper-3.9.3-bin/bin/zkCli.sh -server 10.0.0.101:2181 delete /zk-test
/opt/zookeeper/apache-zookeeper-3.9.3-bin/bin/zkCli.sh -server 10.0.0.102:2181 ls /
6 Kafka 集群部署
6.1 解压安装包
bash
tar xf /tmp/kafka_2.13-3.9.1.tgz -C /opt/kafka
6.2 配置文件
三台内容一致,仅 broker.id 与 advertised.listeners 不同,根据节点规划修改对应配置:
bash
cp /opt/kafka/kafka_2.13-3.9.1/config/server.properties /opt/kafka/kafka_2.13-3.9.1/config/server.properties-back
cat > /opt/kafka/kafka_2.13-3.9.1/config/server.properties << 'EOF'
broker.id=0
listeners=SASL_PLAINTEXT://:9092
advertised.listeners=SASL_PLAINTEXT://10.0.0.101:9092
listener.security.protocol.map=SASL_PLAINTEXT:SASL_PLAINTEXT
inter.broker.listener.name=SASL_PLAINTEXT
num.network.threads=3
num.io.threads=8
socket.send.buffer.bytes=102400
socket.receive.buffer.bytes=102400
socket.request.max.bytes=104857600
log.dirs=/opt/kafka/data
num.partitions=3
log.retention.hours=168
log.segment.bytes=1073741824
log.retention.check.interval.ms=300000
zookeeper.connect=10.0.0.101:2181,10.0.0.102:2181,10.0.0.103:2181
zookeeper.connection.timeout.ms=60000
zookeeper.session.timeout.ms=18000
zookeeper.max.in.flight.requests=10
default.replication.factor=3
offsets.topic.replication.factor=3
offsets.topic.num.partitions=50
# topic 是否允许删除,根据实际情况开启。
#delete.topic.enable=true
# 副本最小同步数量,根据实际情况开启或调整。
#min.insync.replicas=2
sasl.enabled.mechanisms=PLAIN
sasl.mechanism.inter.broker.protocol=PLAIN
listener.name.sasl_plaintext.plain.sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required \
username="admin" password="$KAFKA_ADMIN_PASSWORD" \
user_admin="$KAFKA_ADMIN_PASSWORD" \
user_app1="$KAFKA_APP1_PASSWORD" \
user_monitor="$KAFKA_MONITOR_PASSWORD";
super.users=User:admin
EOF
chown -R kafka:kafka /opt/kafka/
说明:
$KAFKA_ADMIN_PASSWORD、$KAFKA_APP1_PASSWORD、$KAFKA_MONITOR_PASSWORD为占位符,部署前替换为实际密码。
6.3 客户端凭据文件
bash
cat > /opt/kafka/client-admin.properties << 'EOF'
security.protocol=SASL_PLAINTEXT
sasl.mechanism=PLAIN
sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required \
username="admin" password="$KAFKA_ADMIN_PASSWORD";
EOF
chmod 600 /opt/kafka/client-admin.properties
6.4 启动测试
bash
# 三节点前台运行 kafka,观察是否存在异常。
/opt/kafka/kafka_2.13-3.9.1/bin/kafka-server-start.sh /opt/kafka/kafka_2.13-3.9.1/config/server.properties
/opt/kafka/kafka_2.13-3.9.1/bin/kafka-topics.sh --bootstrap-server 10.0.0.101:9092 \
--create --topic test --command-config /opt/kafka/client-admin.properties
/opt/kafka/kafka_2.13-3.9.1/bin/kafka-topics.sh --bootstrap-server 10.0.0.102:9092 \
--describe --command-config /opt/kafka/client-admin.properties
6.5 Systemd 管理
bash
# Ctrl+C 停止前台 kafka 进程。
chown -R kafka:kafka /opt/kafka
cat > /etc/systemd/system/kafka.service << 'EOF'
[Unit]
Description=Apache Kafka 3.9.1
After=network.target
[Service]
Type=simple
User=kafka
Group=kafka
Environment="JAVA_HOME=/usr/local/jdk17/jdk-17.0.17"
Environment="KAFKA_HEAP_OPTS=-Xms4g -Xmx4g"
Environment="KAFKA_OPTS=-XX:MaxDirectMemorySize=2g -Djdk.nio.maxCachedBufferSize=1048576"
ExecStart=/opt/kafka/kafka_2.13-3.9.1/bin/kafka-server-start.sh /opt/kafka/kafka_2.13-3.9.1/config/server.properties
KillSignal=SIGTERM
TimeoutStopSec=180
Restart=on-failure
RestartSec=10
LimitNOFILE=100000
SuccessExitStatus=143
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl start kafka
systemctl status kafka --no-pager
7 集群功能验证
7.1 创建测试 Topic
bash
/opt/kafka/kafka_2.13-3.9.1/bin/kafka-topics.sh --bootstrap-server 10.0.0.101:9092 \
--command-config /opt/kafka/client-admin.properties \
--create --topic cluster-check --partitions 3 --replication-factor 3
/opt/kafka/kafka_2.13-3.9.1/bin/kafka-topics.sh --bootstrap-server 10.0.0.101:9092 \
--command-config /opt/kafka/client-admin.properties \
--describe --topic cluster-check
7.2 生产消费连通性
bash
seq 1 10 | /opt/kafka/kafka_2.13-3.9.1/bin/kafka-console-producer.sh \
--bootstrap-server 10.0.0.101:9092 \
--producer.config /opt/kafka/client-admin.properties \
--topic cluster-check
/opt/kafka/kafka_2.13-3.9.1/bin/kafka-console-consumer.sh \
--bootstrap-server 10.0.0.101:9092 \
--consumer.config /opt/kafka/client-admin.properties \
--topic cluster-check \
--from-beginning --timeout-ms 10000