3、Kafka集群部署:单机与集群模式搭建、ZooKeeper/KRaft模式对比、常用配置参数
好,咱们进入第三章。说实话,Kafka的部署是很多初学者第一个“劝退点”。单机还好说,一上集群就各种玄学报错。我当年第一次搭三节点集群,折腾了整整一个通宵,最后发现是防火墙没关。嗯,今天咱们就把这事彻底捋清楚。
3.1 单机模式:快速上手
单机模式说白了就是“先跑起来看看”。你本地开发、做Demo、或者像我一样想快速验证一个Flink消费逻辑,用单机就够了。
步骤其实很简单:
- 下载Kafka二进制包(别从源码编译,浪费时间)
- 解压,进入目录
- 启动ZooKeeper(老版本必须,新版本可选)
- 启动Kafka Server
我习惯把ZooKeeper和Kafka的日志目录单独拎出来,放在 /data/kafka 下。为什么?因为默认的 /tmp 目录,系统一重启就没了。我曾经吃过这个亏,生产环境数据全丢,吓得我后背发凉。
# 启动 ZooKeeper(Kafka 自带)
bin/zookeeper-server-start.sh config/zookeeper.properties
# 启动 Kafka Broker
bin/kafka-server-start.sh config/server.properties
启动成功后,你可以创建一个Topic试试:
bin/kafka-topics.sh --create --topic test-topic --bootstrap-server localhost:9092 --partitions 3 --replication-factor 1
replication-factor 只能设为1。你设成3试试?Kafka会直接报错,告诉你没有足够的副本节点。这个坑我踩过。
3.2 集群模式:真正的战场
生产环境必须上集群。为什么?单点故障你扛不住。我记得有一次线上单机Kafka挂了,整个实时数仓链路断了两个小时,业务方电话打爆了。从那以后,我坚持至少三节点起步。
集群搭建的核心逻辑很简单:多个Broker,共享同一个ZooKeeper集群。每个Broker的 server.properties 里,broker.id 必须唯一。
假设你有三台机器:
| 节点 | IP | broker.id |
|---|---|---|
| Node1 | 192.168.1.101 | 1 |
| Node2 | 192.168.1.102 | 2 |
| Node3 | 192.168.1.103 | 3 |
每个节点的 server.properties 核心配置如下:
# Node1 示例
broker.id=1
listeners=PLAINTEXT://192.168.1.101:9092
log.dirs=/data/kafka/logs
zookeeper.connect=192.168.1.101:2181,192.168.1.102:2181,192.168.1.103:2181
你想想看,这里有个容易忽略的点:listeners 要写内网IP,别写 0.0.0.0。我见过有人写了 0.0.0.0,结果客户端连不上,折腾半天才发现是监听地址的问题。
zookeeper.connect 要写所有ZooKeeper节点的地址,用逗号分隔。别只写一个,否则ZooKeeper挂了你的Kafka也就废了。
3.3 ZooKeeper vs KRaft:新旧模式之争
这个话题最近很热。Kafka 2.8开始引入了KRaft模式,目的是干掉ZooKeeper。为什么?说白了,ZooKeeper本身也是一个分布式系统,维护它等于多了一套要伺候的“祖宗”。
我个人的经验是这样的:
- ZooKeeper模式:成熟稳定,社区资料多。如果你用的是Kafka 2.x或者3.0以下,老老实实用ZooKeeper。
- KRaft模式:架构更简洁,没有外部依赖。但注意,直到Kafka 3.5版本,KRaft才算是生产就绪。我之前在3.2版本上试过KRaft,遇到过Controller选举超时的问题。
来,咱们画个图对比一下:
你看这个图就清楚了。左边ZooKeeper模式,Broker和ZooKeeper是两套系统;右边KRaft模式,Controller角色内嵌在Broker中,通过Raft协议自己选主。
3.4 常用配置参数:这些你必须知道
配置参数太多了,几百个。但常用的其实就十几个。我按重要程度排个序:
| 参数名 | 默认值 | 说明 | 我的建议 |
|---|---|---|---|
broker.id |
0 | 集群内唯一标识 | 从1开始编号,别用0 |
log.dirs |
/tmp/kafka-logs | 数据存储目录 | 改成独立磁盘,别用/tmp |
num.partitions |
1 | 默认分区数 | 生产环境建议3-6 |
default.replication.factor |
1 | 默认副本数 | 至少2,推荐3 |
log.retention.hours |
168 | 日志保留时间(小时) | 看业务需求,7天够用 |
log.segment.bytes |
1073741824 | 单个日志段大小(1GB) | 别改,默认挺好 |
message.max.bytes |
1048576 | 单条消息最大字节 | 如果传大图片,改成10MB |
这里有个参数我特别想提一下——log.retention.hours。你想想看,如果设置得太短,消费者还没消费完数据就被删了;设置得太长,磁盘又扛不住。我一般建议:先按7天设,然后监控磁盘使用率。如果磁盘涨得太快,再调短。
message.max.bytes 设成50MB,结果生产者疯狂报错。后来发现Kafka的 fetch.max.bytes 也要同步调大,否则消费者拉取时会失败。这两个参数要一起改。
3.5 启动与验证
配置写好了,怎么验证集群是否正常?我一般三步走:
- 看日志:启动时看
logs/server.log,搜索INFO [KafkaServer id=1] started字样 - 查节点:
bin/zookeeper-shell.sh localhost:2181 ls /brokers/ids,看看有几个节点 - 发消息:创建一个带副本的Topic,然后生产消费测试
# 创建带3副本的Topic
bin/kafka-topics.sh --create --topic my-topic \
--bootstrap-server localhost:9092 \
--partitions 3 --replication-factor 3
# 查看Topic详情
bin/kafka-topics.sh --describe --topic my-topic \
--bootstrap-server localhost:9092
输出结果里,你会看到类似这样的信息:
Topic: my-topic Partition: 0 Leader: 1 Replicas: 1,2,3 Isr: 1,2,3
Topic: my-topic Partition: 1 Leader: 2 Replicas: 2,3,1 Isr: 2,3,1
Topic: my-topic Partition: 2 Leader: 3 Replicas: 3,1,2 Isr: 3,1,2
看到 Isr 里三个节点都在,说明集群正常。如果某个节点不在 Isr 里,那就要去查那个节点的日志了。嗯,这种情况我遇到过,多半是磁盘满了或者网络不通。
好了,Kafka集群部署这块就这些。说白了,单机是入门,集群是实战,ZooKeeper和KRaft是选择题,配置参数是基本功。把这些搞定了,后面跟Flink集成的时候,你心里就有底了。
公众号:蓝海资料掘金营,微信deep3321