2. Kafka 安装与部署:单机模式安装、ZooKeeper 配置、Kafka Server 配置、启动与验证
说实话,很多初学者一上来就奔着集群去了。我个人习惯是,先老老实实把单机跑通。你想想看,单机都搞不定,集群只会让你更头疼。这一章,我们就从零开始,把 Kafka 单机环境搭起来。
我会把每一步拆开讲,包括 ZooKeeper 的配置、Kafka Server 的参数调优,以及启动后怎么验证它是不是真的在干活。嗯,这里要注意,很多坑其实就藏在那些不起眼的配置项里。
核心目标:在一台机器上完成 Kafka 单机部署,并验证生产者与消费者的基本通信。
2.1 环境准备与版本选择
先说说版本。Kafka 从 2.8 版本开始逐步剥离对 ZooKeeper 的强依赖,但直到 3.x 系列,ZooKeeper 模式依然是生产环境的主流选择。我建议你选 Kafka 3.4.0 + ZooKeeper 3.8.1 这个组合,稳定,社区活跃,文档也全。
操作系统方面,CentOS 7 或 Ubuntu 20.04 都行。JDK 必须 11 以上,我用的是 OpenJDK 11。记得配好 JAVA_HOME 环境变量,不然启动时会报错——我曾经因为这个卡了半小时,后来发现是路径写错了。
| 组件 | 推荐版本 | 备注 |
|---|---|---|
| Kafka | 3.4.0 | Scala 2.13 编译版本 |
| ZooKeeper | 3.8.1 | 独立部署,非内嵌 |
| JDK | 11 (OpenJDK) | 必须配置 JAVA_HOME |
| OS | CentOS 7 / Ubuntu 20.04 | 64位系统 |
2.2 下载与解压
下载地址我就不贴了,直接去 Apache 官网找。我个人习惯把软件统一放在 /opt 目录下,方便管理。
# 下载 Kafka(包含内置 ZooKeeper 脚本,但我们用独立 ZK)
wget https://downloads.apache.org/kafka/3.4.0/kafka_2.13-3.4.0.tgz
# 解压
tar -xzf kafka_2.13-3.4.0.tgz -C /opt/
# 创建软链接,方便后续升级
ln -s /opt/kafka_2.13-3.4.0 /opt/kafka
# 下载 ZooKeeper
wget https://downloads.apache.org/zookeeper/zookeeper-3.8.1/apache-zookeeper-3.8.1-bin.tar.gz
# 解压
tar -xzf apache-zookeeper-3.8.1-bin.tar.gz -C /opt/
ln -s /opt/apache-zookeeper-3.8.1-bin /opt/zookeeper
小技巧:软链接是个好习惯。以后升级版本,只需要改一下链接指向,不用改脚本里的路径。
2.3 ZooKeeper 配置
ZooKeeper 的配置文件在 /opt/zookeeper/conf/ 目录下。默认有个 zoo_sample.cfg,复制一份改名为 zoo.cfg。
cp /opt/zookeeper/conf/zoo_sample.cfg /opt/zookeeper/conf/zoo.cfg
打开 zoo.cfg,核心参数如下:
# ZooKeeper 基本配置
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/data/zookeeper
clientPort=2181
maxClientCnxns=60
解释一下这几个参数:
- tickTime:ZooKeeper 的最小时间单位,单位毫秒。2000 就是 2 秒。
- initLimit:Leader 节点启动时,Follower 节点同步数据的最大时间。10 个 tick,也就是 20 秒。
- syncLimit:Leader 与 Follower 之间心跳超时时间。5 个 tick,10 秒。
- dataDir:数据存储目录。记得提前创建好,ZooKeeper 不会自动建。
- clientPort:客户端连接端口,默认 2181。
注意:dataDir 目录必须手动创建,并且确保运行 ZooKeeper 的用户有读写权限。我曾经因为忘记建目录,启动时报了个莫名其妙的错误,排查了半天。
2.4 Kafka Server 配置
Kafka 的配置文件在 /opt/kafka/config/server.properties。单机模式下,我们主要关注以下几个参数:
# 每个 broker 的唯一标识,单机就写 0
broker.id=0
# 监听地址,0.0.0.0 表示监听所有网卡
listeners=PLAINTEXT://0.0.0.0:9092
# 对外暴露的地址,客户端通过这个地址连接
advertised.listeners=PLAINTEXT://192.168.1.100:9092
# 日志数据存储目录
log.dirs=/data/kafka/logs
# ZooKeeper 连接地址
zookeeper.connect=localhost:2181
# 日志保留时间,单位小时,默认 168(7天)
log.retention.hours=168
# 每个分区日志文件的最大大小,默认 1GB
log.segment.bytes=1073741824
# 自动创建主题,生产环境建议关掉
auto.create.topics.enable=false
这里有个容易踩的坑:advertised.listeners。如果你是在本机测试,写 localhost 没问题。但如果是跨机器访问,必须写本机的真实 IP 或域名。否则客户端连上来会报连接超时——我当年在测试环境就吃过这个亏。
关键参数速查表:
| 参数名 | 默认值 | 说明 |
|---|---|---|
| broker.id | 0 | 集群中唯一标识,单机保持 0 |
| listeners | PLAINTEXT://:9092 | 监听地址和协议 |
| advertised.listeners | null | 客户端可见地址,跨机器必须配置 |
| log.dirs | /tmp/kafka-logs | 建议改为独立数据盘,别用 /tmp |
| zookeeper.connect | localhost:2181 | ZooKeeper 连接串 |
| auto.create.topics.enable | true | 生产环境建议关掉 |
2.5 启动与验证
启动顺序很重要:先启动 ZooKeeper,再启动 Kafka。反过来不行,Kafka 启动时会连 ZooKeeper,连不上就直接退出了。
2.5.1 启动 ZooKeeper
# 启动 ZooKeeper
/opt/zookeeper/bin/zkServer.sh start
# 检查是否启动成功
/opt/zookeeper/bin/zkServer.sh status
# 正常输出应该是:
# ZooKeeper JMX enabled by default
# Using config: /opt/zookeeper/bin/../conf/zoo.cfg
# Client port found: 2181. Client address: localhost.
# Mode: standalone
看到 Mode: standalone 就说明 ZooKeeper 跑起来了。
2.5.2 启动 Kafka
# 启动 Kafka
/opt/kafka/bin/kafka-server-start.sh -daemon /opt/kafka/config/server.properties
# 检查进程
jps -l | grep kafka
# 正常应该看到类似输出:
# 12345 kafka.Kafka
-daemon 参数让 Kafka 在后台运行。如果不加,终端一关进程就没了。
2.5.3 验证功能
启动完成后,我们创建一个测试主题,然后发条消息试试。
# 创建主题
/opt/kafka/bin/kafka-topics.sh --create \
--bootstrap-server localhost:9092 \
--replication-factor 1 \
--partitions 1 \
--topic test-topic
# 查看主题列表
/opt/kafka/bin/kafka-topics.sh --list \
--bootstrap-server localhost:9092
# 启动生产者,输入消息
/opt/kafka/bin/kafka-console-producer.sh \
--broker-list localhost:9092 \
--topic test-topic
> hello kafka
> this is a test message
> ^C # Ctrl+C 退出
# 启动消费者,查看消息
/opt/kafka/bin/kafka-console-consumer.sh \
--bootstrap-server localhost:9092 \
--topic test-topic \
--from-beginning
hello kafka
this is a test message
如果消费者能正确打印出生产者发送的消息,恭喜你,单机环境搭建成功。
验证小技巧:消费者加上 --from-beginning 参数,会从头开始消费所有消息。如果不加,只消费启动之后的消息。这个区别在调试时很有用。
2.6 整体架构图
下面这张图展示了单机模式下各组件的关系。你可以看到,Producer 和 Consumer 都通过 Kafka Broker 交互,而 Broker 的元数据信息存储在 ZooKeeper 中。
2.7 常见问题与避坑
最后,分享几个我实际遇到过的问题:
- 端口被占用:ZooKeeper 的 2181 端口或 Kafka 的 9092 端口被其他进程占用。用
netstat -tlnp | grep 2181检查一下。 - 数据目录权限:ZooKeeper 和 Kafka 的数据目录如果没有写权限,启动时会报错。确保目录所有者是运行进程的用户。
- 防火墙未关闭:跨机器访问时,记得关闭防火墙或开放对应端口。CentOS 7 用
systemctl stop firewalld。 - JAVA_HOME 未设置:启动脚本依赖
JAVA_HOME环境变量。用echo $JAVA_HOME确认一下。
曾经踩过的坑:有一次我启动 Kafka 后,生产者发消息一直报 Connection refused。排查了半天,发现是 advertised.listeners 写成了 localhost,而客户端是从另一台机器连接的。改成真实 IP 后问题解决。