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 验证集群状态

我一般用这几个命令来验证:

  1. 查看Broker列表:
/opt/kafka/bin/zookeeper-shell.sh 192.168.1.101:2181 ls /brokers/ids

输出应该是[0, 1, 2],表示三个Broker都注册了。

  1. 创建测试Topic:
/opt/kafka/bin/kafka-topics.sh --create --topic test-topic --partitions 3 --replication-factor 2 --bootstrap-server 192.168.1.101:9092
  1. 查看Topic详情:
/opt/kafka/bin/kafka-topics.sh --describe --topic test-topic --bootstrap-server 192.168.1.101:9092

输出应该显示每个Partition的Leader、Replicas和ISR。

  1. 生产与消费测试:
# 生产者
/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集群的关系,以及客户端如何连接。

Kafka 3节点集群部署架构图 Kafka 3节点集群部署架构 Zookeeper 集群(3节点) ZK-01 (Leader) ZK-02 (Follower) ZK-03 (Follower) Kafka Broker 集群(3节点) Broker-0 (Leader) Broker-1 Broker-2 客户端连接 Producer Consumer Admin Tools 说明:ZK集群负责Broker元数据管理和Leader选举;Broker集群负责消息存储和复制;客户端通过Bootstrap Server连接任意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里通常有线索。