文章目录
-
- 1:kafka架构设计
-
- 1.1:架构设计
- 1.2:kafka内部的通信协议
- 1.3:kafka元数据
- 2:kafka源码结构介绍
-
- 2.1:源码结构
- 2.2:broker核心源码core 模块介绍
-
1:kafka架构设计
1.1:架构设计
Kafka集群中生产者将消息发送给以Topic命名的消息队列Queue中,消费者订阅发往以某个Topic命名的消息队列Queue中的消息。其中Kafka集群由若干个Broker组成,Topic由若干个Partition组成,每个Partition里的消息通过Offset来获取。
基本组成包括:
- Broker:一台Kafka服务器就是一个Broker,一个集群由多个Broker组成,一个Broker可以容纳多个Topic,Broker和Broker之间没有Master和Standby的概念,他们之间地位是平等的
- Topic:每条发送到Kafka集群的消息都属于某个主题,这个主题就称为Topic。物理上不同Topic的消息分开存储,逻辑上一个Topic的消息虽然保存在一个或多个Broker上,但是用户只需指定消息主题Topic即可生产或消费数据而不需要关心数据存放在何处。
- Partition:为了实现可扩展性,一个非常大的Topic可以被分为多个Partition,从而分布到多台Broker上。Partition中的每条消息都会被分配一个自增Id(Offset)。Kafka只保证按照一个Partition中的顺序将消息发送给消费者,但是不保证单个Topic中多个Partition之间的顺序。
- Offset:消息在Topic的Partition中的位置,同一个Partition中的消息随着消息的写入其对应的Offset也自增。
- Replica:副本,Topic的Partition有N个副本,N为副本因子。其中一个Replica为Leader,其他都为Follower,Leader处理Partition的所有读写请求,Follower定期同步Leader上的数据。
- Message:消息是通信的基本单位。每个Producer可以向一个Topic发布消息
- Producer:消息生产者,将消息发布到指定的Topic中,也能够决定消息所属的Partition:比如基于Round-Robin或者Hash算法
- Consumer:消息消费者,向指定的Topic获取消息,根据指定Topic的分区索引及其对应分区上的消息偏移量来获取消息
Consumer Group:消费者组,每个消费者都属于一个组。当消费者具有相同组时,消息会在消费者之间负载均衡。一个Partition的消息只会被相同消费者组中的某个消费者消费。不同消费者组是相互独立的。
- Zookeeper:存放Kafka集群相关元数据的组件。Zookeeper集群中保存了Topic的状态信息,例如分区个数、分区组成、分区的分布情况等;保存Broker的状态信息;保存消费者的消费信息等。通过这些信息,Kafka很好地将消息生产、消息存储、消息消费的过程结合起来。

1.2:kafka内部的通信协议
Kafka内部各个Broker之间的角色并不是完全相等的,Broker内部负责管理分区和副本状态以及异常情况下分区的重新分片等这些功能的模块称为KafkaController。每个Kafka集群中有且只有一个Leader状态的KafkaController,当其出现异常时,其余Standby状态的KafkaController会通过Zookeeper选举出有一个Leader状态的KafkaController。
维度一:通信协议详情
- ProducerRequest:生产者发送消息的请求,生产者将消息发送至Kafka集群中的某个Broker,Broker接收到此请求后持久化此消息并更新相关元数据信息。
- ProducerRequest.requiredAcks的取值为0时,生产者不关心Broker Server端持久化执行结果,但是高级消费者发送的提交偏移量的请求还是需要返回具体执行结果。为1则生产者消费者都需要将Broker Server端持久化的执行结果返回客户端。为-1时,不会立刻返回Broker Server端消息持久化的结果,而是需要等待Partition的ISR列表中的Replica完成数据同步,并且ISR列表的个数大于min.insync.replicas时才会将响应返回给对应客户端。这里采用的是称为Purgatory的策略。Broker Server上对应的Partition的HighWatermark发生改变才触发检查。
- TopicMetadataRequest:获取Topic元数据信息的请求,无论是生产者还是消费者都需要通过此请求来获取感兴趣的Topic的元数据。
- FetchRequest:消费者获取Topic的某个分区的消息的请求。分区状态为Follower的副本也需要利用此请求去同步分区状态为Leader的对应副本数据。
- OffsetRequest:消费者发送至Kafka集群来获取感兴趣Topic的分区偏移量的请求,通过此请求可以获知当前Topic所有分区在不同时间段的偏移量详情。
- OffsetCommitRequest:消费者提交Topic被消费的分区偏移量信息至Broker,Broker接收到此请求后持久化相关偏移量信息。
- OffsetFetchRequest:消费者发送获取提交至Kafka集群的相关Topic被消费详细信息,和OffsetCommitRequest相互对应。
- LeaderAndIsrRequest:当Topic的某个分区状态发送变化时,处于Leader状态的KafkaController发送至相关Broker通知其做出相应处理。
当某个Replica称为Leader:暂停Fetch→添加进Assigned Replica列表→添加进In-Sync Replica列表→删除已经不存在的Assigned Replica→初始化Leader Replica的HighWatermark
当某个Replica成为Follower:暂停旧的Fetch线程→截断数据至HighWatermark以下→开启新的Fetch线程→添加进Assigned Replica列表→删除已经不存在的Assigned Replica
- StopReplicaRequest:当Topic的某个分区被删除或者下线的时候,处于Leader状态KafkaController发送至相关Broker通知其做出相应处理。
- UpdateMetadataRequest:当Topic的元数据信息发生变化时,处于Leader状态的KafkaController发送至相关Broker通知其做出相应处理。
- BrokerControllerShutdownRequest:当Broker正常下线时,发送此请求到处于Leader状态的KafkaController。
- ConsumerMetadataRequest:获取保存特定Consumer Group消费详情的分区信息
通信协议交互
- Producer和Kafka集群:Producer需要利用ProducerRequest和TopicMetadataRequest来完成Topic元数据的查询、消息的发送。
- Consumer和Kafka集群:Consumer需要利用TopicMetadataRequest请求、FetchRequest请求、OffsetRequest、OffsetCommitRequest、OffsetFetchRequest、ConsumerMetadataRequest来完成Topic元数据的查询、消息的订阅、历史偏移量的查询、偏移量的提交、当前偏移量的查询。
- KafkaController状态为Leader的Broker和KafkaController状态为Standby的Broker:Leader需要用LeaderAndIsrRequest、StopReplicaRequest、UpdateMetadataRequest来完成对Topic的管理。Standby需要利用BrokerControllerShutdownRequest来通知Leader自己的下线动作。
- Broker和Broker之间:Broker相互之间需要利用FetchRequest请求来同步Topic分区的副本数据,这样才能使Topic分区各副本数据保持一致。
1.3:kafka元数据
Kafka 集群的元数据都定义了哪些内容呢?我用一张图给你完整地展示一下,当前 Kafka 定义的所有集群元数据信息。

所有定义的元数据都由kafka.controller.ControllerContext进行实现
2:kafka源码结构介绍
2.1:源码结构
bin: 各种执行脚本;
clients:生产者和消费者代码;1.x版本是java语言开发;
config: 运行所需的所有配置文件,包括broker,producer,consumer;
core : kafka服务实例(broker)的代码,scala语言开发,实现了集群管理,分区副本管理,消息存储和消息获取,网络通信等功能;
admin包:执行管理命令的功能;
api 包: 封装请求和响应DTO对象;
cluster包:集群对象,例如Replica 类代表一个分区副本,Partition类代表一个分区;
common包: 通用jar包;
controller包: 和kafkaController(kc)相关的类,重点模块,一个kafka集群只有一个leader kc,该kc负责 分区管理,副本管理,并保证集群信息在集群中同步;
coordinator包:组协调者相关,负责处理消费者组的代码;
log包: 磁盘存储相关,重点模块;
network包: 网络相关,重点模块,使用的是NIO,从这里可学习如何应用java 的NIO类;
consumer包,producer好多废弃类,无需关注;
server包: kafka实例的各种管理类,核心包,也是重点;
tools 工具类。
docs:kakfa文档
examples:生产者消费者demo 启动脚本;
streams:kafka 流相关代码;
2.2:broker核心源码core 模块介绍
broker启动流程源码以及涉及的主要core中的模块如下

1:KafkaServer模块
KafkaServer表示单个Kafka代理的生命周期。
start.sh启动脚本最终调用包装类:kafkaserver类,其包括kafka各个模块细节的调用,处理所有需要的功能,启动和关闭单个Kafka节点。
kafkaserver类介绍
startup:用于启动Kafka服务器的单个实例的API。
shutdown:关闭服务器
initZK:初始化ZK
broker中各个模块间关系

requestChannel实现socketserver和kafkaApis间的解耦
逻辑分析:socketserver监听到我们的客户端请求--------》转发给kafkaApis逻辑实现代码-------》调度响应模块处理
broker启动主要模块介绍
-
1:socketserver:监听9092端口的socket读写请求。首先开启一个Acceptor线程,新的Socket连接成功建立时会将对应的SocketChannel以轮询方式转发给N个Processor线程中的某一个,由其处理接下来SocketChannel的请求,将请求放置在RequestChannel中的请求队列;当Processor线程监听到SocketChannel请求的响应时,会将响应从RequestChannel中的响应队列中取出来并发给客户端
-
2:KafkaRequesThandlePool:从socketserver获取客户端请求然后调用 KafkaApis实现业务逻辑处理,将响应结果返回给requestChannel,再给客户端。
-
3:OffsetManager:偏移量管理模块。对偏移量的保存和读取,offset保存分zk和kafka两种地方,由参数offsets.storage=zookeeper/kafka决定。kafka保存到名为consumer_offsets的topic中。
-
4:TopicConfigManager:topic的配置信息管理模块,副本数等
-
5:KafkaApis:kafka的业务逻辑实现层。各种request的实现类,通过match-case匹配请求类型调用实现逻辑。
-
6:KafkaController:kafka的集群管理模块。通过在zk上注册节点达到监听
-
7:KafkaScheduler:kafka的后台定时任务调度的资源池。主要为logmanager,ReplicaManager,OffsetManager提供资源调度。
-
8:ReplicaManager:副本管理。包括有关副本的Leader和ISR的状态变化、副本的删除、副本的监测等。
-
9:KafkaHealthCheck:集群健康检查,brokers/ids下的节点id进行检测
-
10:logmanager:日志管理模块。脏数据,过期数据删除等,负责提供Broker Server上Topic的分区数据读取和写入功能。
-
11:initZkClient:启动zookeeper模块,管理kafka的元数据