1 Kafka发送消息格式
一个 Kafka的Message由一个固定长度的 header和一个变长的消息体 body组成
• header部分由一个字节的 magic(文件格式 )和四个字节的 CRC32(用于判断 body消息体是否正常 )构成。当 magic 的值为 1的时候,会在 magic 和crc32之间多一个字节的数据:attributesattributesattributes (保存一些相关属性,比如是否压缩、格式等 );如果 magic 的值为 0,那么不存在 attributes属性。
• body是由 N个字节构成的一个消息体,包含了具体key/value消息 注意:每个版本的 Kafka消息格式是不一样的 。
2 kafka Log消息格式
存储在磁盘的日志采用不同于Producer发送的消息格式,每个日志文件都是一个"log entries"序列,每一个log entry包含一个四字节整型数(message长度,值为1+4+N),一个字节的magic,四个字节的CRC32位值,最终是N个字节的消息数据。每条消息都有一个当前Partition下唯一的64位offset,指定该消息的起始下标位置。这个“log entries”并非 由一个文件构成,而是分成多个segment file(日志文件,存储具体的消息记录)和一个索引文件(存储每个segment文件的offset偏移量范围)。结构如右图所示:
3 Kafka消息存储机制
一个Topic分为多个Paritition来进行数据管理,一个Partition中的数据是有序的、不可变的,使用偏移量(offset)唯一标识一条数据,是一个long类型的数据。
Partition接收到producer发送过来的数据后,会产生一个递增的offset偏移量数据,同时将数据保存到本地的磁盘文件中(也就是说kafka的数据是落盘的)。Partition中是数据存活时间超过参数值(log.retention.{ms,minutes,hours},默认是7天)的时候会进行删除。
Consumer根据offset消费对应Topic的Partition中的数据(也就是每个Consumer消费帆软每个Topic的Partition都有自己的offset偏移量)。
一个Topic中的所有数据分布式的存储在Kafka集群的所有机器(broker)上,以分区(partition)的形式进行数据存储,每个分区允许存在备份数据/备份分区(存储在同一Kafka集群的其他broker上的分区)。
每个数据分区在kafka集群中存在一个broker节点上的分区叫做leader,存储在其它broker上的备份分区叫做follower。只有leader节点负责该分区的数据读写操作,follower节点作为leader节点的热备节点,从leader节点备份数据,当leader节点挂掉的时候,会有follower节点中有一个变成leader节点,重新提供服务。kafka集群的Partition的leader和follower切换依赖zookeeper。
4 kafka消息产生/收集机制
Kafka集群中由producer负责数据的产生,并发送到对应的topic,producer通过push的方式将数据发送到对应topic的分区。
producer发送到topic的数据是由key/value键值对组成的,kafka根据key的不同的值决定发送到不同的partition,默认采用Hash的机制发送数据到对应topic的不同partition中,配置参数为{partitioner.class}
Producer 发送数据的方式分为 sync(同步 )和async (异步 )两种,默认为同步方式由 参数 {producer.type} 决定;当发送模式为异步的时候,Producer提供重试机制, 默认失败重试发送 3次。同步发送即消息产生就发送,异步发送是指并不是消息一产生就发送,而是等过一定的时间或者一定的消息数量再一起发送。
5 Kafka消息消费机制
Kafka有两种模式消费数据:队列 和发布订阅 ;在队列模式下,一条数据只会发 送给 customer group中的一个 customer 进行消费;在发布订阅模式下,一条数据会发送给多个 customer进行消费。
Kafka的Customer基于 offset对kafka中的数据进行消费,对于一个 customer group中 的所有 customer共享一个 offset偏移量。
Kafka中通过控制 Customer的参数 {group.id}来决定 kafka是什么数据消费模式,如 果所有消费者的该参数值是相同,那么此时kafka就是类似于队列模式,数据只会发送到一个 customer,此时类似于负载均衡,否则就是订阅分布模式。
Kafka的数据是按照分区进行排序(插入的顺序 ),也就是每个分区中的数据有序的,但是多个分区之间做不到全局有序。在 Consumer进行数据消费的时候, 也是对分区有序但是不保证所有数据的序性 (多个分区之间 )。
Consumer Rebalance:当一个 consumer group组中的消费者数量和对应 Topic 的分区数量一致的时候,此时一个Consumer消费一个 Partition的数据;如果不一致, 那么可能出现一个 Consumer消费多个 Partition的数据或者不消费情况,这 个机制是根据 Consumer和Partition的数量动态变化。
6 Kafka中的Replication副本
Kafka的Replication指的是Partition的复制,一个 Partition的所有分区中只一个区是 leader节点,其它分区是 follower节点。只有leader节点负责该分区的数据读写操作,follower节点作为leader节点的热备节点,从leader节点备份数据,当leader节点挂掉的时候,会有follower节点中有一个变成leader节点,重新提供服务。Replication对Kafka的吞吐率由一定的影响,但是极大的增强了可用性。
Follower节点会定时的从leader节点上获取增量数据,一个活跃的 follower节点必须满足以下两个条件:
所有的节点必须维护和 zookeeper连接 (通过zk 的heartbeat 实现 )
follower必须能够及时的将leader上的 writing复制过来,不能 “落后太多 ”落后太多”由参数 {replica.lag.time.max.ms} {replica.lag.time.max.ms} 决定。
7 Kafka的Leader选举
Kafka提供了一个 in -sync replicas(ISR)来确保 Kafka的Leader Leader选举,ISR 是一个保存分区node的集合,如果一个 node宕机了或数据 “落后太多 ”,leader会将该 node节点 从ISR 中移除,只有 ISR 中的 follower节点才有可能成为 leader节点,这样可以避免数据落后太多的follower节点成为leader,事实上,成为leader的follower节点必须和leader数据同步。
Leader节点的切换基于 Zookeepe的Watcher机制,当 leader节点宕机的时候,其他 ISR 中的 follower节点会竞争的在 zk 中创建一个文件目录 (只会有一个 follower节点创建成功 ),创建成功的 followerf节点成为 leader节点。
8 消息分发语义
Message delivery semantics是消息系统中数据传输的可靠性保证一个定义,主要分为三 种类型:
At most once(最多一次):消息可能会丢失,但是不重复发送
At least once(最少一次):消息不可能丢失,但是重复发送
Exactly once(仅一次):消息只发送,但不存在丢失 Kafka的Producer
通过参数 {request.required.acks}来定义Producer和Broker之间是哪种消息传递类型 。
Kafka的数据是分区存储,每个分区中的数据按照进入kafka的时间进行排序 。