1、安装前准备
在开始部署 Kafka 集群之前,需要进行一些准备工作:
-
操作系统和主机规划 :准备至少 3 台 CentOS 服务器(可以是虚拟机或实体机),用于部署 3 个 Kafka broker 节点和 3 个 ZooKeeper 实例。这样可以形成一个具有高可用性的生产级基本集群(典型架构一般使用 3 个 ZooKeeper 节点,必要时可扩展到 5 个。确保这些服务器网络互通,并为它们配置合适的主机名或 IP 地址(以下文档中假定主机名分别为
kafka1
,kafka2
,kafka3
)。如果没有 DNS,可在每台服务器的/etc/hosts
文件中添加相应条目以解析主机名。 -
Java 环境 :安装 Java (JDK) 11 或更高版本。Kafka 是用 Java 开发的,需要 Java 运行时环境支持。 确认使用
java -version
命令可以看到正确的版本输出。如果系统上没有安装 Java,可通过yum install java-11-openjdk
等方式安装。 -
创建 Kafka 用户(可选) :为了提高安全性,建议为运行 Kafka 和 ZooKeeper 创建一个独立的系统用户,例如
kafka
用户,并避免使用 root 用户直接运行服务。可以执行命令创建用户并创建其主目录,例如:sudo useradd -m -s /sbin/nologin kafka
然后稍后在安装目录中赋予该用户读写权限。本文档后续假定使用
kafka
用户来运行 Kafka 和 ZooKeeper 服务。 -
文件描述符限制 :Kafka 对文件描述符数量要求较高,默认的每进程 1024 个文件句柄可能不足。 为避免潜在的「Too many open files」错误,建议将操作系统的文件描述符限制调高到至少
100000
。可以通过编辑/etc/security/limits.conf
或在 systemd 服务配置中设置LimitNOFILE
来提高该限制。
完成以上准备工作后,继续进行 ZooKeeper 和 Kafka 的安装配置。
1.2、ZooKeeper 安装与配置
Kafka 依赖 Apache ZooKeeper 来存储元数据和进行集群协调。在 Kafka 3.8.1 中,虽然引入了不依赖 ZooKeeper 的 KRaft 模式,但我们这里选择经典的 ZooKeeper 模式来部署 Kafka 集群。强烈建议使用由多个节点组成的 ZooKeeper 集群来提高可靠性 。以下是在每台节点上安装配置 ZooKeeper 3.8.x 的步骤:
-
下载 ZooKeeper:从 Apache 官方获取 ZooKeeper 二进制发行版(稳定版 3.8.2 或相近版本)。例如,在每台机器上执行:
wget https://downloads.apache.org/zookeeper/zookeeper-3.8.2/apache-zookeeper-3.8.2-bin.tar.gz
(也可以先下载后通过 SCP 分发到各节点)。下载完成后,选择合适的目录解压。本文将使用
/opt/zookeeper
作为安装目录:tar -xzf apache-zookeeper-3.8.2-bin.tar.gz -C /opt/ mv /opt/apache-zookeeper-3.8.2-bin /opt/zookeeper
解压并重命名目录为统一的
/opt/zookeeper
便于后续引用。将该目录权限赋给kafka
用户:chown -R kafka:kafka /opt/zookeeper
-
配置 ZooKeeper:ZooKeeper 安装包提供了示例配置文件。进入配置目录并复制一份示例文件:
cd /opt/zookeeper/conf cp zoo_sample.cfg zoo.cfg
使用编辑器打开
zoo.cfg
,根据集群需要进行修改:-
基本时间参数:设置心跳间隔和超时等参数:
tickTime=2000 initLimit=10 syncLimit=5
以上配置表示 ZooKeeper 的基本心跳单元为 2000 毫秒,Follower 在启动时最多等待 10 个 tick 与 Leader 完成同步,Leader 与 Follower 之间通信最大允许 5 个 tick 的延迟。
-
数据存储路径 :修改数据目录为一个持久路径,而非默认的
/tmp
:dataDir=/opt/zookeeper/data
确保创建该目录用于存储 ZooKeeper 内部快照和 myid 文件,例如:
mkdir -p /opt/zookeeper/data chown -R kafka:kafka /opt/zookeeper/data
-
客户端通信端口:保留默认的客户端连接端口:
clientPort=2181
ZooKeeper 客户端(如 Kafka broker 或管理工具)将通过此端口连接到 ZooKeeper。
-
集群配置:添加集群中各 ZooKeeper 节点的信息,每个节点一行:
server.1=kafka1:2888:3888 server.2=kafka2:2888:3888 server.3=kafka3:2888:3888
格式说明:
server.<id>=<主机>:<选举端口>:<同步端口>
。其中<id>
是节点的整数 ID,<主机>
是该 ZooKeeper 实例所在服务器的主机名或IP,2888
为集群中 Leader 与 Follower 之间的数据同步端口,3888
为选举 Leader 时的通信端口。上述配置表示我们有3个 ZooKeeper节点,ID分别为1、2、3,对应主机名kafka1
、kafka2
、kafka3
(请替换为实际的主机名或IP 地址)。注意 :所有 ZooKeeper 实例的配置文件中server.X
列表应该完全相同。
-
-
设置节点 ID :对于每个 ZooKeeper 实例,在其数据目录下创建一个名为
myid
的文件,写入对应的节点ID数字。这个 ID 必须和配置文件中server.X
的 X 相对应。例如:-
在主机
kafka1
上执行:echo "1" > /opt/zookeeper/data/myid
-
在主机
kafka2
上执行:echo "2" > /opt/zookeeper/data/myid
-
在主机
kafka3
上执行:echo "3" > /opt/zookeeper/data/myid
确保
myid
文件中只有数字且无换行符。这样每个 ZooKeeper 实例就能识别自身身份,并在启动时构成一个 quorum 集群。 -
完成上述配置后,ZooKeeper 集群即可准备启动。请在继续 Kafka 部署之前先启动并确认 ZooKeeper 集群正常运行(具体启动步骤在后文"启动与验证"章节)。
1.3、Kafka 安装与配置
接下来在每台服务器上安装并配置 Apache Kafka 2.13-3.8.1。版本号中的"2.13"代表 Kafka 所使用的 Scala 版本。本指南选择 ZooKeeper 模式运行 Kafka(Kafka 3.x 仍支持 ZooKeeper 模式,而 Kafka 4.0 开始将完全移除对 ZooKeeper 的依赖,因此我们将通过正确配置来确保 Kafka 使用 ZooKeeper 而非 KRaft 模式。
-
下载 Kafka:从 Apache 官方网站下载 Kafka 2.13-3.8.1 二进制发行版。例如:
wget https://downloads.apache.org/kafka/3.8.1/kafka_2.13-3.8.1.tgz -P /opt
下载完成后,解压到
/opt
目录:tar -xzf /opt/kafka_2.13-3.8.1.tgz -C /opt/ mv /opt/kafka_2.13-3.8.1 /opt/kafka
将解压后的目录重命名为
/opt/kafka
以简化路径,并赋予kafka
用户权限:chown -R kafka:kafka /opt/kafka
请确保将 Kafka 安装目录复制到集群中的每一台 Kafka broker 节点上(或者在每台节点重复上述下载解压步骤),以保证所有节点使用相同版本的 Kafka。
-
编辑 Kafka 配置文件 :Kafka 的主配置文件为
config/server.properties
。在每台 Kafka 节点上,用文本编辑器打开/opt/kafka/config/server.properties
,根据集群规划修改以下关键配置项:-
broker.id(节点标识) :为每个 Kafka broker 设置一个唯一的整数 ID。默认配置中可能有
broker.id=0
,请确保不同节点不要重复。您可以为kafka1
,kafka2
,kafka3
分别设置,例如:broker.id=1
(第二台设置为2,第三台为3)。broker.id 必须是整数且在集群内唯一,用于标识不同的 broker。
-
log.dirs(日志存储目录) :指定 Kafka 存储分区日志的目录(即消息数据文件存放位置)。默认值是
/tmp/kafka-logs
(不适合生产环境,因为重启可能丢失数据)。建议设置为持久磁盘上的专用目录。例如:log.dirs=/opt/kafka/data
然后在系统上创建对应的目录并赋权:
mkdir -p /opt/kafka/data chown -R kafka:kafka /opt/kafka/data
确保每个 broker 有自己的数据存储路径。多个路径也可以用逗号分隔配置,以将数据分布在多个磁盘上。
-
zookeeper.connect(ZooKeeper 集群连接信息):配置 Kafka 集群要连接的 ZooKeeper 集群地址列表。填写之前部署的 3 个 ZooKeeper 实例的主机名:端口,端口一般为 2181。示例如下:
zookeeper.connect=kafka1:2181,kafka2:2181,kafka3:2181
这将使每个 Kafka broker 在启动时连接 ZooKeeper 集群以注册自身、进行元数据管理等 。请确保列出的主机名可以被各节点解析访问(必要时利用
/etc/hosts
)。注意 :使用 ZooKeeper 模式时,只需设置此项即可,无需配置任何 KRaft 模式的参数。请不要在配置中设置controller.quorum.voters
或process.roles
等 KRaft 专用参数,以免干扰 ZooKeeper 模式。 -
listeners(监听地址):指定 broker 对外提供服务的地址和协议。默认配置通常为:
listeners=PLAINTEXT://:9092
这表示在所有网络接口的 9092 端口监听 PLAINTEXT 明文协议。可以保留为 0.0.0.0 表示绑定本机所有 IP。如果希望明确指定网卡 IP 或主机名,也可以设置为例如
PLAINTEXT://kafka1:9092
(在每台机器上对应修改为各自的主机名/IP)。通常保持默认即可,但在多网卡环境下需要确保监听正确的网络。 -
advertised.listeners(通告地址) :如果 listeners 使用了0.0.0.0泛绑定,建议设置 advertised.listeners,让 broker 向外通告自己的访问地址。例如在
kafka1
节点上:advertised.listeners=PLAINTEXT://kafka1:9092
这样其他节点或客户端连接时,会使用
kafka1:9092
这个地址。对于kafka2
,kafka3
类似设置为各自的主机名:端口。注意:advertised.listeners 的主机名/IP 应是对其他节点和客户端可达的地址。 -
num.partitions(默认分区数):新创建主题的默认分区数量。Kafka 默认是1 。在多broker集群中,通常将其提高,以充分利用并行处理和数据分布。您可以根据需求设置一个较大的值,例如:
num.partitions=3
表示如果创建主题时未指定分区数,则默认创建3个分区。请注意,过多的分区也会增加开销,合理选择该值以平衡性能和管理成本。
-
默认副本相关配置(可选) :为了充分利用集群的多个 broker 提供容错能力,建议设置主题的默认副本因子 和最小同步副本等参数:
default.replication.factor=3 min.insync.replicas=2
以上配置表示:自动创建的主题默认会有3副本(在3台broker上各存一份);生产消息要求至少有2个副本是同步的才算成功(用于
acks=-1
的生产确认)。设置副本有助于防止单点故障导致数据丢失。若您的主题大多会手动创建并指定副本因子,此项也可视情况调整。 -
其他常见配置 :根据需要还可修改例如
message.max.bytes
(单条消息最大大小),delete.topic.enable
(是否允许删除主题,默认为 false,可考虑启用以便清理不需要的主题)等配置。但这些超出本次要求,可留用默认值或根据官方文档调整。
修改上述配置后,保存文件。请在每台 Kafka broker 节点上都进行相应的配置调整。其中
broker.id
和advertised.listeners
因节点而异,其余配置在所有节点应保持一致(除了日志目录路径可能因机器而异)。 -
-
确认 Kafka 配置模式 :确保每台 broker 的配置文件都包含了
zookeeper.connect
项,并且没有 配置任何 KRaft 模式专用的项。例如,不应存在诸如controller.quorum.voters
或controller.listener.names
等配置。如果意外存在,与 ZooKeeper 模式不符,需要注释或移除。Kafka 3.8.1 在检测到zookeeper.connect
配置时会以 ZooKeeper 模式启动 broker,将自身注册到 ZooKeeper。
完成 Kafka 的安装和配置后,下一步就是启动 ZooKeeper 集群和 Kafka 集群,并验证它们是否正常运行。
2、启动与验证集群
按照先 ZooKeeper、后 Kafka 的顺序启动整个集群,并进行基本的健康检查。
2.1.、启动 ZooKeeper 集群
首先在 每台 ZooKeeper 节点 上启动 ZooKeeper 服务。确保以前面创建的 kafka
用户执行启动命令(或使用 sudo -u kafka
切换用户):
在 kafka1
、kafka2
、kafka3
上分别执行:
/opt/zookeeper/bin/zkServer.sh start /opt/zookeeper/conf/zoo.cfg
该脚本会在后台启动 ZooKeeper 实例(如果需要前台模式调试,可将 start
换为 start-foreground
)。启动时请留意控制台输出或日志文件 /opt/zookeeper/zookeeper.out
,确认 ZooKeeper 各节点启动成功并彼此发现。
验证方法:可以在任意一台节点上运行 ZooKeeper自带的客户端脚本查看集群状态,例如:
/opt/zookeeper/bin/zkCli.sh -server kafka1:2181
进入交互界面后,输入命令 srvr
或 stat
,应能看到类似 mode: follower 或 mode: leader 的字样以及集群节点数等信息。如果集群成功组建,会有一个节点显示为leader,其余为followers,表示ZooKeeper集群正常运行。
2.2、启动 Kafka 集群
在 ZooKeeper 集群就绪后,依次在每台 Kafka broker 节点 上启动 Kafka 服务:
以 kafka
用户执行以下命令启动 Kafka(这里使用 -daemon
参数让进程在后台运行):
/opt/kafka/bin/kafka-server-start.sh -daemon /opt/kafka/config/server.properties
请在 kafka1
, kafka2
, kafka3
三台服务器上分别执行上述命令。Kafka broker 将读取各自的配置文件并尝试连接 ZooKeeper。由于我们在配置中设置了相同的 zookeeper.connect
,每个 broker 会注册到同一个 ZooKeeper 集群,从而组成 Kafka 集群的一部分 。
验证 Kafka 启动:Kafka 启动过程会在控制台和日志中输出大量信息。可以通过以下方式检查每个 broker 是否成功启动:
-
查看日志文件:Kafka 默认将日志输出到
logs
目录下(例如/opt/kafka/logs/server.log
)。检查该文件末尾是否有 "started (kafka.server.KafkaServer)" 等字样,或是否有错误。特别留意是否有与 ZooKeeper 连接相关的报错,如连接超时等。 -
使用 JPS 工具:因为 Kafka 是 Java进程,可运行
jps -l
,应看到一个kafka.Kafka
的进程。 -
命令行检查:尝试列出集群中的 broker 列表或主题列表。例如执行:
/opt/kafka/bin/kafka-broker-api-versions.sh --bootstrap-server kafka1:9092
该命令会尝试连接指定 broker 并输出其支持的API版本信息。如果 broker 正常运行并对外提供服务,该命令应返回版本列表而非报错。类似地,也可以尝试列出当前主题(预期刚启动时还没有创建任何主题):
/opt/kafka/bin/kafka-topics.sh --bootstrap-server kafka1:9092 --describe
若返回空列表或无权限之类的信息而非连接错误,说明 Kafka 集群基本联通。
Kafka broker 在启动时会通过 ZooKeeper 完成彼此的发现与协调,因此必须确保 ZooKeeper 先于 Kafka 启动并保持可用 。如果 Kafka 启动时 ZooKeeper 集群不可用,broker 将无法完成启动或及时注册。
到这里,Kafka 集群的各节点应该都已经启动并互相识别(默认情况下,一个 Kafka 集群中的 broker 数量等信息可以在 ZooKeeper 的 /brokers/ids
路径下查看)。下一步可以进行功能测试验证消息的生产和消费。
提示:在生产环境中,建议将 ZooKeeper 和 Kafka 配置为系统服务,以便更方便地管理启动/停止并在宕机后自动启动。详见下一章节的 systemd 服务配置。
配置 systemd 服务
为了便于运维,我们可以将 ZooKeeper和Kafka加入到 systemd 服务中。这允许使用 systemctl start/stop
命令管理,并可设置开机自启。以下是在 CentOS 系统上配置 ZooKeeper和Kafka的 systemd 单元文件的方法:
-
创建 ZooKeeper 的 systemd 服务文件 :以管理员权限在
/etc/systemd/system/
目录下新建文件zookeeper.service
,内容如下:[Unit] Description=Apache ZooKeeper Service After=network.target Wants=network.target [Service] Type=simple User=kafka ExecStart=/opt/zookeeper/bin/zkServer.sh start-foreground /opt/zookeeper/conf/zoo.cfg ExecStop=/opt/zookeeper/bin/zkServer.sh stop /opt/zookeeper/conf/zoo.cfg Restart=on-failure [Install] WantedBy=multi-user.target
说明:
-
[Unit]
部分指定服务信息和依赖关系。这里确保在网络就绪后启动 ZooKeeper。 -
[Service]
部分定义具体启动命令:使用我们安装目录下的zkServer.sh
脚本以前台模式启动 ZooKeeper,并指定配置文件路径。使用前台模式可以让进程附属在此 systemd 单元中。停止命令调用zkServer.sh stop
脚本。User=kafka
保证进程以我们创建的kafka
用户运行。Restart=on-failure
表示异常退出时自动重试启动。 -
[Install]
部分表明服务安装在多用户目标下,即正常启用。
-
-
创建 Kafka 的 systemd 服务文件 :新建文件
kafka.service
于/etc/systemd/system/
,内容如下:[Unit] Description=Apache Kafka Service After=zookeeper.service Requires=zookeeper.service [Service] Type=simple User=kafka ExecStart=/opt/kafka/bin/kafka-server-start.sh /opt/kafka/config/server.properties ExecStop=/opt/kafka/bin/kafka-server-stop.sh Restart=on-failure LimitNOFILE=100000 [Install] WantedBy=multi-user.target
说明:
-
在
[Unit]
中声明 Kafka 服务在 ZooKeeper 服务启动之后,并且需要 ZooKeeper 服务。这样可以确保在使用systemctl
启动 Kafka 时,ZooKeeper 会被自动拉起并先行启动。 -
[Service]
中,ExecStart 调用 Kafka 自带脚本启动 broker,指定配置文件路径。这里不使用-daemon
,因为由 systemd 管理前台进程。ExecStop 则调用 Kafka 的停止脚本优雅地关闭 broker。LimitNOFILE=100000
提高文件句柄限制(如前述,提高到至少 100k)以满足 Kafka 要求。 -
Requires=zookeeper.service
确保在启动 Kafka 时,若 ZooKeeper 未运行会被拉起;同时在停止 Kafka 时也会将 ZooKeeper 一并停止(因为是依赖关系)。如果不希望停止 Kafka 时影响 ZooKeeper,可将此改为Wants=zookeeper.service
。
-
-
加载并启动服务:保存上述两个文件后,运行命令令 systemd 重新加载配置:
sudo systemctl daemon-reload
然后设置服务开机自启:
sudo systemctl enable zookeeper.service sudo systemctl enable kafka.service
现在即可通过 systemd 启动或停止服务。例如,要启动整个 Kafka 集群,可以在每台机器上执行:
sudo systemctl start zookeeper.service sudo systemctl start kafka.service
或者简洁地:
sudo systemctl start kafka.service
(因为 Kafka 的单元文件声明了依赖,会自动启动 ZooKeeper)。
启动后,可通过
systemctl status kafka.service
和systemctl status zookeeper.service
查看服务状态,应显示 Active (running) 字样。如果需要重启所有节点,也可以使用systemctl restart kafka.service
等命令。这样配置后,服务器重启时 systemd 会自动按依赖顺序启动 ZooKeeper 和 Kafka,无需人工干预。
通过 systemd 管理服务,可以提高生产环境中集群运维的可靠性和一致性。在修改配置后,别忘了重新加载和重启相关服务使其生效。
3、测试消息生产与消费
最后,部署完成后我们使用 Kafka 自带的命令行工具测试消息的发送和接收,确保集群功能正常。
测试步骤:
-
创建测试主题 :在集群上创建一个示例主题,例如命名为 "
test
"。可以在任意一台 Kafka broker 节点上执行以下命令:/opt/kafka/bin/kafka-topics.sh --bootstrap-server kafka1:9092 \ --create --topic test --partitions 3 --replication-factor 3
该命令通过
kafka1:9092
broker连入集群,创建名为test
的主题,指定3个分区,3副本。成功时会输出 "Created topic test." 。可以再运行kafka-topics.sh --bootstrap-server kafka1:9092 --describe --topic test
查看主题配置,确认分区和副本分布。 -
启动消费者(Consumer):使用控制台消费者订阅刚创建的主题。在一台服务器上执行:
/opt/kafka/bin/kafka-console-consumer.sh --bootstrap-server kafka1:9092 \ --topic test --from-beginning
该命令将连接集群并订阅
test
主题的消息,从起始位置开始消费(--from-beginning
指定从头开始读取已有消息)。此时由于还没有消息,消费者会在终端等待新消息的到来。 -
生产消息(Producer):打开另一个终端,会话到任意一台 Kafka 节点(可以和上一步相同或不同的节点),启动控制台生产者发送消息:
/opt/kafka/bin/kafka-console-producer.sh --bootstrap-server kafka1:9092 --topic test
执行后,将进入一个交互模式,可以在终端输入消息并按 Enter 发送。例如输入:
Hello Kafka!
然后回车。每输入一行并回车,就作为一条消息发送到test
主题。 -
验证消费结果:查看第二步启动的消费者终端窗口,应该能看到刚才发送的消息打印出来:
Hello Kafka!
如此,即表示生产者发送的消息已经通过 Kafka 集群成功传递到消费者。如果连续发送多条消息,消费者都会按照发送顺序收到。这个简单的"Hello World"测试验证了Kafka集群的基本功能:消息能够在不同节点之间可靠地发布和订阅。
如果消费者没有收到消息,请检查以下几点:主题名称是否一致,消费者是否订阅到了正确的主题,--bootstrap-server
是否指定正确,以及集群中各 broker 的 advertised.listeners 配置是否让消费者能够访问。