- Kafka概述
是一个分布式的基于发布订阅模式的消息队列
2.Kafka几个角色
Broker: 每一个kafka进程实例
Topic:用来对消息进行分类
Partition: 分区,用于对某个topic做发送的负载均衡
Leader:生产者和消费者对某一个topic实际发送和消费的来源
Follower:对某一个topic做冗余备份
Producer:消息生产者
Consumer:消息消费者
Topic-》分区-》 分区副本
一个topic可以通过负载均衡到不同的partition-leader中。每个partition-leader又可以有自己的分区副本partition-follower
Consumergroup-》consumer-》分区
一个消费者组里面可以有多个消费者,每个消费者对同一个topic的不同partition-leader进行消费。但是不同消费者组里面的不同消费者可以对同一个topic的不同partition-leader进行消费
Consumergroup可以做消费者消费的负载均衡
Zk: 用来管理 kafka集群的元数据信息,以及保存消费进度(跟kafka版本有关系,0.9之前是存在在zk中。0.9之后存在 kafka本地(topic- counsumer-offsets)的系统topic中)
3.消息的有序性
由于分区的存在,每个topic下的所有分区都各自维护了自己的offset。Kafka无法保证topic的全局的有序性,只能保证区内的有序性
4.Kafka的文件存储
.Index 和 .log
.Index 存储偏移量及在.log文件中的偏移量,消息长度
.log 存储topic某一个分区下的所有消息,a和消息的偏移量
kafka文件的命名方式,是以当前第一条消息的起始偏移量进行命名的。这样做是方便消费者拉取消息的时候快速定位到消息所在的index文件。
5.kafka消费者是如何找到需要消费的消息?
消费者通过偏移量和二分查找法找到消息所在的index文件,在index文件中找到对应的在log文件中的偏移量。 当找到偏移量后 去log文件获取消息内容
6.生产者的分区策略
类似于rocketmq的生产者发送负载均衡算法
7.Kafka的ack机制,通过生产者acks参数进行配置
0:producer只管发送数据就返回ack,broker挂了或者发送时由于网络的原因会导致数据丢失
1: leader落盘后发送ack给发送者,发送ack前,leader挂了会导致数据丢失
-1: leader和ISR 中的follower都落盘后发送ack给发送者,如果在发送ack前,leader挂了,会导致数据重复
8.Kafka集群数据一致性,hw和leo
每个副本的 高水位和 最大偏移量
在同一个分区内,取分区内所有副本中最大偏移量最小的那个偏移量作为高水位,因此同一个分区内的所有副本的高水位都是相同的。 高水位之前的数据是消费者可见的数据
9.exactly once语义
精准一次性的将消息发送到kafka集群,保证不出现数据丢失和数据重复的情况
当ack为0时,可以保证消息最多发送一次
当ack为-1是,可以保证消息至少发送一次,数据不会丢失
精准一致性 = 至少一次 + 幂等性
Kafka通过分配给producer的pid ,发送消息的partition,每条消息携带的seqnum,来对重复消息进行去重。 kafka不能保证跨会话或者跨分区的幂等性
10.消费者的分区策略
Round robin:按同一消费者组中的所有消费者订阅的所有主题的分区进行分配分区
问题:当消费者组中的消费者消费了不同的主题,会发生有一些分区没办法进行正常的消费数据
Range(kafka默认): 按同一消费者组中的消费者订阅的某一个主题的分区进行分配分区
问题:会出现消费不均衡
当消费者数目发生变化,会触发分区重分配
11.消费者的offset的存储
Consumergroup + topic + partition来确定消费者的消费进度,即使这个分区被该消费者组下的新的消费者进行消费也可以拿到上一个消费者消费的offset
消费者每隔1s提交offset到系统主题中__consumer_offset
12.kafka高效读写数据
顺序写磁盘,零拷贝技术,分布式
13.Kafka的事务
生产者事务:
Pid只能保证单分区和单会话的精准一次性。要实现跨会话和分区的精准一次性就需要用到生产者事务。那么什么是生产者事务呢?
生产者客户端将消息携带上Transaction id 和 pid绑定,交由 kafka的transaction coordinator进行维护
消费者事务:
Kafka的消费者事务较弱。因为消费者是通过offset进行消费的
14.Kafka的再均衡
再均衡是指当分区的所属消费者个数发生变更的时候,再均衡发生期间,消费者无法拉取消息。即使当消费者个数大于分区数的时候,消费者个数发生变化了还是会出发再均衡
15.Kafka的ISR,同步副本
Kafka没有采取半数同步的机制(半数同步机制在允许N个节点挂掉时候,需要有2n+1个节点,最后才能保证有1个点是已经被同步过的)。kafka采取了全数同步的机制(这个会有点问题,当进行ack的时候,有一个节点挂掉了,那么这个时候就永远不可以完成ack了),因此kafka并且做了一些优化,也就是ISR,每一个分区都会有一个ISR,里面存放的是该分区的同步的副本。之后数据的同步,以及leader的选举都是在ISR中进行的
16.Kafka的故障处理
hw和leo。 hw保证消费的一致性和分区副本存储的一致性。
消费的一致性:超过hw的不可以被消费。假设如果超过hw的可以被进行消费,那么由于ISR中的leo会有可能不同,当leader出现故障了,由于已消费的offset>新leader的leo,导致后续消费者无法再进行消费。
存储的一致性:当ISR的leader节点发生故障的时候,为了保证副本之间的一致性,选举的新的leader会让follower高出自己的进行截断,如果follower高出了hw也进行截断,保证了新的ISR中各副本数据的一致性
因此hw只能保证副本之间的数据一致性,不能保证数据不丢失或者不丢失,数据是否丢失应该由ack机制来保证。
17.分区策略
RoundRobin:针对消费者组里消费者订阅的所有主题来分,当消费者组里的消费者订阅了不同的主题就会有可能导致错分。所以使用这种方式约定,消费者组里的消费者订阅的主题需要相同
Range:默认,按照主题的分区按范围来分给消费者组中的消费者
补充分区分配策略的举例:(2020-10-21)
两个topic,每个topic10个分区:
topic1: A1 A2 A3 A4 A5 A6 A7 A8 A9 A10
topic2: B1 B2 B3 B4 B5 B6 B7 B8 B9 B10
消费者三个,都订阅了topic1、topic2:
C1
C2
C3
range:
C1: A1 A2 A3 A4 B1 B2 B3 B4
C2: A5 A6 A7 B5 B6 B7
C3: A8 A9 A10 B7 B8 B9 B10
roundrobin:
C1: A1 A4 A7 A10 B3 B6 B9
C2: A2 A5 A8 B1 B4 B7 B10
C3: A3 A6 A9 B2 B5 B8
sticky:
目标:分配的更均匀, 再均衡时会尽量避免消费者的分区出现变化
如果订阅和topic是均匀的,那么分配的结果和roundrobin是一致