kafka 核心概念
message:Kafka 中的数据单元被称为消息,也被称为记录,可以把它看作数据库表中某一行的记录
Message由offset来表示它在这个partition中的偏移量,这个offset不是该Message在partition数据文件中的实际存储位置,而是逻辑上一个值,它唯一确定了partition中的一条Message
message 中存储信息:offset,messageSize,data。其中offset为long型,MessageSize为int32,表示data有多大,data为message的具体内容。
实际物理结构:
magic:1个字节。魔数标识,与消息格式有关,取值为0或1。当magic为0时,消息的offset使用绝对offset且消息格式中没有timestamp部分;当magic为1时,消息的offset使用相对offset且消息格式中存在timestamp部分
attributes:1个字节。0~2位表示消息使用的压缩类型,0(000)->无压缩 1(001)->gzip 压缩 2(010)->snappy 压缩 3(011)-> lz4 压缩。第3位表示时间戳类型,0->创建时间 1->追加时间。
timestamp:8个字节,时间戳
批次:一组消息
主题:消息的种类被称为topic
分区:主题可以被分为若干个分区(partition),每个分区中包含多个segment文件,同一个主题中的分区可以不在一个机器上,有可能会部署在多个机器上,由此来实现 kafka 的伸缩性,单一主题中的分区有序,但是无法保证主题中所有的分区有序。
consumeGroup:消费者群组,由一组消费者构成
offset :Offset记录着下一条将要发送给Consumer的消息的序号,分为Current Offset和Committed Offset。
Current Offset保存在Consumer客户端中,它表示Consumer希望收到的下一条消息的序号。它仅仅在poll()方法中使用。Committed Offset保存在Broker上,它表示Consumer已经确认消费过的消息的序号。主要通过commitSync和commitAsync
API来操作。用于Consumer Rebalance过程的,它能够保证新的Consumer能够从正确的位置开始消费一个partition,从而避免重复消费。
producer :生产者是推送消息给一个或多个Kafka主题的发布者。
consumer :消费者是从broker中拉取topic消息
broker: 一个独立的 Kafka 服务器就被称为 broker,broker 接收来自生产者的消息,为消息设置偏移量,并提交消息到磁盘保存
broker 集群:broker 是集群 的组成部分,broker 集群由一个或多个 broker 组成,每个集群都有一个 broker 同时充当了集群控制器的角色(自动从集群的活跃成员中选举出来)
副本:Kafka 中消息的备份又叫做 副本(Replica),副本的数量是可以配置的,Kafka 定义了两类副本:领导者副本(Leader Replica) 和 追随者副本(Follower Replica),前者对外提供服务,后者只是被动跟随。
Follower跟随Leader,所有写请求都通过Leader路由,数据变更会广播给所有Follower,Follower与Leader保持数据同步。如果Leader失效,则从Follower中选举出一个新的Leader。当Follower与Leader挂掉、卡住或者同步太慢,leader会把这个follower从“in sync replicas”(ISR)列表中删除,重新创建一个Follower。
重平衡:Rebalance。消费者组内某个消费者实例挂掉后,其他消费者实例自动重新分配订阅主题分区的过程。Rebalance 是 Kafka 消费者端实现高可用的重要手段。
消息队列的介绍:
消息传递通常由两种模式,queuing(队列)和publish-subscribe (发布-订阅)
queuing:每个Consumer从消息队列中取走一个消息
pub-sub:消息被广播到每个Consumer
Kafka通过提供了一个对Consumer的抽象来同时实现这两种模式-ConsumerGroup。Consumer实例需要给自己指定一个ConsumerGroup的名字,如果所有的实例都用同一个ConsumerGroup名字,那么这些Consumer就会以queuing的模式工作;如果所有的实例分别用的不同的ConsumerGroup名字,那么它们就以public-subscribe模式工作。
(group的概念只针对于客户端,如果有多个客户端定义了多个组时,broker会以pub-scrib的形式将消息发送到每一个group上)
如下图所示:含两台server的集群一共有p0~p3四个Partition,两个Consumer Group,在Group内部是以queuing的模式消费Partition,在Group之间是以pub-scrib模式消费。
pub-sub 工作流程
-
生产者定期向主题发送消息。
-
Kafka broker存储为该特定主题配置的分区中的所有消息。 它确保消息在分区之间平等共享。 如果生产者发送两个消息并且有两个分区,Kafka将在第一分区中存储一个消息,在第二分区中存储第二消息。
-
消费者订阅特定topic。
-
一旦消费者订阅主题,Kafka将向消费者提供主题的当前偏移,并且还将偏移保存在Zookeeper中。
-
消费者将定期请求Kafka(如100 Ms)新消息。
-
一旦Kafka收到来自生产者的消息,它将这些消息转发给消费者。
-
消费者将收到消息并进行处理。
-
一旦消息被处理,消费者将向broker发送确认。
-
一旦Kafka收到确认,它将偏移更改为新值,并在Zookeeper中更新它。 由于偏移在Zookeeper中维护,消费者可以正确地读取下一封邮件,即使在服务器暴力期间。
-
以上流程将重复,直到消费者停止请求。
-
消费者可以随时回退/跳到所需的主题偏移量,并阅读所有后续消息
在用户组中:
一旦新消费者到达,Kafka将其操作切换到共享模式,并在两个消费者之间共享数据。 此共享将继续,直到用户数达到为该特定主题配置的分区数。
一旦消费者的数量超过分区的数量,新消费者将不会接收任何进一步的消息,直到现有消费者取消订阅任何一个消费者。 出现这种情况是因为Kafka中的每个消费者将被分配至少一个分区,并且一旦所有分区被分配给现有消费者,新消费者将必须等待。
kafka 消息发送过程
1.ProducerRecord 是 Kafka 中的一个核心类,它代表了一组 Kafka 需要发送的 key/value 键值对,它由记录要发送到的主题名称(Topic Name),可选的分区号(Partition Number)以及可选的键值对构成
2.在发送 ProducerRecord 时,我们需要将键值对对象由序列化器转换为字节数组,这样它们才能够在网络上传输。然后消息到达了分区器。
3.如果发送过程中指定了有效的分区号,那么在发送记录时将使用该分区。如果发送过程中未指定分区,则将使用key 的 hash 函数映射指定一个分区。如果发送的过程中既没有分区号也没有,则将以循环的方式分配一个分区。选好分区后,生产者就知道向哪个主题和分区发送数据了。
4.ProducerRecord 还有关联的时间戳,如果用户没有提供时间戳,那么生产者将会在记录中使用当前的时间作为时间戳。Kafka 最终使用的时间戳取决于 topic 主题配置的时间戳类型。
如果将主题配置为使用 CreateTime,则生产者记录中的时间戳将由 broker 使用。如果将主题配置为使用LogAppendTime,则生产者记录中的时间戳在将消息添加到其日志中时,将由 broker 重写。然后,这条消息被存放在一个记录批次里,这个批次里的所有消息会被发送到相同的主题和分区上。由一个独立的线程负责把它们发到 Kafka Broker 上。
5.Kafka Broker 在收到消息时会返回一个响,如果写入成功,会返回一个 RecordMetaData 对象,它包含了主题和分区信息,以及记录在分区里的偏移量,上面两种的时间戳类型也会返回给用户。如果写入失败,会返回一个错误。生产者在收到错误之后会尝试重新发送消息,几次之后如果还是失败的话,就返回错误消息。
KafKa 面试题
kafka的message包括哪些信息?
参考链接:
https://baijiahao.baidu.com/s?id=1651919282506404758&wfr=spider&for=pc
https://www.w3cschool.cn/apache_kafka/apache_kafka_workflow.ht