在Kafka中,使⽤⼀个类别属性来划分消息的所属类,划分消息的这个类称为topictopic相当于消 息的分类标签,是⼀个逻辑概念,我来为大家科普一下关于kafka基础知识整理?下面希望有你要的答案,我们一起来看看吧!
kafka基础知识整理
基本术语Topic——主题在Kafka中,使⽤⼀个类别属性来划分消息的所属类,划分消息的这个类称为topic。topic相当于消 息的分类标签,是⼀个逻辑概念
Partition——分区topic中的消息被分割为⼀个或多个partition,其是⼀个物理概念,对应到系统上就是⼀个或若⼲个⽬录。Kafka分配的单位是partition。每个Partition是⼀个FIFO队列,其中的消息是有序的。但Partition之间的顺序是⽆序的。
segment——段kafka又将partition进⼀步细分为了若⼲的segment,每个segment⽂件的最⼤⼤⼩相等。
Broker——kafka服务器Kafka集群中的每⼀台服务器就是一个Broker
Producer——生产者Producer负责将消息发送到Kafka集群的某⼀个topic中。同时Producer发送消息时能够指定partition号,从⽽将消息持久化到特定的partition中。
Consumer——消费者消息消费者,⼀个消费者可以消费多个topic的消息,⼀个消费者也可以消费同⼀个topic中的多个partition中的消息
Consumer group——消费组consumer group是kafka提供的可扩展且具有容错性的消费者机制。组内可以有多个消费者,它们 共享⼀个公共的ID,即group ID。
offset——偏移量Consumer消费消息时,通过指定的offset来定位下⼀条要读取的消息。值得注意的是,offset的 维护是由Consumer全权控制的。 (注意:kafka的相关术语还有很多,本文只列出比较重要的几个)
简单图解工作原理启动Broker要想使用kafka,必须先启动,当每个broker启动时,会在ZooKeeper中的/brokers/ids 路径下创建⼀个节点来注册⾃⼰,节点ID为配置⽂件中的broker.id参数
zookeeper注册controller启动kafka集群后,ZooKeeper中创建 /controller 临时节点节点并注册⾃⼰的信息,先注册上的broker就是 controller,controller除了是⼀个普通的 broker 之外,还是集群的总扛把⼦,它负责副本 leader 的选举、 topic 的创建和删除、副本的迁移、副本数的增加、broker 上下线的管理等等。
消息路由策略消息生产者Producer生产消息,发送消息到broker,会打到哪个分区呢?其实是有三种消息路由策略:
- 指定分区partition,则直接写入到指定的分区partition
ProducerRecord record = new ProducerRecord<>("cities", 0, 1, "tianjin");
- 指定key,则通过对key的hash值与partition数量取模,则该取模结果就是要发送的partition索引
ProducerRecord record2 = new ProducerRecord<>("cities", 0, "tianjin");
- 若partition和key都未指定,则使⽤轮训策略选出⼀个partition
ProducerRecord record3 = new ProducerRecord<>("cities", "tianjin");
Kafka中提供了多重分区分配算法(PartitionAssignor)的实现: RangeAssignor,RoundRobinAssignor,StickyAssignor三种,PartitionAssignor接⼝⽤于⽤户定义实现分区分配算法,以实现Consumer之间的分区分配。Kafka默认采⽤RangeAssignor的分配算法。
RangeAssignorRangeAssignor策略的原理是按照消费者总数和分区总数进⾏整除运算来获得⼀个跨度,然 后将分区按照跨度进⾏平均分配,以保证分区尽可能均匀地分配给所有的消费者。对于每⼀个 Topic,RangeAssignor策略会将消费组内所有订阅这个Topic的消费者按照名称的字典序排序,然 后为每个消费者划分固定的分区范围,如果不够平均分配,那么字典序靠前的消费者会被多分配 ⼀个分区。
这种分配⽅式明显的⼀个问题是随着消费者订阅的Topic的数量的增加,不均衡的问题会越来 越严重,⽐如上图中4个分区3个消费者的场景,C0会多分配⼀个分区。如果此时再订阅⼀个分区 数为4的Topic,那么C0⼜会⽐C1、C2多分配⼀个分区,这样C0总共就⽐C1、C2多分配两个分区 了,⽽且随着Topic的增加,这个情况会越来越严重。
RoundRobinAssignorRoundRobinAssignor的分配策略是将消费组内订阅的所有Topic的分区及所有消费者进⾏排序后尽 量均衡的分配(RangeAssignor是针对单个Topic的分区进⾏排序分配的)。如果消费组内,消费者订阅 的Topic列表是相同的(每个消费者都订阅了相同的Topic),那么分配结果是尽量均衡的(消费者之间 分配到的分区数的差值不会超过1)。
StickyAssignor尽管RoundRobinAssignor已经在RangeAssignor上做了⼀些优化来更均衡的分配分区,但是在⼀些情况下依旧会产⽣严重的分配偏差。所以又有了StickyAssignor,分区的分配尽量的均衡,每⼀次重分配的结果尽量与上⼀次分配结果保持⼀致。
消息写入算法消息⽣产者将消息发送给broker,并形成最终的可供消费者消费的log,是⼀个⽐较复杂的过程。
- producer向broker集群提交连接请求,其所连接上的任意broker都会向其发送broker controller的 通信URL,即broker controller主机配置⽂件中的listeners地址
- 当producer指定了要⽣产消息的topic后,其会向broker controller发送请求,请求当前topic中所有 partition的leader列表地址
- broker controller在接收到请求后,会从zk中查找到指定topic的所有partition的leader,并返回 给producer
- producer在接收到leader列表地址后,根据消息路由策略找到当前要发送消息所要发送的partition leader,然后将消息发送给该leader
- leader将消息写⼊本地log,并通知ISR中的followers
- ISR中的followers从leader中同步消息后向leader发送ACK
- leader收到所有ISR中的followers的ACK后,增加HW,表示消费者已经可以消费到该位置了
- 若leader在等待的followers的ACK超时了,发现还有follower没有发送ACK,则会将该follower从ISR 中清除,然后增加HW。
⽣产者将消息发送到topic中,消费者即可对其进⾏消费,其消费过程如下:
- consumer向broker集群提交连接请求,其所连接上的任意broker都会向其发送broker controller的 通信URL,即broker controller主机配置⽂件中的listeners地址
- 当consumer指定了要消费的topic后,其会向broker controller发送poll请求
- broker controller会为consumer分配⼀个或⼏个partition leader,并将该partitioin的当前offset发 送给consumer
- consumer会按照broker controller分配的partition对其中的消息进⾏消费
- 当消费者消费完该条消息后,消费者会向broker发送⼀个该消息已被消费的反馈,即该消息的 offset
- 当broker接到消费者的offset后,会更新到相应的__consumer_offset中
- 以上过程⼀直重复,直到消费者停⽌请求消息
- 消费者可以重置offset,从⽽可以灵活消费存储在broker上的消息
至此,kafka的大致的工作原理已经介绍完了。 需要交流学习可以关注公众号【温故知新之java】,互相学习,一起进步。
,