kafka的offset理解

kafka的offset理解

    • kafka的offset理解
    • zero copy
    • 分区数据存储
    • isr与数据同步

kafka的offset理解

kafka是顺序读写,具备很好的吞吐量。实现原理是
每次生产消息时,都是往对应partition的文件中追加写入,而消息的被读取状态是由consumer来维护的
所以每个partition中offset一般都是连续递增的(如果开启了压缩,因为对旧数据的merge会导致不连续)
被读取的消息并不会删除,所以每次都是追加写入顺序读写,具备很好的吞吐量。
这也是为什么说kafka的broker是无状态的,整个过程中伴随由zookeeper的协调参与,一般是不同broker存储了不同partition或副本数据,当存在多个副本时,从那个broker读取数据时由zookeeper决定的,一般会由一台kafka作为leader(被读取),如果该kafka不可用时,zookeeper切换到别的broker,因为broker在zookeeper上维护一个 /broker/ids/{id}的临时节点,如果kafka不可用,该节点也会被删除,kafka集群会根据该节点的信息,切换被读取的kafka
实现过程是 consumer在消费消息后,向broker中有个专门维护每个consumer的offset的topic生产一条消息,记录自己当前已读的消息的offset+1的值作为新的offset的消息。当然在旧版本的实现是在zookeeper上有个节点存放这个offset,当时后面考虑性能问题,kafka改到了topic里,同时可以自由配置使用zookeeper还是使用topic,以下是刚刚各个情况在zookeeper上的展示
kafka的offset理解_第1张图片
而在kafka存放topic数据的目录中,存有一个我们创建的test主题的目类(因为没有别的分区,所以是分区0),以及存放__consumer_offsets的50个分区目录
kafka的offset理解_第2张图片
每次consumer消费消息时,kafka都会根据该topic下对于该consumer记录的offset,传递对应消息,当offset不存在时,根据auto.offset.reset配置的值,会有几种不同策略

earliest
无指定的offset时,从头开始消费

latest
无提交的offset时,消费该分区下最新产生的消息

none
topic不存在指定的offset,则抛出异常

zero copy

kafka之所以使用了文件存储还可以有这么高的吞吐量得益于他利用了操作系统的零拷贝技术,主要是利用Channel的transferTo方法
普通IO模式下(read,write),实际经过四次的文件内容复制

1、将磁盘文件数据,copy到操作系统内核缓冲区;
2、将内核缓冲区的数据,copy到应用程序的buffer;
3、将应用程序buffer中的数据,copy到socket发送缓冲区(属于操作系统内核);
4、将socket buffer的数据,copy到网卡,由网卡进行网络传输。

而在零拷贝技术下,只有两步

1.将磁盘文件数据读取到操作系统内核缓冲区
2.将内核缓冲区数据copy到网卡,由网卡进行网络传输

分区数据存储

kafka的分区数据在磁盘上划分为多个segment,每个segment由索引文件和数据文件两个文件组成。每个segment文件根据设定的配置,最多存储相同大小的消息。每一个segment的文件都以自己文件里存储的第一消息的上一个offset作为文件名(第一个文件使用0作为开始,后续每个文件名为上一个文件的最后一个offset),基于这个设计,可以更加灵活的分片存储以及快速查找(通过二分查找快速找到文件名的offset)

isr与数据同步

kafka将不同分区放到不同broker上,其中一台作为leader,其他为isr或者不在isr中(被踢出去集群,等待重新加入),kafka的leader负责来写消息,isr的其他成员异步的去同步这些消息,在isr中的成员都同步成功时,这条消息对于消费端不可见(内部通过为每台broker设置一个HW代表消费端所能读取到的最大的下一个offset,leader接收了消息后,会先判断isr中成员的offset,如果不是最大+1代表isr中有成员还没有接收到这条消息,则不会更改hw,而在isr每台机器每次通信都会对比isr的offset,当leader发现isr每台机器的offset比自己都大1,代表可以更新hw了,此时leader才会把这个消息变为可见,并把更新hw的消息发送给isr中的follower,而至于如果有follower出现宕机的,因为会直接被剔除出isr,所以最坏情况下也会将所有follower都剔除,而只对自己更新hw,其他broker在重新加入集群后再同步消息)

更多文章,请搜索公众号歪歪梯Club
更多资料,请搜索公众号编程宝可梦

你可能感兴趣的:(消息中间件)