2. Kafka集群搭建
搭建Kafka集群,说白了就是两件事:先把Zookeeper跑起来,再把Kafka Broker连上去。很多新手一上来就急着配Kafka,结果Zookeeper没弄好,后面各种诡异问题。我刚开始带团队时也犯过这错——Zookeeper集群没配对,Kafka连了半天连不上,最后发现是Zookeeper的myid文件写错了。嗯,咱们一步步来。
2.1 Zookeeper安装与配置
Kafka从2.8版本开始虽然可以脱离Zookeeper运行(KRaft模式),但生产环境里绝大多数团队还是用Zookeeper。我个人习惯用3.6.x或3.7.x版本,稳定,坑少。
2.1.1 下载与解压
# 下载Zookeeper
wget https://archive.apache.org/dist/zookeeper/zookeeper-3.7.1/apache-zookeeper-3.7.1-bin.tar.gz
# 解压
tar -zxvf apache-zookeeper-3.7.1-bin.tar.gz -C /opt/
mv /opt/apache-zookeeper-3.7.1-bin /opt/zookeeper
2.1.2 配置文件
Zookeeper的配置文件在 conf/zoo.cfg。默认没有这个文件,需要从模板复制。
cd /opt/zookeeper/conf
cp zoo_sample.cfg zoo.cfg
然后修改核心参数:
# zoo.cfg 核心配置
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/data/zookeeper
clientPort=2181
# 集群节点配置(3节点示例)
server.1=192.168.1.101:2888:3888
server.2=192.168.1.102:2888:3888
server.3=192.168.1.103:2888:3888
参数说明:
- tickTime:Zookeeper的基本时间单位,毫秒。2000就是2秒。
- initLimit:Follower启动时与Leader同步的最大tick数。10个tick就是20秒。
- syncLimit:Follower与Leader通信的超时tick数。5个tick就是10秒。
- dataDir:数据存储目录。我建议单独挂一块盘,别跟系统盘混一起。
- clientPort:客户端连接端口,默认2181。
2.1.3 myid文件
每个Zookeeper节点需要一个唯一的ID。在 dataDir 目录下创建 myid 文件:
# 在节点1上
mkdir -p /data/zookeeper
echo "1" > /data/zookeeper/myid
# 在节点2上
echo "2" > /data/zookeeper/myid
# 在节点3上
echo "3" > /data/zookeeper/myid
我曾经踩过的坑:myid文件里的数字必须跟zoo.cfg里server.x的x一致。有一次我手抖把节点2的myid写成了3,结果整个集群选举一直失败,日志里全是连接超时。查了半小时才发现。
2.1.4 启动Zookeeper集群
# 每个节点分别启动
/opt/zookeeper/bin/zkServer.sh start
# 查看状态
/opt/zookeeper/bin/zkServer.sh status
# 正常输出示例(Leader节点)
ZooKeeper JMX enabled by default
Using config: /opt/zookeeper/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost.
Mode: leader
# Follower节点输出
Mode: follower
2.2 Kafka Broker配置
Zookeeper集群跑起来后,咱们开始配Kafka。下载解压就不重复了,直接看核心配置。
2.2.1 server.properties 核心参数
# broker.id 每个节点唯一
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
# 分区副本数
default.replication.factor=3
# 最小同步副本数
min.insync.replicas=2
# 消息保留时间(168小时=7天)
log.retention.hours=168
# 日志段大小(1GB)
log.segment.bytes=1073741824
我的建议:broker.id一定要规划好。我习惯用IP最后一段作为broker.id,比如192.168.1.101就用101。这样看日志时一眼就知道是哪个节点。
2.2.2 参数对比表
| 参数 | 默认值 | 生产推荐值 | 说明 |
|---|---|---|---|
| broker.id | 0 | 唯一整数 | 集群内唯一标识 |
| default.replication.factor | 1 | 3 | 副本数,保证高可用 |
| min.insync.replicas | 1 | 2 | 最小同步副本,防止数据丢失 |
| log.retention.hours | 168 | 72-168 | 根据业务需求调整 |
| num.partitions | 1 | 3-6 | 默认分区数,建议按需设置 |
2.3 集群启动与验证
2.3.1 启动Kafka
# 每个Broker节点执行
/opt/kafka/bin/kafka-server-start.sh -daemon /opt/kafka/config/server.properties
# 查看进程是否启动
jps | grep Kafka
# 输出示例
12345 Kafka
2.3.2 验证集群状态
启动后别急着走,先验证一下。我一般做三步检查:
- 检查Zookeeper里的Broker注册信息
/opt/zookeeper/bin/zkCli.sh -server 192.168.1.101:2181
ls /brokers/ids
# 应该看到 [1, 2, 3]
- 查看Broker的日志
tail -f /opt/kafka/logs/server.log
# 搜索 "started" 关键字
# 正常会看到类似:
# [2024-01-15 10:30:00,123] INFO [KafkaServer id=1] started (kafka.server.KafkaServer)
- 用命令行工具验证
# 查看所有Broker
/opt/kafka/bin/kafka-broker-api-versions.sh --bootstrap-server 192.168.1.101:9092
# 创建测试Topic
/opt/kafka/bin/kafka-topics.sh --create \
--topic test-cluster \
--partitions 3 \
--replication-factor 3 \
--bootstrap-server 192.168.1.101:9092
# 查看Topic详情
/opt/kafka/bin/kafka-topics.sh --describe \
--topic test-cluster \
--bootstrap-server 192.168.1.101:9092
验证通过的标准:
- Zookeeper里能看到所有Broker ID
- 日志无ERROR或FATAL
- Topic的Replicas分布在不同的Broker上
- ISR(In-Sync Replicas)列表完整
2.4 常用命令行工具
Kafka自带的命令行工具非常强大。我平时用得最多的就这几个:
2.4.1 kafka-topics.sh
Topic管理,创建、删除、查看、修改。
# 列出所有Topic
kafka-topics.sh --list --bootstrap-server localhost:9092
# 查看Topic详情
kafka-topics.sh --describe --topic my-topic --bootstrap-server localhost:9092
# 修改分区数(只能增加)
kafka-topics.sh --alter --topic my-topic --partitions 6 --bootstrap-server localhost:9092
2.4.2 kafka-console-producer.sh
生产消息测试,简单粗暴。
# 发送消息
kafka-console-producer.sh --topic my-topic --bootstrap-server localhost:9092
>hello world
>test message
>^C # Ctrl+C退出
2.4.3 kafka-console-consumer.sh
消费消息验证,支持从开头或最新开始。
# 从最新开始消费
kafka-console-consumer.sh --topic my-topic --bootstrap-server localhost:9092
# 从开头开始消费
kafka-console-consumer.sh --topic my-topic --bootstrap-server localhost:9092 --from-beginning
2.4.4 kafka-consumer-groups.sh
消费者组管理,查看偏移量、重置偏移量。
# 列出所有消费者组
kafka-consumer-groups.sh --list --bootstrap-server localhost:9092
# 查看组详情
kafka-consumer-groups.sh --describe --group my-group --bootstrap-server localhost:9092
# 重置偏移量到最新
kafka-consumer-groups.sh --reset-offsets --group my-group \
--topic my-topic --to-latest --execute --bootstrap-server localhost:9092
注意:重置偏移量时,消费者组必须处于非活跃状态。我曾经在生产环境上直接执行重置,结果消费者还在跑,偏移量乱跳,丢了一批消息。还好有备份,不然就出大事了。
2.5 集群架构图
下面这张图展示了我们搭建的3节点Kafka集群的完整架构:
2.6 避坑总结
最后,把我这些年踩过的坑总结一下:
启动顺序:先Zookeeper,再Kafka。关的时候反过来,先Kafka再Zookeeper。这个顺序我记了五年,从来没忘过。
网络配置:Broker的listeners一定要写IP或域名,别写0.0.0.0。我曾经图省事写了0.0.0.0,结果客户端连不上,折腾了半天才发现是advertised.listeners没配。
生产环境最低配置:
- Zookeeper:3节点,2核4G,SSD盘
- Kafka:3节点,4核8G,SSD盘,独立数据盘
- 副本因子:3
- 最小同步副本:2
- acks:all(生产端)
嗯,集群搭好了,工具也熟了。接下来就可以开始往管道里灌数据了。记住一点:集群搭建只是开始,运维才是持久战。