Kafka 一文到底
说明:以下内容为个人学习kafka的笔记整理,已发布在了掘金,现也在CSDN也做一份分享发布,如果对读者有些帮助那就再好不过了。图片有一部分是自己画的,有一部分来自于百度图片,若有侵袭,请留言,我会删除。内容上若有不完善的地方,欢迎读者留言指出,笔者会尽快勘正,谢谢!
kafka是什么?
kafka是分布式的、高并发的、基于发布/订阅模式的消息队列软件系统。
kafka是一个基于发布/订阅模式的消息队列
kafka对外使用topic的概念,生产者往topic里写消息,消费者组的消费者从topic里读消息。
-
生产者向kafka集群PUSH消息,消费者组用长链接从kafka集PULL消息。
-
kafka集群具有持久化消息的能力
-
消费者以消费者组的方式存在,同一个topicA的消息消费最多只会被整个消费者组消费一次。
kafka是一个高并发的基于发布/订阅模式的消息队列
为了提高某个topic的负载能力,kafka的一个topic是由多个分区(Partition)组成。生产者根据一定的规则向多个分区PUSH数据,消费者组的多个消费者可以同时消费不同分区里的消息。
-
消费者组保证一个topic的每一个分区都有消费者进行消费。
-
生产者尽量均匀地向一个topic的每一个分区PUSH消息。
-
kafka保证了同一个主题的区内有序,不保证主题的全局有序性。
kafka是 分布式的、高并发的、基于发布/订阅模式的消息队列软件系统。
为保证可用性,kafka的每一个分区都能配置N个副本。副本分为Leader副本和Follower副本,Follower仅负责从Leader复制数据,Leader负责所有的读写请求。kafka集群实际存储的是副本。
-
Kafka集群的每一个单机为一个Broker。Broker 会向 zookeeper 发送心跳请求来上报自己的状态。zookeeper 维护了一个正在运行并且属于集群的 broker 列表。
-
Kafka集群中的多个broker会有一个broker被选举为控制器(Kafka Controller),它负责管理整个集群中所有分区和副本的状态:当某个分区的leader副本出现故障时,由控制器负责为该分区选举新的leader副本
-
主题分区副本在broker的分配原则:每个Broker都有均等分配分区Leader的机会,同个分区的副本不能落到同一台机器上!具体规则:
- 将所有N Broker和待分配的i个Partition排序。
- 将第i个Partition分配到第(i mod n)个Broker上。
- 将第i个Partition的第j个副本分配到第((i + j) mod n)个Broker。
所以kafka是
Kafka是一个分布式、分区的、多副本的、多订阅者,基于zookeeper协调的分布式MQ系统。
生产者与kafka集群
生产者分区选择策略
- 轮询:消费者依次向每一个分区发送数据
- 随机:消费者随机向某一个分区发送数据
- 散列:消费者按照消息键的hashcode%分区数,向指定分区发送数据
- 自定义分区选择策略:生产者实现kafka提供的PartitionAssignor接口,自定义分区选择策略。
为提高发送效率,生产者通常将多条消息打包PUSH到kafka集群。
分区何时返回给生产者ACK?副本同步机制!
分区的Leader副本负责读写,Leader副本收到来着生产者的消息并写入本地的同时,也会将消息发给对应的Follower副本,Follower写入本地后返回给Leader ACK,Leader收到一定数量的Follower的ACK以后再返回给生产者ACK表示消息已写入Kafka集群。kafka的副本同步不是完全同步,也不是完全异步,而是一种ISR机制。
kafka的ISR机制
leader会维护一个与其基本保持同步的Replica列表,该列表称为ISR(in-sync Replica),每个Partition都会有一个ISR,而且是由leader动态维护。
-
如果一个Follower超过一定时间未发起数据复制请求,则leader将其从ISR中移除。
-
如果一个Follower的消息偏移量追赶上Leader的同步消息偏移量,则leader将其放入ISR中。
Leader收到ISR里的全部Follower的ACK以后再向发送者回复ACK。
若主从数据没有完全同步完,Leader挂掉,会不会丢失数据?主从一致性问题!
-
LEO:每一个副本的最后一个偏移量
-
HW:所有副本中最小的LEO
HW之后的数据对消费者不可见,当leader挂掉以后,就从ISR里选举一个新的leader。之后,为保证多个副本之间的数据一致性,其余的Follower都会将各自消息文件高于hw的部分截掉,然后从新的leader同步数据。
若kafka集群没有及时回复ACK,生产者重复发送消息怎么办?
-
精准一次性=重复数据(至少一次)+ 幂等性
-
幂等性:无论调用者发送多少次消息,服务端都只处理一次。
kafka集群会给开启幂等性的生产者在初始化的时候会分配一个PID。生产者发往同一个分区(Partition)的每一个消息会附带上一个序列号(SeqNumber)。Broker端会对<PID,Partition,SeqNumber>做缓存,当具有相同序列号的消息提交时,Broker只会持久化一条消息。
但生产者的PID在重启以后会变化,同时不同的分区也具有不同序列号,所以幂等性无法保证跨分区跨会话的精准一次性。
kafka集群与消费者
消费者为何选择从kafka集群PULL消息
- Push模式:很难适应消费速率不同的消费者,因为消费发送速率是由broker决定的。它的目标是尽可能以最快的速度传递消息,这样很容易造成consumer来不及消费消息。
- Pull模式: 如果kafka没有数据,消费者会陷入循环中,一直返回空数据。可以传入一个timeout参数,如果没有数据可供消费consumer就等待一段时间之后再返回。
Push模式和Pull模式都有各自的优势和缺点,相较之下,Kafka选择了Pull模式,以提高整个集群的消费能力
消费者消费哪个分区?消费分区分配策略!
需保证两个原则:所有的分区的消息都有消费者进行消费,不可能出现同一个消费者组的多个个消费者负责同一个分区。
- RoundRobin轮询:将消费组内所有消费者以及消费者所订阅的所有topic的partition按照字典序排序,然后通过轮询方式逐个将分区以此分配给每个消费者。
- Range范围:将消费者总数和分区总数进行整除运算来获得一个跨度,然后将分区按照跨度进行平均分配,以保证分区尽可能均匀地分配给所有的消费者。
以上内容图片均来自于百度图片,侵删!!!