本文手把手教你从零搭建一个高可用的Kafka集群,涵盖Zookeeper选举、Broker配置、Topic分区策略及故障排查全流程。
一、开篇:从单机到集群,迈出高可用第一步
在前几篇文章中,我们体验了Kafka单机版的威力。但在真实的生产环境中,单点故障 和容量瓶颈 是必须解决的问题。今天,我们将一起迈出关键一步------从单台服务器扩展到三台服务器,搭建一个具备高可用 和横向扩展能力的Kafka集群。
想象一下:一家快递公司从只有1个仓库,扩展到3个区域分拨中心。即使某个分拨中心临时关闭,快递网络依然能正常运转。这就是集群的价值所在。
消息即连接,数据即价值。 而高可用的集群,就是保障这份价值永不中断的基石。
二、为什么需要Kafka集群?
在单机环境下,Kafka的性能已经相当惊人(TPS可达百万级别)。但面对以下场景时,集群成为必然选择:
1. 数据量太大,一台机器存不下
- 一个Topic每天产生TB级日志
- 解决方案:将数据拆分到多个Partition,分布到不同Broker
2. 单点故障风险高
- 机器宕机 → 服务中断 → 数据丢失
- 解决方案:每个Partition配置多个副本,主从备份
3. 读写性能需要线性扩展
- 并发用户数从1万增长到100万
- 解决方案:增加Broker节点,分散读写压力
4. 业务需要高可用保障
- 金融交易、实时监控等关键业务
- 解决方案:跨节点冗余,自动故障转移
三、环境准备:三台服务器的交响曲
我们将在三台CentOS服务器上搭建集群,它们将扮演不同的角色:
| 服务器 | 主机名 | IP示例 | 角色 |
|---|---|---|---|
| 服务器1 | worker1 | 192.168.1.101 | ZK节点 + Kafka Broker |
| 服务器2 | worker2 | 192.168.1.102 | ZK节点 + Kafka Broker |
| 服务器3 | worker3 | 192.168.1.103 | ZK节点 + Kafka Broker |
前置检查清单:
# 1. 确保三台服务器时钟同步(集群必备)
sudo timedatectl set-ntp true
date # 在三台机器上分别执行,时间差应小于1秒
# 2. 关闭防火墙或开放必要端口
sudo systemctl stop firewalld
sudo systemctl disable firewalld
# 3. 配置主机名解析(每台机器都要配置)
sudo vi /etc/hosts
在/etc/hosts文件中添加:
text
192.168.1.101 worker1
192.168.1.102 worker2
192.168.1.103 worker3
4. 安装JDK 1.8+
sudo yum install -y java-1.8.0-openjdk-devel
java -version
注意:生产环境中建议配置专用防火墙规则,而不是直接关闭防火墙。
四、第一步:部署Zookeeper集群(选举中心)
Zookeeper是Kafka集群的"大脑",负责Broker注册、Leader选举、配置管理等关键协调工作。
1. 下载与安装(三台机器都执行)
# 下载Zookeeper(以3.8.4为例)
wget https://downloads.apache.org/zookeeper/zookeeper-3.8.4/apache-zookeeper-3.8.4-bin.tar.gz
# 解压到指定目录
sudo mkdir -p /app
sudo tar -zxvf apache-zookeeper-3.8.4-bin.tar.gz -C /app/
sudo mv /app/apache-zookeeper-3.8.4-bin /app/zookeeper
2. 配置Zookeeper集群
# 进入配置目录
cd /app/zookeeper/conf
# 复制示例配置文件
cp zoo_sample.cfg zoo.cfg
# 编辑配置文件
vi zoo.cfg
关键配置项如下:
properties
# 数据存储目录(重要!不要用默认的/tmp)
dataDir=/app/zookeeper/data
# 客户端连接端口
clientPort=2181
# 集群节点配置(三台机器配置相同)
server.1=worker1:2888:3888
server.2=worker2:2888:3888
server.3=worker3:2888:3888
配置说明:
server.x:x是节点的唯一ID(myid)2888:集群内部数据同步端口3888:集群选举通信端口
3. 创建myid文件(每台机器不同)
# 在worker1上执行
echo 1 > /app/zookeeper/data/myid
# 在worker2上执行
echo 2 > /app/zookeeper/data/myid
# 在worker3上执行
echo 3 > /app/zookeeper/data/myid
技巧 :可以使用scp命令将配置好的zookeeper目录直接分发到其他机器,然后只需修改myid文件。
4. 启动与验证Zookeeper集群
# 在三台机器上分别启动(使用后台模式)
cd /app/zookeeper
bin/zkServer.sh start
# 检查启动状态
bin/zkServer.sh status
期望输出:
text
# 其中一台会是Leader
Mode: leader
# 另外两台是Follower
Mode: follower
小贴士 :如果出现Error contacting service. It is probably not running.,检查防火墙和网络连通性。
五、第二步:部署Kafka集群(消息引擎)
Zookeeper集群就绪后,我们来部署Kafka Broker集群。
1. 下载与安装(三台机器都执行)
# 下载Kafka(以3.8.0为例)
wget https://downloads.apache.org/kafka/3.8.0/kafka_2.13-3.8.0.tgz
# 解压
sudo tar -zxvf kafka_2.13-3.8.0.tgz -C /app/
sudo mv /app/kafka_2.13-3.8.0 /app/kafka
2. 配置Kafka Broker
# 进入配置目录
cd /app/kafka/config
# 编辑配置文件
vi server.properties
worker1上的关键配置:
properties
# Broker唯一ID(每台机器必须不同)
broker.id=1
# 服务监听地址(使用主机名或IP)
listeners=PLAINTEXT://worker1:9092
# 数据存储目录(可配置多个,用逗号分隔)
log.dirs=/app/kafka/logs
# 默认分区数(创建Topic时的默认值)
num.partitions=3
# 默认副本因子(建议设置为2或3)
default.replication.factor=3
# Zookeeper集群地址
zookeeper.connect=worker1:2181,worker2:2181,worker3:2181
# 以下为可选优化配置
# 消息保留时间(小时)
log.retention.hours=168
# 是否允许删除Topic
delete.topic.enable=true
# 最小同步副本数(影响消息持久性)
min.insync.replicas=2
worker2和worker3的配置区别:
broker.id:分别设置为2和3listeners:分别设置为worker2:9092和worker3:9092- 其他配置可以相同
3. 启动Kafka集群
# 在三台机器上分别启动(后台模式)
cd /app/kafka
nohup bin/kafka-server-start.sh config/server.properties > kafka.log 2>&1 &
# 检查进程
jps | grep Kafka
期望看到每台机器上都有Kafka进程。
4. 验证集群状态
# 在任何一台Broker上执行
bin/kafka-broker-api-versions.sh --bootstrap-server worker1:9092
# 查看集群中的Broker
bin/kafka-cluster.sh --bootstrap-server worker1:9092 cluster-id
六、第三步:创建分布式Topic,体验集群威力
现在集群已经运行,让我们创建一个真正分布式的Topic。
1. 创建具备冗余的Topic
# 在任意一台Broker上执行
bin/kafka-topics.sh \
--bootstrap-server worker1:9092 \
--create \
--topic cluster-topic \
--partitions 3 \
--replication-factor 2
参数解析:
--partitions 3:将Topic分为3个分区,可并行处理--replication-factor 2:每个分区有2个副本,提高可用性
2. 查看Topic详情
bin/kafka-topics.sh \
--bootstrap-server worker1:9092 \
--describe \
--topic cluster-topic
期望输出:
text
Topic: cluster-topic TopicId: xxxx PartitionCount: 3 ReplicationFactor: 2 Configs:
Topic: cluster-topic Partition: 0 Leader: 1 Replicas: 1,2 Isr: 1,2
Topic: cluster-topic Partition: 1 Leader: 2 Replicas: 2,3 Isr: 2,3
Topic: cluster-topic Partition: 2 Leader: 3 Replicas: 3,1 Isr: 3,1
输出解读:
Partition: 0:分区编号Leader: 1:该分区的主节点是broker.id=1的机器Replicas: 1,2:该分区的副本分布在broker1和broker2上Isr: 1,2:当前存活的同步副本(In-Sync Replicas)
3. 测试集群消息收发
# 生产者(发送到集群)
bin/kafka-console-producer.sh \
--broker-list worker1:9092,worker2:9092,worker3:9092 \
--topic cluster-topic
# 消费者(从集群消费)
bin/kafka-console-consumer.sh \
--bootstrap-server worker1:9092 \
--topic cluster-topic \
--from-beginning
注意 :生产者的--broker-list参数包含所有Broker地址,这样即使某个Broker宕机,生产者也能自动切换到其他可用Broker。
七、集群状态检查与故障排查指南
1. 日常健康检查命令
# 1. 检查Broker是否存活
jps | grep -E "(Kafka|QuorumPeerMain)"
# 2. 查看Topic分布状态
bin/kafka-topics.sh --bootstrap-server worker1:9092 --describe
# 3. 查看消费者组延迟
bin/kafka-consumer-groups.sh --bootstrap-server worker1:9092 --all-groups --describe
# 4. 检查集群控制器
bin/kafka-metadata-quorum.sh --bootstrap-server worker1:9092 describe --status
2. 常见故障与解决方案
问题1:Zookeeper节点无法启动
现象 :Error contacting service. It is probably not running.
排查步骤:
# 检查myid文件是否正确
cat /app/zookeeper/data/myid
# 检查端口是否被占用
netstat -tlnp | grep 2181
# 查看日志
tail -100 /app/zookeeper/logs/zookeeper.out
问题2:Kafka Broker无法加入集群
现象 :Broker启动后立即退出
排查步骤:
# 检查broker.id是否重复
grep broker.id config/server.properties
# 检查Zookeeper连接
telnet worker1 2181
# 查看Kafka日志
tail -100 /app/kafka/logs/server.log
问题3:生产者发送消息失败
现象 :LEADER_NOT_AVAILABLE或NOT_ENOUGH_REPLICAS
解决方案:
# 检查Topic的ISR列表
bin/kafka-topics.sh --bootstrap-server worker1:9092 --describe --topic your-topic
# 如果ISR数量小于min.insync.replicas,需要等待副本同步
# 或临时降低生产者的acks要求
3. 模拟故障演练(学习环境)
# 1. 停止一个Broker(模拟宕机)
ps aux | grep kafka | grep -v grep | awk '{print $2}' | head -1 | xargs kill
# 2. 观察Topic的Leader切换
watch -n 1 "bin/kafka-topics.sh --bootstrap-server worker2:9092 --describe --topic cluster-topic"
# 3. 消息收发是否正常
# 生产者应自动切换到其他Broker
# 消费者应继续消费(可能有短暂暂停)
八、集群优化建议
1. 硬件规划
- 磁盘:使用SSD,配置多个数据目录
- 内存:至少16GB,JVM堆内存设置4-8GB
- 网络:千兆或万兆网卡,低延迟网络
2. 配置优化
properties
# server.properties中的关键优化项
# 提高吞吐量
num.network.threads=8
num.io.threads=16
# 优化刷盘策略
log.flush.interval.messages=10000
log.flush.interval.ms=1000
# 调整副本同步
replica.socket.timeout.ms=30000
replica.lag.time.max.ms=10000
3. 监控方案
- 基础监控:JVM内存、CPU、磁盘IO、网络流量
- 业务监控:Topic吞吐量、消费者延迟、ISR数量
- 告警阈值:ISR数量减少、磁盘使用率>80%、Broker宕机
九、常见问题FAQ
Q1:Zookeeper为什么需要奇数个节点?
A:Zookeeper采用多数同意原则(Quorum)。3个节点允许1个故障,5个节点允许2个故障。奇数个节点可以最大化容错能力。
Q2:replication-factor设置为多少合适?
A:
- 测试环境:1(无冗余)
- 预生产环境:2(允许1个Broker故障)
- 生产环境:3(允许2个Broker故障,更高可用性)
Q3:分区数是不是越多越好?
A:不是!分区数影响:
- 并行度:分区数越多,并行消费能力越强
- ZK压力:每个分区都在ZK上有元数据
- 推荐:从
(预期消费者数 * 2)开始,根据监控调整
Q4:如何安全地扩容集群?
A:步骤:
- 准备新服务器,配置相同的环境
- 启动新Broker(确保broker.id唯一)
- 使用
kafka-reassign-partitions.sh工具重新分配分区 - 监控数据迁移进度,确保无数据丢失
Q5:Kafka集群需要几台服务器?
A:最小3台(ZK和Broker混布)。生产环境建议:
- 中小规模:3-5台
- 大规模:ZK集群3台 + Broker集群5台以上
Q6:如何备份和恢复Kafka数据?
A:
- 备份 :直接复制
log.dirs目录数据 - 恢复:停止Broker → 替换数据目录 → 重启 → 等待副本同步
- 工具 :考虑使用
MirrorMaker进行跨集群复制
十、总结:从三台服务器开始的数据高速公路
通过今天的实战,我们完成了:
✅ Zookeeper集群部署 ------建立可靠的选举中心
✅ Kafka Broker集群配置 ------构建弹性的消息引擎
✅ 分布式Topic创建 ------体验真正的分区与副本机制
✅ 故障排查技能------掌握集群运维的关键命令
消息如流水,Kafka是渠道,而集群就是由多条渠道组成的智能水网。即使某条渠道临时堵塞,水流依然能通过其他路径到达目的地。
现在,你已经拥有了一个真正高可用的Kafka集群。它不仅能存储海量数据,还能在部分节点故障时自动恢复,为你的业务提供坚实的数据流转保障。
下一期,我们将深入Kafka的生产者与消费者高级配置,探索如何优化吞吐量、保证消息顺序、实现精确一次语义等高级特性。
动手挑战:尝试在搭建好的集群中,模拟Broker宕机,观察Leader如何自动切换,并记录切换时间和数据完整性。欢迎在留言区分享你的实验结果!
📲 关注公众号【码客研究所】
每天进步一点点,让你上班少加班,下班早回家!
作者:MarkYe
所属合集: 《流式心传·MQ手札》
关键词: Kafka集群搭建、高可用架构、Zookeeper配置、分布式消息队列、故障转移、分区副本