kafka存储原理介绍

2023-11-05

几个基本概念

Topic

消息主题。

每一条消息都必须要指定主题。kafka集群可以同时进行多个topic的分发。

Broker

消息处理的节点。

可以立即为每个broker是一个单独的kafka进程, 一般部署在不同的机器上, 多个broker共同组成一个集群。

Partition

分区。是topic在物理上的分组。每个partition实际上就是一个目录。

对于同一个topic下的多条消息, 按照一定的规则存储在多个partition上。 对于每个partition而言,消息的存储是有序的,但是对于整个topic而言, 消息的存储是无序的。

Segment

partition在物理上是有多个segment组成。

文件存储方式

topic中partition存储分布

假设当前环境kafka集群只有一个broker, 配置的数据存储根目录是 /data/, 假设现在创建了两个topic, 分别为event_log和alarm_log, partition数量设置的都为4, 则在/data目录下的结构如下:

/data
	event_log-0/
  event_log_1/
  event_log_2/
  evnet_log_3/
  alarm_log_0/
  alarm_log_1/
  alarm_log_2/
  alarm_log_3/

我们可以看到每个topic按名称分别占据了4个目录,且第一个partition的序号从0开始, 依次递增。

partition中文件存储分布

60be0fc82c265724267fad5c24367c91

  • 每个partition目录下平均分配到多个大小相等segment(段)数据文件。 但每个segment段文件的消息数量不一定相等。
  • 每个partition只允许顺序读写。这也是为什么说单个partition存储的消息是有序的。

对于segment文件, 由两部分组成, 且一一对应,成对出现, 分别为:

  • index file 索引文件,后缀为index。 存储元数据, 索引文件中的元数据指向对应数据文件中meaage的物理偏移地址。
  • data file 数据文件, 后缀为log。 存储message数据

下面是某个partition目录下的存储的segment文件

event_log-0/
	0000000000000000000.index
	0000000000000000000.log
	0000000000000246789.index
	0000000000000246789.log
	......

其中segment文件的命名规则如下:

  • partition全局的第一个segment从0开始
  • 后续每个sengment文件名为上一个全局partiitonde的最大offset(偏移message数)
  • 19位数字字符长度, 没有用0填充

可以看到data file是由meassage组成的, message的物理结构如下图所示:

dca706f2626f6cf4d139681380c606d2

关键字 解释说明
8 byte offset 在parition(分区)内的每条消息都有一个有序的id号,这个id号被称为偏移(offset),它可以唯一确定每条消息在parition(分区)内的位置。即offset表示partiion的第多少message
4 byte message size message大小
4 byte CRC32 用crc32校验message
1 byte “magic" 表示本次发布Kafka服务程序协议版本号
1 byte “attributes" 表示为独立版本、或标识压缩类型、或编码类型。
4 byte key length 表示key的长度,当key为-1时,K byte key字段不填
K byte key 可选
value bytes payload 表示实际消息数据。
在 partition 中通过 offset 查找 message过程
  1. 根据 offset 的值,查找 segment 段中的 index 索引文件。由于索引文件命名是以上一个文件的最后一个offset 进行命名的,所以,使用二分查找算法能够根据offset 快速定位到指定的索引文件
  2. 找到索引文件后,根据 offset 进行定位,找到索引文件中的匹配范围的偏移量position。(kafka 采用稀疏索引的方式来提高查找性能)
  3. 得到 position 以后,再到对应的 log 文件中,从 position处开始查找 offset 对应的消息,将每条消息的 offset 与目标 offset 进行比较,直到找到消息

比如说,我们要查找 offset=2490 这条消息,那么先找到00000000000000000000.index, 然后找到[2487,49111]这个索引,再到 log 文件中,根据 49111 这个 position 开始查找,比较每条消息的 offset 是否大于等于 2490。最后查找到对应的消息以后返回

kafka特性

顺序写

如果把消息以随机的方式写入到磁盘,那么磁盘首先要做的就是寻址,也就是定位到数据所在的物理地址,在磁盘上就要找到对应的柱面、磁头以及对应的扇区;这个过程相对内存来说会消耗大量时间,为了规避随机读写带来的时间消耗,kafka 采用顺序写的方式存储数据。

零拷贝

一般的拷贝过程如下:

20190218182751148

  1. 操作系统将数据从磁盘读入到内核空间的页缓存
  2. 应用程序将数据从内核空间读入到用户空间缓存
  3. 应用程序将数据写回到内核空间到 socket 缓存中
  4. 操作系统将数据从 socket 缓冲区复制到网卡缓冲区,以便将数据经网络发出

而零拷贝则直接将数据从页缓存传输到 socket, 不需要经过用户空间。

在 Linux 中,是通过 sendfile系统调用来完成的。Java 提供了访问这个系统调用的方法FileChannel.transferTo

2019021818281340

参考文章:

https://blog.csdn.net/zhangxm_qz/article/details/87636094

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

kafka存储原理介绍 的相关文章

随机推荐

  • 报错:java.lang.NullPointerException: Attempt to invoke virtual method ‘void android.widget.ImageView

    小编在调用View的时候出错 错误代码 java lang NullPointerException Attempt to invoke virtual method void android widget ImageView setIma
  • get和post请求方式总结

    前端发送请求最常 的是get请求还有post请求 get请求只能传params参数 params参数都是拼在请求地址上的 post可以传body和params两种形式 注意 params形式传递数据不管是get还是post请求 参数最后都是
  • java---多线程编程

    Java 多线程编程 Java 给多线程编程提供了内置的支持 一条线程指的是进程中一个单一顺序的控制流 一个进程中可以并发多个线程 每条线程并行执行不同的任务 与之对比的是 多线程是多任务的一种特别的形式 但多线程使用了更小的资源开销 这里
  • 异步处理及其他

    异步的方式 Spring事件发布 开启新的线程 其他资料 非异步 事务提交后 做其他的事情 事务回滚 同时记录异常信息 Spring事件发布 https blog csdn net root zhb article details 1256
  • 算法基础/递归回溯

    当要求解全排列或者全部的组合时 常采用递归 回溯的方式 标准的递归 回溯 DFS形式DFS nums index 表示当前位置是index 1 对于每个位置的数 要么被选中 temp push back nums index DFS num
  • Ubuntu 扩展内存或断电之后卡在 /dev/sda1 clean 和 /dev/sda1 recovering journal

    当ubuntu虚拟机硬盘空间不够用的时候 往往会出现新增扩展硬盘空间之后 出现开机卡死的现象 通过查阅相关资料 排坑如下 一 原VM硬盘空间已满 当原VM硬盘空间已满的情况下 千万不要重启或者关机操作 极容易引起卡死的状况发生 解决方案为
  • 计及电池储能寿命损耗的微电网经济调度(matlab代码)

    目录 1 主要内容 2 部分代码 3 程序结果 4 下载链接 1 主要内容 该程序参考文献 考虑寿命损耗的微网电池储能容量优化配置 模型 以购售电成本 燃料成本和储能寿命损耗成本三者之和为目标函数 创新考虑储能寿命损耗约束 放电深度约束和储
  • 分立式BUCK电路原理与制作持续更新

    目录 一 分立式BUCK电路总体原理图 二 BUCK电路与LDO的区别 三 BUCK电路为什么要加电感 四 BUCK电路要加续流二极管 五 BUCK电路导通与断开的回路 六 电源公式的中的几个表示方式 1 输入功率用Pin表示 2 输出功率
  • springboot+vue商城项目实战-springboot后端搭建

    搭建Spring Boot Vue商城后端项目 要搭建Spring Boot Vue商城后端项目 你需要掌握一系列的技术背景 下面我将为你介绍 开发这种项目所需的主要技术要求 Spring Boot框架 Spring Boot是一个开发Ja
  • redis常见操作命令-list

    1 将1个或者多个的value压入key的表头 LPUSH key value value 127 0 0 1 6379 gt LPUSH list abc integer 1 127 0 0 1 6379 gt LGET list err
  • Nginx设置成网站为https

    首先 获取SSL证书 我的证书是阿里云获取的 免费版dv证书 一年有效期 购买后 自动跳转到证书控制台 点击申请 然后选择如下设置 打码内容填入自己的个人信息 等待审核通过 我大概等了半小时 然后下载证书 解压 获得以下两个文件 在服务器的
  • 多益网络人工智能面试和入职问题

    以下几点是我在技术面试中技术hr问到的一些问题 1 简单自我介绍 2 网测的智商检测问题怎么看 3 分别介绍两个项目 4 基于第一个项目 有没有做过法律相关的知识图谱构建来优化模型结果 5 基于第二个项目 在做方案研究的时候就只是模型的融合
  • hello paddle

    文章目录 一 用飞桨定义模型的计算 二 准备好运行飞桨 三 告诉飞桨怎么样学习 四 运行优化算法 五 机器学习出来的参数 import paddle 导入飞桨paddle和numpy import numpy print paddle pa
  • ssh普通用户(非root用户)的密钥登录

    原文地址 ssh原理 ssh普通用户 非root用户 的密钥登录 这里以用户名 zhangsan 为例 由于个人习惯问题 我把用户zhangsan的默认目录改了 在使用密钥登录的过程中 始终提示要输入用户密码 而 var log secur
  • 群晖硬盘已损毁 Linux 修复,群晖NAS提示空间损毁修复纪实

    注 以下操作有丢失数据的风险 请慎重考虑按本文提示操作 前几天 家里的服务器RAID卡告警 提示阵列掉盘 后花了一天时间进行重新挂盘并重建数据 不是重建阵列哈 开机 OK ESXI一切正常 运行各种系统没有问题 当打开NAS时 提示报错 重
  • stm32单片机基础(一)

    stm32单片机 串口复用 IO口功能如何查看 GPIO配置选择 GPIO 如何确定外设的时钟是APB1还是APB2 概念 时钟周期 机器周期 双工 半双工 单工含义区别 串口复用 一定要记得使能复用时钟 AFIO 端口IO功能复用时钟 某
  • 线程共享和私有的数据

    引用 windows程序员面试指南 堆上的数据是线程共享的 栈上的数据是线程私有的 1 堆上共享的数据 a 进程 代码段 b 进程 数据段 c 进程打开的文件描述符 d 信号的处理器 e 进程的当前目录和 f 进程用户 ID 与进程组 ID
  • 全网最牛,接口自动化-Linux系统安装Jenkins+Ant详细步骤

    目录 导读 前言 一 Python编程入门到精通 二 接口自动化项目实战 三 Web自动化项目实战 四 App自动化项目实战 五 一线大厂简历 六 测试开发DevOps体系 七 常用自动化测试工具 八 JMeter性能测试 九 总结 尾部小
  • vld(Visual Leak Detector)下载地址和源码地址

    安装包下载页面 https kinddragon github io vld eg https github com KindDragon vld releases download v2 5 1 vld 2 5 1 setup exe 源
  • kafka存储原理介绍

    几个基本概念 Topic 消息主题 每一条消息都必须要指定主题 kafka集群可以同时进行多个topic的分发 Broker 消息处理的节点 可以立即为每个broker是一个单独的kafka进程 一般部署在不同的机器上 多个broker共同