kafka架构
kafka架构
一个kafka架构包括如下4部分:
- 若干个Producer,负责发生消息
- 一个kafka集群,包含若干个Broker,负责存储消息
- 若干个consumer group,每个consumer group包含一个或者多个consumer,负责消息消息
- 一个Zookeeper集群,负责管理集群配置及服务协同
kafka各个组件详解
Producer
Producer即消息生产者,负责发布消息到broker,是向broker推送消息的客户端。
一个消息会被发布到一个特定的topic(主题)上,producer默认会将消息均衡地分布到topic的patition(分区)上。
在发送一条消息时,可以指定这条消息的key,Producer会根据这个key和Partition机制来判断应该将这条消息发送到哪个Parition。
Producer发送消息并不时即时发送的,而是进行批量发送,通常会维护一个发送缓冲区,当缓冲区满了或者指定的发送周期到达了才会真正的向kafka集群发送消息
Broker
Broker即kafka集群中包含的服务器,一个单独的Kafka server就是一个Broker。
Broker的主要工作就是接受生产者发过来的消息,分配offset,之后保存到磁盘中,同时,接收消费者、其他Borker的请求,根据请求类型进行相应处理并返回响应。
kafka集群会选举其中一台服务器作为leader,leader负责管理分区的状态、管理每个分区的副本的状态、监听Zookeeper中数据的变化等工作。当Leader出现故障时则重新选举。
对于传统的消息队列而言,一般会删除已经被消费的消息,而kafka集群会保留所有的消息。
因为磁盘限制,集群是不可能永久保留所有消息,因此kafka提供了两种删除策略来删除数据:
- 基于时间,例如kafka删除2天或一周的数据
- 基于partition文件大小,例如在partition文件超过1GB时删除数据
Consumer Group
Consumer Group即消费者组,每个consumer group包含一个或者多个consumer,consumer从Topic中消费消息。
consumer在创建的时候会设置一个GroupID属性,通过GroupID来区分consumer属于哪一个Consumer Group。
consumer采取拉取模型(poll),由自己控制消费速度,以及消费的进度,消费者可以按照任意的偏移量进行消费。
consumer消费完成后需要向kafka集群进行commit(提交)操作,kafka集群根据consumer的提交来管理offset(位移),保证消费不重复。
每条消息只能被consumer group中的一个Consumer消费,但同一条消息可以被多个consumer group消费。
kafka保证的是稳定状态下每一个Consumer只会消费一个或多个特定partition数据,而某个partition的数据只会被某一特定的consumer实例消费。
具体哪个consumer消费哪个partition是随机分配的,且会根据consumer的增加和减少触发rebalance(分区重平衡)
同一个Consumer Group的consumer的数量只能小于或者等于patition数量,如果consumer大于patition数量则会有consumer无法消费数据,造成浪费。
zookeeper
Zookeeper集群在kafka整体架构中的主要作用是存储元数据,broker会在zookeeper注册并保持相关的元数据(topic,partition信息等)更新。
客户端会在zookeeper上注册相关的watcher。一旦zookeeper发生变化,客户端能及时感知并作出相应调整。这样就保证了添加或去除broker时,各broker间仍能自动实现负载均衡。
Zookeeper在Kafka中的作用有如下几方面
- Broker管理:记录每个Broker的ID和对应的信息(主要是host和IP)
- Topic管理:记录topic的名称,每个topic的patition数量和分布情况
- 生产者负载均衡:提供负责均衡算法帮助生产者需要将消息合理地发送到这些分布式的Broker上
- 消费者负载均衡: 负载均衡来实现多个消费者合理地从对应的Broker服务器上接收消息
- 消费者管理:记录消费者组和每个消费者组包含的数量和详细信息
- 消费Offset记录:记录每个分区上消费的offset情况
下图展示了Kafka在Zookeeper存储的信息的情况
需要注意的是kafka正在逐步弱化对应zookeeper的依赖,在较新版本的kafka中消费者的Offset记录以及不再存储在zookeeper中,但是其他重要的元数据还是存储在zookeeper中,所以kafka集群工作还是依赖zookeeper。