3、Kafka集群部署:环境准备、Zookeeper安装、Kafka Broker配置、集群启动与验证
部署Kafka集群,说白了就是搭积木。你得先把地基打牢,再把零件一个个装上去。我这些年帮不少团队搞过Kafka集群,从3台到30台都折腾过。踩过的坑多了,自然就知道哪些地方容易出问题。
这一节,咱们就一步步来。从环境准备开始,到Zookeeper安装,再到Broker配置,最后启动验证。你跟着走一遍,基本就能搭出一个能用的集群。
核心要点:Kafka集群的稳定性,很大程度上取决于Zookeeper集群的可靠性。别小看这一步,很多线上事故都是Zookeeper先崩的。
3.1 环境准备
先说说硬件和系统层面的准备。我个人习惯用CentOS 7.9或Ubuntu 20.04 LTS。JDK必须用1.8以上,推荐OpenJDK 11。
我记得有一次,一个同事用JDK 1.7跑Kafka 2.8,结果Consumer一直报错。查了半天,发现是JDK版本不兼容。从那以后,我每次部署前都会先确认JDK版本。
3.1.1 服务器规划
假设我们要搭一个3节点的集群。节点规划如下:
| 主机名 | IP地址 | 角色 | 配置建议 |
|---|---|---|---|
| kafka-01 | 192.168.1.101 | ZK + Broker | 4C 16G 100G SSD |
| kafka-02 | 192.168.1.102 | ZK + Broker | 4C 16G 100G SSD |
| kafka-03 | 192.168.1.103 | ZK + Broker | 4C 16G 100G SSD |
小提示:生产环境建议ZK和Broker分开部署。小规模集群可以合在一起,但超过5台Broker,ZK最好独立出来。
3.1.2 系统优化
系统层面有几个关键点:
- 关闭防火墙:或者开放9092、2181端口
- 关闭SELinux:这玩意儿经常导致权限问题
- 调整文件描述符:Kafka会打开大量文件,默认1024肯定不够
- 设置内核参数:vm.swappiness、net.core.somaxconn这些
我曾经遇到过一个问题:Kafka集群运行了两个月,突然Broker全部挂掉。排查发现是文件描述符用完了。你想想看,一个高吞吐的Topic,每个Partition对应一个文件,再加上日志段文件,很容易就超了。
所以,我建议你一开始就把这些参数调好:
# /etc/security/limits.conf
* soft nofile 65536
* hard nofile 65536
# /etc/sysctl.conf
vm.swappiness = 1
net.core.somaxconn = 1024
net.ipv4.tcp_max_syn_backlog = 1024
3.2 Zookeeper安装
Zookeeper是Kafka的"大脑"。它负责管理Broker的元数据、选举Controller、维护Topic和Partition信息。说白了,没有ZK,Kafka就转不起来。
3.2.1 下载与解压
我习惯用3.6.3版本,稳定且兼容性好。
wget https://archive.apache.org/dist/zookeeper/zookeeper-3.6.3/apache-zookeeper-3.6.3-bin.tar.gz
tar -zxvf apache-zookeeper-3.6.3-bin.tar.gz -C /opt/
mv /opt/apache-zookeeper-3.6.3-bin /opt/zookeeper
3.2.2 配置文件
Zookeeper的配置主要在zoo.cfg里。嗯,这里要注意,默认没有这个文件,需要从模板复制。
cp /opt/zookeeper/conf/zoo_sample.cfg /opt/zookeeper/conf/zoo.cfg
然后修改配置:
# zoo.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/data/zookeeper
clientPort=2181
maxClientCnxns=60
autopurge.snapRetainCount=3
autopurge.purgeInterval=1
# 集群配置
server.1=192.168.1.101:2888:3888
server.2=192.168.1.102:2888:3888
server.3=192.168.1.103:2888:3888
这里有个关键点:dataDir目录下要创建一个myid文件,内容就是对应的server编号。
# 在kafka-01上
mkdir -p /data/zookeeper
echo "1" > /data/zookeeper/myid
# 在kafka-02上
echo "2" > /data/zookeeper/myid
# 在kafka-03上
echo "3" > /data/zookeeper/myid
警告:myid文件必须与zoo.cfg中的server编号一致。我曾经见过有人把编号写反了,结果ZK集群一直选不出Leader。
3.2.3 启动Zookeeper
三台机器都执行:
/opt/zookeeper/bin/zkServer.sh start
检查状态:
/opt/zookeeper/bin/zkServer.sh status
正常的话,应该能看到一台是Leader,两台是Follower。
3.3 Kafka Broker配置
ZK搞定了,接下来就是Kafka本身。我建议用2.8.1版本,它支持不少新特性,而且稳定性不错。
3.3.1 下载与解压
wget https://archive.apache.org/dist/kafka/2.8.1/kafka_2.12-2.8.1.tgz
tar -zxvf kafka_2.12-2.8.1.tgz -C /opt/
mv /opt/kafka_2.12-2.8.1 /opt/kafka
3.3.2 核心配置
配置文件在/opt/kafka/config/server.properties。这里我挑几个关键参数说说:
| 参数 | 说明 | 推荐值 |
|---|---|---|
| broker.id | 每个Broker的唯一标识 | 0, 1, 2(依次递增) |
| listeners | 监听地址和端口 | PLAINTEXT://0.0.0.0:9092 |
| log.dirs | 数据存储目录 | /data/kafka/logs |
| zookeeper.connect | ZK连接地址 | 192.168.1.101:2181,192.168.1.102:2181,192.168.1.103:2181 |
| num.partitions | 默认分区数 | 3 |
| default.replication.factor | 默认副本数 | 2 |
以kafka-01为例,配置如下:
# server.properties
broker.id=0
listeners=PLAINTEXT://0.0.0.0:9092
advertised.listeners=PLAINTEXT://192.168.1.101:9092
log.dirs=/data/kafka/logs
num.partitions=3
default.replication.factor=2
offsets.topic.replication.factor=2
transaction.state.log.replication.factor=2
transaction.state.log.min.isr=2
zookeeper.connect=192.168.1.101:2181,192.168.1.102:2181,192.168.1.103:2181
auto.create.topics.enable=false
delete.topic.enable=true
小提示:advertised.listeners这个参数容易被忽略。如果Broker有内网和外网IP,一定要显式指定。不然客户端连不上,你查半天都找不到原因。
3.3.3 内存与JVM调优
Kafka的JVM参数在/opt/kafka/bin/kafka-server-start.sh里。我一般这样调:
export KAFKA_HEAP_OPTS="-Xmx8G -Xms8G"
export KAFKA_JVM_PERFORMANCE_OPTS="-server -XX:+UseG1GC -XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:+DisableExplicitGC"
为什么用G1GC?因为Kafka的堆内存里有很多大对象,比如PageCache。G1GC能更好地处理大堆和低延迟场景。我试过CMS,效果不如G1。
3.4 集群启动与验证
配置都搞定了,咱们来启动集群。
3.4.1 启动Broker
三台机器依次执行:
/opt/kafka/bin/kafka-server-start.sh -daemon /opt/kafka/config/server.properties
检查进程:
jps -l | grep Kafka
应该能看到kafka.Kafka进程。
3.4.2 验证集群状态
我一般用这几个命令来验证:
- 查看Broker列表:
/opt/kafka/bin/zookeeper-shell.sh 192.168.1.101:2181 ls /brokers/ids
输出应该是[0, 1, 2],表示三个Broker都注册了。
- 创建测试Topic:
/opt/kafka/bin/kafka-topics.sh --create --topic test-topic --partitions 3 --replication-factor 2 --bootstrap-server 192.168.1.101:9092
- 查看Topic详情:
/opt/kafka/bin/kafka-topics.sh --describe --topic test-topic --bootstrap-server 192.168.1.101:9092
输出应该显示每个Partition的Leader、Replicas和ISR。
- 生产与消费测试:
# 生产者
/opt/kafka/bin/kafka-console-producer.sh --topic test-topic --bootstrap-server 192.168.1.101:9092
# 消费者(另一个终端)
/opt/kafka/bin/kafka-console-consumer.sh --topic test-topic --from-beginning --bootstrap-server 192.168.1.101:9092
在生产者终端输入消息,消费者终端应该能实时收到。
关键验证点:如果消费者能收到消息,说明整个链路通了。但别忘了测试容错——手动停掉一个Broker,看看生产和消费是否正常。我每次部署完都会做这个测试。
3.5 集群部署架构图
下面这张图展示了我们刚搭建的3节点Kafka集群的整体架构。你可以看到ZK集群和Broker集群的关系,以及客户端如何连接。
3.6 常见问题与避坑指南
部署过程中,有几个坑我帮你提前踩了:
- 端口冲突:ZK默认用2181,Kafka用9092。如果机器上还有其他服务,记得改端口。
- 磁盘空间:Kafka的日志文件不会自动删除,除非你配置了
log.retention.hours。我见过有人忘了配,结果磁盘写满,Broker直接挂掉。 - 网络延迟:ZK对网络延迟很敏感。如果三个节点跨机房部署,延迟超过100ms,ZK集群可能频繁选举。
- 时钟同步:所有节点的时间必须同步。用NTP服务,不然ZK的Session会超时。
避坑指南:我曾经在生产环境遇到过一个问题:ZK集群三个节点都在同一台物理机上(用Docker部署)。结果物理机宕机,整个集群全挂。所以,ZK节点一定要分布在不同的物理机上。
好了,到这里,Kafka集群的部署就完成了。你按照这个流程走一遍,应该能顺利搭起来。如果遇到问题,先检查日志——/opt/kafka/logs/server.log和/opt/zookeeper/logs/zookeeper.log里通常有线索。