【Kafka从入门到放弃系列 三】Kafka架构深入——工作流程和存储机制

简介: 【Kafka从入门到放弃系列 三】Kafka架构深入——工作流程和存储机制

上一篇blog亲手搭建了一个kafka的分布式集群【Kafka从入门到放弃系列 二】Kafka集群搭建并且成功的发送和消费消息,初步验证了Kafka的功能,接下来会在第一篇【Kafka从入门到放弃系列 一】概述及基本架构的简单理论和第二篇的实践基础之上,开始深入探讨Kafka的架构和一些策略,本篇blog重点介绍全流程以及文件存储机制,接下来的几篇分别介绍下生产者策略、消费者策略和一些高级特性

Kafka工作流程

通过基础概念的学习可以知道kafka的消息分为Topic,而Topic从逻辑上又可以划分为Partion,关于Topic&Partion需要注意以下几点:

  • 一个 Topic可以认为是一类消息,每个 topic 将被分成多个 Partion,每个 Partion在存储层面是 append log 文件。
  • 任何发布到partition 的消息都会被追加到log文件的尾部,每条消息在文件中的位置称为 offset(偏移量),offset 为一个 long 型的数字,它唯一标记一条消息

  • Kafka 机制中,producer push 来的消息是追加(append)到 Partion中的,这是一种顺序写磁盘的机制,效率远高于随机写内存
  • 消费者组中的每个消费者,都会实时记录自己消费到了哪个 offset,以便出错恢复时,从上次的位置继续消费
  • Kafka只保证Partion内的消息有序,不能保证全局Topic的消息有序

整体的流程如下图所示:

那么为什么有分区的概念呢?主要还是为了我们分布式的一切中间件的共同特性:负载均衡&水平扩展,Topic 只是逻辑概念,面向的是 producer 和 consumer;而 Partition 则是物理概念。可以想象,如果 Topic 不进行分区,而将 Topic 内的消息存储于一个 broker,那么关于该 Topic 的所有读写请求都将由这一个 broker 处理,吞吐量很容易陷入瓶颈,这显然是不符合高吞吐量应用场景的。所以一定是需要分区来将流量分发到不同的服务器上去的

Kafka文件存储机制

当然即使是对一个Partition 而言,如果消息量过大的话也会有堵塞的风险,所以我们需要定期清理消息,当然是从旧的开始清理,如果只有一个Partion,那么就得全盘清除,这将对消息文件的维护以及已消费的消息的清理带来严重的影响。所以我们需要在物理上进一步细分Partition 。因此,需以 segment 为单位将 partition 进一步细分,每个 partition(目录)相当于一个巨型文件被平均分配到多个大小相等的 segment(段)数据文件中(每个 segment 文件中消息数量不一定相等)这种特性也方便 old segment 的删除,即方便已被消费的消息的清理,提高磁盘的利用率。每个 partition 只需要支持顺序读写就行。

Partition&Segment

接下来我们发送一条消息,看看在物理存储上是什么样的:

三个消息:hello、dashuaige、hhh。打开存储目录可以看到,在103机器上,一组index和log,这就是一个segment的内容

segment 文件由两部分组成,分别为 “.index” 文件和 “.log” 文件,分别表示为 segment 索引文件和数据文件。这两个文件的命令规则为:partition 全局的第一个 segment 从 0 开始,后续每个 segment 文件名为上一个 segment 文件最后一条消息的 offset 值,数值大小为 64 位,20 位数字字符长度,没有数字用 0 填充,我这里只有一条数据,所以是从0开始的,打开log文件可以看到:

虽然是乱码的,但是隐约可以看到顺序发送的消息。整体的存储架构如下:

Segment存储结构

通过以上对Segment落盘文件的了解,我们基本搞清楚了Segment的结构,当然我这里是单segment,看不出来。这里从网上找了一个大量文件的示例:

//第一段segment,起始位置为0
00000000000000000000.index
00000000000000000000.log
//第一段segment,起始位置为170410
00000000000000170410.index
00000000000000170410.log
//第一段segment,起始位置为239430
00000000000000239430.index
00000000000000239430.log

以上面的 segment 文件为例,展示出 segment:00000000000000170410 的 “.index” 文件和 “.log” 文件的对应的关系,如下图:

如上图,“.index” 索引文件存储大量的元数据,“.log” 数据文件存储大量的消息,索引文件中的元数据指向对应数据文件中 message 的物理偏移地址。其中以 “.index” 索引文件中的元数据 [3, 348] 为例,在 “.log” 数据文件表示第 3 个消息,即在全局 partition 中表示 170410+3=170413 个消息,该消息的物理偏移地址为 348【注意此物理偏移地址不是offset,全局offset为170413 】

快速定位partion中消息

既然消息在Partion中被分为了一段段的segment,那么我们如何快速定位消息的位置,来精准的对消息进行操作呢?以上图为例,读取 offset=170418 的消息:

  • 首先查找 segment 文件,其中 00000000000000000000.index 为最开始的文件,第二个文件为 00000000000000170410.index(起始偏移为 170410+1=170411),而第三个文件为 00000000000000239430.index(起始偏移为 239430+1=239431),所以这个 offset=170418 就落到了第二个文件之中。其它后续文件依次类推,以其偏移量命名并排列这些文件,然后根据二分查找法就可以快速定位到具体文件位置。
  • 其次根据 00000000000000170410.index 文件中的170418 -170410=8,得出是该segment 中的第8个消息,再次依据二分查找法定位到该索引,得到**[消息偏移量,物理偏移量]**坐标 [8,1325] 定位到 00000000000000170410.log 文件中的 1325 的位置进行读取。
  • 找到1325位置后,顺序读取消息即可,确定读完本条消息【本条消息读到哪里结束】由消息的物理结构解决,消息都具有固定的物理结构,包括:offset(8 Bytes)、消息体的大小(4 Bytes)、crc32(4 Bytes)、magic(1 Byte)、attributes(1 Byte)、key length(4 Bytes)、key(K Bytes)、payload(N Bytes)等等字段,可以确定一条消息的大小,即读取到哪里截止。

以上就是定位消息的详细方法,通过索引的方式,可以在kafka顺序写磁盘的基础上仍然能快速的找到对应的消息。

本篇blog讲解了Kafka的工作流程和存储机制,其实对于Kafka而言,更多的策略体现在生产者和消费者端,接下来的两篇blog我们分别介绍下生产者策略和消费者策略

部分内容参考 https://gitbook.cn/books/5ae1e77197c22f130e67ec4e/index.html

相关文章
|
1月前
|
JSON JavaScript 前端开发
Vue3源码架构简析及Monorepo流程构建
【10月更文挑战第12天】Vue3源码架构简析及Monorepo流程构建
Vue3源码架构简析及Monorepo流程构建
|
3月前
|
存储 缓存 前端开发
Django 后端架构开发:存储层调优策略解析
Django 后端架构开发:存储层调优策略解析
53 2
|
7天前
|
SQL Java 数据库连接
Mybatis架构原理和机制,图文详解版,超详细!
MyBatis 是 Java 生态中非常著名的一款 ORM 框架,在一线互联网大厂中应用广泛,Mybatis已经成为了一个必会框架。本文详细解析了MyBatis的架构原理与机制,帮助读者全面提升对MyBatis的理解和应用能力。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
Mybatis架构原理和机制,图文详解版,超详细!
|
1月前
|
存储 资源调度 算法
操作系统的心脏:深入理解内核架构与机制####
【10月更文挑战第16天】 本文旨在揭开操作系统最神秘的面纱——内核,通过剖析其架构设计与关键机制,引领读者一窥究竟。在这篇探索之旅中,我们将深入浅出地讨论内核的基本构成、进程管理的智慧、内存分配的策略,以及那至关重要的系统调用接口,揭示它们是如何协同工作,支撑起现代计算机系统的高效运行。这既是一次技术的深潜,也是对“看不见的手”调控数字世界的深刻理解。 ####
41 3
|
1月前
|
存储 监控 分布式数据库
百亿级存储架构: ElasticSearch+HBase 海量存储架构与实现
本文介绍了百亿级数据存储架构的设计与实现,重点探讨了ElasticSearch和HBase的结合使用。通过ElasticSearch实现快速检索,HBase实现海量数据存储,解决了大规模数据的高效存储与查询问题。文章详细讲解了数据统一接入、元数据管理、数据一致性及平台监控等关键模块的设计思路和技术细节,帮助读者理解和掌握构建高性能数据存储系统的方法。
百亿级存储架构: ElasticSearch+HBase 海量存储架构与实现
|
1月前
|
存储 消息中间件 大数据
大数据-69 Kafka 高级特性 物理存储 实机查看分析 日志存储一篇详解
大数据-69 Kafka 高级特性 物理存储 实机查看分析 日志存储一篇详解
36 4
|
1月前
|
消息中间件 存储 缓存
大数据-71 Kafka 高级特性 物理存储 磁盘存储特性 如零拷贝、页缓存、mmp、sendfile
大数据-71 Kafka 高级特性 物理存储 磁盘存储特性 如零拷贝、页缓存、mmp、sendfile
52 3
|
1月前
|
存储 消息中间件 大数据
大数据-70 Kafka 高级特性 物理存储 日志存储 日志清理: 日志删除与日志压缩
大数据-70 Kafka 高级特性 物理存储 日志存储 日志清理: 日志删除与日志压缩
39 1
|
1月前
|
存储 消息中间件 大数据
大数据-68 Kafka 高级特性 物理存储 日志存储概述
大数据-68 Kafka 高级特性 物理存储 日志存储概述
26 1
|
1月前
|
消息中间件 分布式计算 Kafka
大数据-98 Spark 集群 Spark Streaming 基础概述 架构概念 执行流程 优缺点
大数据-98 Spark 集群 Spark Streaming 基础概述 架构概念 执行流程 优缺点
40 0
下一篇
无影云桌面