架构总览:Kafka集群角色、Broker、Producer、Consumer、Zookeeper依赖、整体数据流

好,咱们正式开始聊Kafka的架构。很多初学者一上来就盯着API怎么调,结果出了问题根本不知道从哪排查。我个人习惯,学任何中间件,先把它整个骨架摸清楚。今天我们就来拆解Kafka集群里的几个核心角色,以及它们之间怎么配合。

Kafka集群里都有谁?

一个典型的Kafka集群,说白了就这几类角色:Broker、Producer、Consumer,外加一个Zookeeper(或者新版里的KRaft)。它们各司其职,缺一不可。

核心角色速览

  • Broker:集群里的服务器节点,负责存数据、处理读写请求。
  • Producer:生产者,把消息发到Broker。
  • Consumer:消费者,从Broker拉取消息。
  • Zookeeper:集群的“管家”,负责元数据管理和选主。

你想想看,如果没有Zookeeper,Broker之间怎么知道谁活着谁挂了?Producer又该把数据发给谁?所以这个依赖关系,咱们得先理清楚。

Broker:集群的“数据节点”

Broker是Kafka最基础的单元。每个Broker就是一个Java进程,跑在一台机器上。我刚开始接触Kafka时,以为Broker越多越好,结果发现节点多了,网络开销反而成了瓶颈。

Broker的核心职责有三点:

  • 存储数据:消息以分区(Partition)为单位,落盘到磁盘。
  • 处理请求:响应Producer的写入和Consumer的拉取。
  • 副本同步:Leader分区负责读写,Follower分区从Leader同步数据。

这里有个关键点:一个Broker上可以同时有多个分区的Leader和Follower。比如Broker A上,分区0是Leader,分区1是Follower。这样设计是为了负载均衡,避免某个Broker被打满。

Producer:消息的“发件人”

Producer不直接跟某个Broker硬编码通信。它先跟集群要一份元数据,知道“主题A的分区0在Broker 1上”,然后才把消息发过去。

我在项目中遇到过一个问题:Producer把acks设成了0,结果丢了一批订单消息,排查了半天才发现是配置问题。所以这里我建议你记住三种确认级别:

acks值 含义 可靠性 性能
0 发完就算成功,不等待确认 最低 最高
1 Leader确认收到就算成功 中等 中等
all 所有ISR副本都确认才算成功 最高 最低

避坑指南:我曾经把acks设成all,但没调大timeout.ms,结果频繁超时重试,反而把集群打挂了。acks=all一定要配合合理的超时和重试策略。

Consumer:消息的“收件人”

Consumer从Broker拉取数据,而不是Broker推给Consumer。这个设计很巧妙——Consumer自己控制消费速度,不会把自身压垮。

Consumer以消费者组(Consumer Group)为单位工作。同一个组内的Consumer共同消费一个主题,每个分区只能被组内的一个Consumer消费。举个例子:主题有4个分区,你的消费者组有3个实例,那就有1个Consumer会消费2个分区,另外两个各消费1个。

注意:如果消费者组里的实例数超过了分区数,多出来的实例会闲置。我曾经见过有人开了20个Consumer实例,但主题只有5个分区,白白浪费了15个线程的资源。

Zookeeper依赖:集群的“大脑”

老版本的Kafka重度依赖Zookeeper。Zookeeper负责以下几件事:

  • Broker注册与发现:Broker启动时在Zookeeper上创建临时节点,挂了节点自动消失。
  • Leader选举:当分区Leader挂了,Zookeeper协调选出新的Leader。
  • 元数据存储:主题、分区、副本的分配信息都存在Zookeeper里。

但Zookeeper也有短板——它不适合高吞吐的元数据变更。所以从Kafka 2.8开始,社区推出了KRaft模式,去掉了Zookeeper依赖。不过目前生产环境里,Zookeeper模式仍然占主流。我个人建议,如果你是新项目,可以考虑KRaft;如果是老集群迁移,别急着动,先稳定跑着。

整体数据流:一条消息的旅程

好了,角色都认识了,咱们串起来看看一条消息从产生到消费,到底经历了什么。

Producer --> Broker (Leader Partition) --> Follower Partition (同步) --> Consumer

具体步骤是这样的:

  1. Producer向集群请求元数据,找到目标分区的Leader Broker。
  2. Producer把消息发给Leader Broker。
  3. Leader将消息写入本地日志,同时Follower从Leader拉取数据同步。
  4. 当满足acks条件后,Leader向Producer返回确认。
  5. Consumer从Leader拉取消息,更新自己的偏移量(Offset)。

嗯,这里要注意:Consumer只能从Leader分区读数据,不能从Follower读。这是Kafka的设计决策——保证数据一致性。不过在新版本里,Consumer可以从Follower读的配置已经出来了,但默认还是走Leader。

架构总览图

下面这张图把整个数据流和角色关系画出来了。你可以对照着看,会更直观。

Kafka 集群架构总览 Producer Zookeeper Broker 集群 Broker 1 分区0 (Leader) Broker 2 分区0 (Follower) Broker 3 分区0 (Follower) Consumer Consumer 发送消息 元数据/选主 同步 拉取消息 说明 1. Producer 只写 Leader 2. Follower 从 Leader 同步 3. Consumer 只读 Leader 4. Zookeeper 管元数据

从图上可以清楚看到:Producer只跟Leader分区交互,Follower默默从Leader拉数据。Consumer也只从Leader读。Zookeeper在背后管着元数据和选主,不参与数据路径。这样设计的好处是——数据路径简单,性能瓶颈容易定位。

小结一下

这一章我们把Kafka集群的骨架搭起来了。Broker是存数据的,Producer是写数据的,Consumer是读数据的,Zookeeper是管集群的。数据流就是一条直线:Producer → Leader Broker → Follower Broker(同步)→ Consumer。没有复杂的弯弯绕绕。

嗯,记住这个架构图,后面讲分区、副本、一致性的时候,你脑子里就有这张图打底了。