Kafka消息队列+zookeeper

前言

在分布式系统架构中,消息队列(Message Queue,MQ) 早已成为解耦、削峰、异步处理的核心组件。当业务无需立即获取结果,但需要控制并发、应对流量峰值、保证数据可靠传递时,消息队列就是最优解。

Kafka 作为 Apache 旗下顶级开源项目,凭借高吞吐量、低延迟、分布式、持久化、易扩展等特性,成为大数据领域、微服务架构中最主流的消息队列与流处理平台,广泛应用于日志收集、实时数据同步、流式计算、事件驱动架构等场景。


一、消息队列(MQ)

1. 什么是消息队列?

  • 消息(Message):应用间传递的数据单元,可简单(文本)可复杂(对象)。
  • 消息队列(Message Queue) :应用间异步通信框架,发送者只管发、接收者只管取,双方无需感知对方存在,由队列保证消息可靠存储与传递。

2. 消息队列三大核心特征

  1. 存储:消息会缓冲存储,直到被消费 / 主动删除,区别于传统 TCP/UDP 即时传输。
  2. 异步:发送方发完即走,接收方按需拉取,支持断网、服务故障下的容错运行。
  3. 路由:支持单播、广播,多进程可同时读写同一队列。

3. 为什么要用消息队列?(8 大核心优势)

  1. 解耦:上下游系统独立扩展 / 修改,仅需遵守统一接口。
  2. 冗余:消息持久化,避免数据丢失,确认处理完成才删除。
  3. 扩展:轻松增加消费节点,提升处理能力。
  4. 削峰填谷:顶住突发流量,防止系统崩溃。
  5. 可恢复:部分节点故障不影响整体,消息可恢复重处理。
  6. 顺序保证:保证消息按指定顺序处理(Kafka 单 Partition 内严格有序)。
  7. 缓冲:平衡生产与消费速度不一致问题。
  8. 异步通信:无需即时处理,延迟消费不影响业务。

二、Kafka 核心原理与基础概念

1. Kafka 官方定义

Kafka 是高吞吐量的分布式发布 / 订阅消息系统,支持实时处理海量数据,适配 Hadoop 分析、Storm/Spark 流式计算、低时延实时系统。

2. Kafka 核心术语

英文术语 中文释义 核心作用
Broker 代理节点 Kafka 集群服务器,负责消息存储 / 转发
Topic 主题 消息分类标识,类似消息文件夹
Producer 生产者 发送消息到 Broker
Consumer 消费者 从 Broker 拉取并消费消息
Partition 分区 Topic 物理分片,有序队列,每条消息带唯一 Offset(偏移量)
Consumer Group 消费者组 同一组内消费者互斥消费分区,不同组共享消息
Message 消息 通信基本单位

3. Kafka 拓扑架构

典型 Kafka 集群 = 若干 Producer + 若干 Broker + 若干 Consumer Group + ZooKeeper 集群

  • ZooKeeper:负责集群配置、Leader 选举、消费组重平衡。
  • Producer:Push(推) 消息到 Broker。
  • Consumer:Pull(拉) 消息,自主控制消费速率。
  • 核心规则:一个分区只允许同一消费组内一个消费者消费,保证顺序性。

4. Topic 与 Partition 深度解析

  • 一个 Topic 可拆分为多个 Partition,分散存储在不同 Broker。
  • 好处:突破单机磁盘限制、提升吞吐、负载均衡
  • 物理存储:每个 Partition 对应一个文件夹,包含 .index 索引文件 + .log 数据文件。
  • 建议:Partition 数量 ≥ 消费者数量,且 ≤ Broker 数量。

5. Producer 生产机制

生产者根据分区策略将消息分发到不同 Partition,实现负载均衡,并行写入提升吞吐。

6. Consumer 消费机制

  • 两种模式:
    1. 队列模式:一个消费组,一条消息仅被一个消费者消费。
    2. 发布 / 订阅模式:多个消费组,一条消息可被多组消费。
  • 优势:Pull 模式支持消费者批量拉取、自主控速

三、ZooKeeper 核心原理(Kafka 依赖组件)

1. ZooKeeper 是什么?

ZooKeeper 是分布式协调服务 ,解决分布式系统中多进程同步、共享资源竞争、脑裂(双主节点)问题,提供分布式锁、集群管理、配置同步等能力。

2. 核心作用

  • 解决单点故障:避免传统主备切换导致的双 Master 问题。
  • 集群选举:Master 故障自动切换,恢复后自动转为备用节点。

3. ZooKeeper 集群角色

  1. Leader(领导者):处理写请求、发起投票、更新系统状态。
  2. Follower(跟随者):处理读请求、参与投票选举。
  3. Observer(观察者) :同步状态、转发写请求,不参与投票,用于扩展集群。
  4. Client(客户端):发起请求。

4. ZooKeeper 写数据流程

  1. Client 连接 Server 发起写请求。
  2. Server 转发给 Leader。
  3. Leader 广播给所有 Follower。
  4. 多数节点写入成功,则确认写成功。
  5. Leader 响应 Client。

四、ZooKeeper 在 Kafka 中的 7 大核心作用

1. Broker 注册

  • 路径:/brokers/ids
  • Broker 启动创建临时节点,记录 IP / 端口,宕机自动删除。

2. Topic 注册

  • 路径:/brokers/topics
  • 维护 Topic 与 Partition、Broker 的对应关系。

3. 生产者负载均衡

  • 动态感知 Broker 上下线,实现消息均匀分发。

4. 消费者负载均衡

  • 消费组内消费者合理分配分区,避免重复消费 / 消息丢失。

5. 记录分区与消费者关系

  • 路径:/consumers/[group_id]/owners/[topic]/[partition]
  • 保证一个分区仅被同组一个消费者消费。

6. 记录消费进度 Offset

  • 路径:/consumers/[group_id]/offsets/[topic]/[partition]
  • 消费者重启后从断点继续消费。

7. 消费者注册与监听

  • 消费者启动注册节点,监听 Broker / 消费组变化,触发负载均衡。

五、Kafka 单机部署

1. 基础环境配置

bash

运行

复制代码
# 修改主机名
hostnamectl set-hostname kafka1
# 添加映射
echo '192.168.10.101 kafka1' >> /etc/hosts

2. 安装 JDK(ZooKeeper 依赖)

bash

运行

复制代码
yum -y install java

3. 安装并配置 ZooKeeper

bash

运行

复制代码
# 解压
tar zxvf apache-zookeeper-3.6.0-bin.tar.gz
mv apache-zookeeper-3.6.0-bin /etc/zookeeper
# 复制配置文件
cd /etc/zookeeper/conf
mv zoo_sample.cfg zoo.cfg
# 创建数据目录
mkdir -p /etc/zookeeper/zookeeper-data

配置 zoo.cfg

plaintext

复制代码
dataDir=/etc/zookeeper/zookeeper-data
clientPort=2181

bash

运行

复制代码
# 启动 ZooKeeper
cd /etc/zookeeper
./bin/zkServer.sh start
# 查看状态
./bin/zkServer.sh status

4. 安装并配置 Kafka

bash

运行

复制代码
# 解压
tar zxvf kafka_2.13-2.4.1.tgz
mv kafka_2.13-2.4.1 /etc/kafka
# 创建日志目录
mkdir -p /etc/kafka/kafka-logs

修改 server.properties

plaintext

复制代码
broker.id=0
listeners=PLAINTEXT://192.168.10.101:9092
log.dirs=/etc/kafka/kafka-logs
zookeeper.connect=192.168.10.101:2181

bash

运行

复制代码
# 后台启动 Kafka
nohup ./bin/kafka-server-start.sh config/server.properties &
# 验证端口
netstat -anpt | grep 2181
netstat -anpt | grep 9092

5. Kafka 单机测试

bash

运行

复制代码
# 修复脚本警告
sed -i 's/egrep/grep -E/' bin/kafka-run-class.sh

# 创建 Topic
bin/kafka-topics.sh --create --zookeeper kafka1:2181 --replication-factor 1 --partitions 1 --topic test

# 查看 Topic 列表
bin/kafka-topics.sh --list --zookeeper kafka1:2181

# 查看 Topic 详情
bin/kafka-topics.sh --describe --zookeeper kafka1:2181 --topic test

# 生产消息
bin/kafka-console-producer.sh --broker-list kafka1:9092 --topic test

# 消费消息(新终端)
bin/kafka-console-consumer.sh --bootstrap-server kafka1:9092 --topic test --from-beginning

# 删除 Topic
bin/kafka-topics.sh --delete --zookeeper kafka1:2181 --topic test

六、Kafka 集群部署(3 节点)

1. 集群资源规划

IP 主机名 角色
192.168.10.101 kafka1 ZooKeeper+Kafka
192.168.10.102 kafka2 ZooKeeper+Kafka
192.168.10.103 kafka3 ZooKeeper+Kafka

2. 基础环境(所有节点执行)

bash

运行

复制代码
# 关闭防火墙
systemctl stop firewalld
setenforce 0

# 添加主机映射
cat >> /etc/hosts << EOF
192.168.10.101 kafka1
192.168.10.102 kafka2
192.168.10.103 kafka3
EOF

3. ZooKeeper 集群配置

  1. 安装 JDK+ZooKeeper(同单机)
  2. 配置 zoo.cfg(所有节点一致)

plaintext

复制代码
dataDir=/etc/zookeeper/zookeeper-data
clientPort=2181
server.1=192.168.10.101:2888:3888
server.2=192.168.10.102:2888:3888
server.3=192.168.10.103:2888:3888
  1. 配置 myid(每个节点唯一)

bash

运行

复制代码
# kafka1
echo '1' > /etc/zookeeper/zookeeper-data/myid
# kafka2
echo '2' > /etc/zookeeper/zookeeper-data/myid
# kafka3
echo '3' > /etc/zookeeper/zookeeper-data/myid
  1. 启动所有节点 ZooKeeper

bash

运行

复制代码
./bin/zkServer.sh start
./bin/zkServer.sh status

4. Kafka 集群配置

修改 server.properties(每个节点差异化)

  • kafka1:

plaintext

复制代码
broker.id=1
listeners=PLAINTEXT://192.168.10.101:9092
log.dirs=/etc/kafka/kafka-logs
zookeeper.connect=192.168.10.101:2181,192.168.10.102:2181,192.168.10.103:2181
  • kafka2:broker.id=2,IP 改为 192.168.10.102
  • kafka3:broker.id=3,IP 改为 192.168.10.103

bash

运行

复制代码
# 启动 Kafka
nohup ./bin/kafka-server-start.sh config/server.properties &

5. 集群验证

bash

运行

复制代码
# 任意节点创建 Topic(副本数 2,分区 3)
bin/kafka-topics.sh --create --zookeeper kafka1:2181 --replication-factor 2 --partitions 3 --topic cluster-test

# 所有节点查看 Topic
bin/kafka-topics.sh --list --zookeeper kafka1:2181

# 生产/消费测试
bin/kafka-console-producer.sh --broker-list kafka1:9092,kafka2:9092,kafka3:9092 --topic cluster-test
bin/kafka-console-consumer.sh --bootstrap-server kafka1:9092,kafka2:9092,kafka3:9092 --topic cluster-test --from-beginning

七、补充知识点

1. Kafka 高吞吐核心原因

  • 顺序写磁盘:避免随机 IO,机械盘也能高性能。
  • 页缓存:利用操作系统缓存,减少磁盘 IO。
  • 批量发送 / 压缩:Producer 批量发送,支持 Gzip/Snappy 压缩。
  • 零拷贝:减少内核态与用户态数据拷贝。

2. Kafka 高可用机制

  • 副本机制:每个 Partition 设多个副本,分布在不同 Broker。
  • Leader 故障:ZooKeeper 自动从 Follower 选举新 Leader。
  • ISR 机制:保持同步的副本集合,仅 ISR 内节点可被选举为 Leader。

3. 消费组重平衡(Rebalance)

触发条件:

  • 消费者上线 / 下线
  • Topic 分区增减
  • Broker 上下线作用:重新分配分区与消费者对应关系,保证负载均衡。

4. Kafka 消息丢失 / 重复消费解决方案

  • 消息丢失 :设置 acks=all(所有副本确认写入)、开启重试、手动提交 Offset。
  • 重复消费 :业务端做幂等性(如唯一 ID 去重)。

5. Kafka 常用运维命令

bash

运行

复制代码
# 修改分区数
bin/kafka-topics.sh --alter --zookeeper kafka1:2181 --topic test --partitions 5

# 查看消费组列表
bin/kafka-consumer-groups.sh --bootstrap-server kafka1:9092 --list

# 查看消费组偏移量
bin/kafka-consumer-groups.sh --bootstrap-server kafka1:9092 --describe --group test-group
相关推荐
炸炸鱼.2 小时前
Zookeeper + Kafka 消息队列集群部署手册
zookeeper·kafka
卢傢蕊2 小时前
Kafka 消息队列
分布式·kafka·java-zookeeper
lhbian16 小时前
PHP、C++和C语言对比:哪个更适合你?
android·数据库·spring boot·mysql·kafka
Jackyzhe18 小时前
从零学习Kafka:认证机制
分布式·学习·kafka
lhbian19 小时前
PHP vs Java vs Go:编程语言终极对比
java·spring boot·后端·kafka·linq
AutoMQ20 小时前
别再每月浪费数千美元:拆解 AWS/GCP Kafka 背后的隐性账单
kafka·消息队列·aws
Devin~Y1 天前
大厂Java面试实战:Spring Boot/WebFlux、Redis+Kafka、K8s可观测性与Spring AI RAG/Agent三轮连环问
java·spring boot·redis·kafka·kubernetes·resilience4j·spring webflux
indexsunny1 天前
互联网大厂Java求职面试实战:Spring Boot与微服务架构解析
java·spring boot·redis·kafka·spring security·flyway·microservices
ldj20201 天前
kafka如何合理分配消费者数量和分区数量
kafka