Kafka(05)搭建高可用Kafka集群:从三台服务器开始

本文手把手教你从零搭建一个高可用的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和3
  • listeners:分别设置为worker2:9092worker3: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_AVAILABLENOT_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:步骤:

  1. 准备新服务器,配置相同的环境
  2. 启动新Broker(确保broker.id唯一)
  3. 使用kafka-reassign-partitions.sh工具重新分配分区
  4. 监控数据迁移进度,确保无数据丢失

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配置、分布式消息队列、故障转移、分区副本

相关推荐
落羽的落羽1 小时前
【Linux系统】磁盘ext文件系统与软硬链接
linux·运维·服务器·数据库·c++·人工智能·机器学习
Codefengfeng1 小时前
Kali-linux中安装与使用Stegsolve
linux·运维·服务器
桂花很香,旭很美1 小时前
[7天实战入门Go语言后端] Go 后端实战踩坑与解法手册
服务器·网络·golang
tritone2 小时前
初探云原生:在阿贝云免费服务器上学习负载均衡的实践心得
服务器·学习·云原生
百锦再2 小时前
Java ForkJoin 框架全面解析:分而治之的并行编程艺术
java·开发语言·spring boot·spring cloud·kafka·tomcat·maven
何中应3 小时前
如何在 Linux 系统中设置系统时间
linux·运维·服务器
破无差3 小时前
第十一天:技能装载 —— 接入 MCP 生态与工具路由
服务器
雪碧聊技术3 小时前
4.CA证书的介绍?
运维·服务器
Web极客码4 小时前
如何使用 Sugar Calendar 插件打造一个可销售活动门票的 WordPress 网站
运维·服务器