一、前言
在开始之前首先要明确一点,kafka是一个分布式流平台,本质上是一个消息队列。谈到消息队列,就会联想到消息队列的三大作用:异步、消峰、解耦。kafka主要应用在大数据的实时处理领域,使用起来比较简单,本文主要分析kafka的工作流程、存储机制,分区策略,并围绕多个角度展开总结。
但是要注意的是,随着时代的巨轮驶向2020,目前kafka已经不是一家独大了,Pulsar作为一个天生支持多租户、跨地域复制、统一消息模型的消息平台,已经在不少企业成功的替代了Kafka。关于Apache Pulsar的更多知识,感兴趣的可以关注我,后面会对它进行总结和深入。
在kafka的设计之初,考虑到了生产者生产的消息不断追加到log文件末尾后导致log文件过大的情况,所以采用了分片和索引机制,具体来说就是将每个partition分为多个segment。每个segment对应三个文件:.index 文件、.log 文件、.timeindex 文件(早期版本中没有)。其中**.log和.index**文件位于一个文件夹下,该文件夹的命名规则为:topic名称+分区序号。例如,csdn这个topic有2个分区,则其对应的文件夹为csdn-0,csdn-1;
如果我们打开csdn-0这个文件夹,会看到里面的文件如下:
00000000000000000000.index
00000000000000000000.log
00000000000000150320.index
00000000000000150320.log
通过这个文件夹下有两个log,我们可以得出结论,这个partition有2个segment。
文件命名规则:partition全局的第一个segment从0开始,后续每个segment文件名为上一个segment文件最后一条消息的offset值,数值大小为64位,20位数字字符长度,没有数字用0填充。
注意:index 文件并不是从0开始,也不是每次递增1的,这是因为 Kafka 采取稀疏索引存储的方式,每隔一定字节的数据建立一条索引,它减少了索引文件大小,使得能够把 index 映射到内存,降低了查询时的磁盘 IO 开销,同时也并没有给查询带来太多的时间消耗。
下面引用一张旧的kafka存储机制图,不带.timeindex 文件:
index文件和log文件的关系:“.index”文件存储大量的索引信息,“.log”文件存储大量的数据,索引文件中的元数据指向对应数据文件中message的物理偏移地址。
因为每一个segment文件名为上一个 Segment 最后一条消息的 offset ,所以当需要查找一个指定 offset 的 message 时,通过在所有 segment 的文件名中进行二分查找就能找到它归属的 segment ,再在其 index 文件中找到其对应到文件上的物理位置,就能拿出该 message 。
举例:这里我们以查找offset为6的message为例,查找流程如下:
在了解分区策略之前需要先了解为什么要分区,可以从两方面来解释这个问题:
首先要知道producer发送的数据其实需要封装成一个ProducerRecord对象才可以,我们看ProducerRecord提供的方法如下:
通过这个构造方法,我们知道kafka分区策略有如下3种:
四、总结
通过本文,我们探讨了kafka的工作流程、存储机制,分区策略,相信已经理清楚了生产者生产的数据是怎么存储的以及怎么根据offset去查询数据这类问题。
来源:https://blog.csdn.net/qq_26803795/article/details/109265052