我们知道 Kafka 写数据很快,是因为先写内存,将数据写入 PageCache页缓存,然后再由操作系统将页缓存的数据同步到磁盘。所以 Kafka 写数据很快。那么 Kafka 读数据为什么也很快呢?
Step1: 消费者根据 Topic、Partition、Offset 提交给 Kafka请求读取数据;
Step2: Kafka 根据元数据信息,找到对应的这个分区的Leader副本节点;
消费者在消费数据的过程中,我们称为读数据。消费者消费数据的时候,是必须指定分区进行消费。首先,消费者会根据 Topic、Partition、offset 来提交给 Kafka,告诉 Kafka 我要消费哪个 Topic 的哪个分区的哪个offset。Kafka 根据元数据信息,找到这个分区对应的 Leader 节点,这里与写入数据一样。
Step3: 请求 Leader 副本所在的Broker,先读 PageCache,通过零拷贝机制【Zero Copy】读取 PageCache
· 先读内存,如果当前 offset 还在内存中,就使用零拷贝机制读取内存【零拷贝即消费者直接拿到内存的数据,中间没有经过任何的拷贝】
· 如果生产者生产的速度和消费者消费的速度相匹配:生产者一生产就立即被消费者消费
Step4: 如果 PageCache 中没有,读取 Segment 文件段,先根据 offset 找到要读取的那个 Segment
· 根据 offset 和文件名找到最近偏小的那个文件
Step5: 将.log文件对应的.index 文件加载到内存中,根据 .index 中的索引的信息找到 offset 在.log文件中的最近物理偏移量
· Kafka 中的索引:稀疏索引【不是每条数据都有索引。数据量越大,稀疏索引的优点越明显】
优点:(1)索引文件较小,加载到内存的速度更快;(2)加快索引的检索效率。
缺点:只能定位一定的范围,可能不能精准地找到某个 offset 对应的数据。
场景:数据量非常大的情况下
· Step6: 读取.log,根据索引找到对应的offset的数据,读取连续的一个批次的数据。
小结:Kafka 数据的读取过程:先读内存,基于零拷贝机制实现读取,Segment 以及索引读取设计
相关参考资料阅读:
https://zhuanlan.zhihu.com/p/183808742
网友评论