【大数据】Kafka 数据存储

news2024/10/6 1:44:49

Kafka 数据存储

  • 1.文件目录
  • 2.日志分段
  • 3.日志索引
    • 3.1 偏移量索引
    • 3.2 时间戳索引
  • 4.日志清理
    • 4.1 日志删除
      • 4.1.1 基于时间
      • 4.1.2 基于日志大小
      • 4.1.3 基于日志起始偏移量
    • 4.2 日志压缩

1.文件目录

Kafka 中的消息是存储在磁盘上的,一个分区副本对应一个 日志(Log)。为了防止 Log 过大,Kafka 又引入了 日志分段(LogSegment)的概念,将 Log 切分为多个 LogSegment ,相当于一个巨型文件被平均分配为多个相对较小的文件,这样也便于消息的维护和清理。事实上,Log 和 LogSegment 也不是纯粹物理意义上的概念,Log 在物理上只以文件夹的形式存储,而每个 LogSegment 对应于磁盘上的一个日志文件和两个索引文件,以及可能的其他文件(比如以 .txnindex 为后缀的事务索引文件),下图为 Topic、Partition、副本、Log 和 LogSegment 之间的关系。

在这里插入图片描述

2.日志分段

虽然一个 Log 被拆为多个分段,但只有最后一个 LogSegment(当前活跃的日志分段)才能执行写入操作,在此之前所有的 LogSegment 都不能写入数据。当满足以下其中任一条件会创建新的 LogSegment。

  • 当前日志分段文件的大小超过了 Broker 端参数 log.segment.bytes 配置的值,默认值为 1073741824 1073741824 1073741824,即 1 G B 1GB 1GB
  • 当前日志中第一条消息的时间戳与当前系统的时间戳的差值大于 log.roll.mslog.roll.hours 参数配置的值。如果同时配置了 log.roll.mslog.roll.hours,那么以 log.roll.ms 为准。默认只配置了 log.roll.hours 参数,其值为 168 168 168,即 7 7 7 天。
  • 偏移量索引文件或时间戳索引文件的大小达到 Broker 端参数 log.index.size.max.bytes 配置的值,默认值为 10485760 10485760 10485760,即 10 M 10M 10M
  • 追加的消息的偏移量与当前日志分段的偏移量之间的差值大于 Integer.MAX_VALUE,即(offset - baseOffset)> Integer.MAX_VALUE

在索引文件切分的时候,Kafka 会关闭当前正在写入的索引文件并置为只读模式,同时以可读写的模式创建新的索引文件,默认大小为 1 G B 1GB 1GB。当下次索引切分时才会设置为实际大小。也就是说,之前的 Segment 都是实际大小,活跃的 Segment 大小为 1 G 1G 1G

3.日志索引

索引的主要目的是提高查找的效率。

Kafka 采用 稀疏索引sparse index)的方式构造消息的索引,它并不保证每个消息在索引文件中都有对应的索引项。而是每当写入一定量(由 Broker 端参数 log.index.interval.bytes 指定,默认 4 K B 4KB 4KB)的消息时,索引文件会增加一个索引项。

3.1 偏移量索引

一条偏移量索引包含两部分数据,如图:

在这里插入图片描述

在这里插入图片描述

  • relativeOffset:相对偏移量,表示消息相对于 baseOffset 的偏移量,当前索引文件的文件名即为 baseOffset
  • position:物理地址,也就是消息在日志分段文件中对应的物理位置。
  • baseOffset:Segment 第一个 Message 的 Offset。

消息查找过程
在这里插入图片描述

如果我们要查找偏移 23 23 23 的消息,那么应该怎么做呢? 首先通过二分法在偏移量索引文件中找到不大于 23 23 23 最大索引项,即 [22,656],然后从日志分段文件中的物理位置 656 656 656 开始顺序查找偏移 23 23 23 的消息。

以上是比较简单的情况,如下图所示,如果要查找要查找偏移 268 268 268 的消息,那么应该怎么办呢?

在这里插入图片描述

首先肯定是定位到 baseOffset = 251 的日志分段,然后计算相对偏移量 relativeOffset 268 − 251 = 17 268 - 251=17 268251=17,之后再在对应的索引文件中找到不大于 17 17 17 的索引项,最后根据索引项中的 position 定位到具体的日志分段文件位置开始查找目标消息。

那么如何查找 baseOffset 25 的日志分段的呢?Kafka 使用了跳跃表的结构。Kafka 的每个日志对象中使用了 ConcurrentSkipListMap 来保存各个日志分段,每个日志分段的 baseOffset 作为 Key ,这样可以根据指定偏移量来快速定位到消息所在的日志分段。

3.2 时间戳索引

时间戳索引也是包含两部分数据,如图:

在这里插入图片描述

在这里插入图片描述

  • timestamp:当前日志分段最大的时间戳。
  • relativeOffset:时间戳所对应的消息的相对偏移量,也就是偏移量索引中偏移量。

时间戳索引文件中包含若干时间戳索引项,每个追加的时间戳索引项中的 timestamp 必须大于之前追加的索引项的 timestamp,否则不予追加。

消息查找过程

在这里插入图片描述

如果要查找指定时间戳 targetTimeStamp = 1526384718288 开始的消息,首先是找到不小于指定时间戳的日志分段。这里就无法使用跳跃表来快速定位到相应的日志分段 了, 需要分以下几个步骤来完成。

  • targetTimeStamp 和每个日志分段中的最大时间戳对比,直到找到不小于 targetTimeStam 所对应的日志分段。(注:日志分段中的最大时间戳的计算是先查询该日志分段所对应的时间戳索引文件,找到最后一条索引项,若最后一条索引项的时间戳字段值大于 0 0 0,则取其值,否则取该日志分段的最近修改时间。)
  • 找到相应的日志分段之后,在时间戳索引文件中使用二分查找算法查找到不大于 targetTimeStamp 最大索引项,即 [1526384718283, 28],如此便找到了相对偏移量 28 28 28
  • 在偏移量索引文件中使用二分算法查找到不大于 28 28 28 的最大索引工页,即 [26,838]
  • 从第一步中找到的日志分段文件中的 838 838 838 的物理位置开始查找不小于 targetTimeStamp 的消息。

4.日志清理

Kafka 将消息存储在磁盘中,为了控制磁盘占用空间的不断增加就需要对消息做一定的清理操作。Kafka 提供了两种日志清理策略。

  • 日志删除:按照一定的保留策略直接删除不符合条件的日志分段,默认该策略。
  • 日志压缩:针对每个消息的 Key 进行整合,对于有相同 Key 的不同 Value 值,只保留最后一个版本。

4.1 日志删除

kafka 有专门的任务来周期性删除不符合条件的日志分段文件,删除策略主要以下有 3 3 3 种。

4.1.1 基于时间

Broker 端可通过参数设置日志的最大保留时间,默认 7 7 7 天。定时任务会查看每个分段的最大时间戳(计算逻辑同上),若最大时间戳距当前时间超过 7 7 7 天,则需要删除。

删除日志分段时, 首先会先从跳跃表中移除待删除的日志分段,保证没有线程对这些日志分段进行读取操作。然后将日志分段所对应的所有文件添加上 .delete 的后缀。最后由专门的定时任务来删除以 .delete 为后缀的文件。

4.1.2 基于日志大小

日志删除任务会检查当前日志的大小是否超过设定的阈值(retentionSize)来寻找可删除的日志分段的文件集合(deletableSegments)。

注意这里的日志的大小是指所有的 Segment 的总和,不是单个 Segment。

在这里插入图片描述

首先计算日志文件的总大小和设定阈值的差值,即计算需要删除的日志总大小,然后从日志文件中的第一个日志分段开始进行查找可删除的日志分段,放入集合 deletableSegments 中 。之后进行删除,删除过程同 4.1.1 小节所述。

4.1.3 基于日志起始偏移量

一般情况下,日志文件的起始偏移 logStartOffset 等于第 1 1 1 个日志分段的 baseOffset,但 logStartOffset 是可以被修改的。

该策略会判断某日志分段的下一个日志分段的起始偏移量 baseOffset 是否小于等于 logStartOffset,若是,则将其放入 deletableSegments 中。如下图所示。

在这里插入图片描述
之后进行删除,删除过程同 4.1.1 小节所述。

4.2 日志压缩

对于有相同 Key 的不同 Value 值,只保留最后一个版本。如果应用只关心 Key 对应的最新 Value 值,则可以开启 Kafka 的日志压缩功能,Kafka 会定期将相同 Key 的消息进行合井,只保留最新的 Value 值。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1116534.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2019年亚太杯APMCM数学建模大赛A题基于图像分析的二氧化硅熔化表示模型求解全过程文档及程序

2019年亚太杯APMCM数学建模大赛 A题 基于图像分析的二氧化硅熔化表示模型 原题再现 铁尾矿的主要成分是二氧化硅,而二氧化硅是铁尾矿成分中最难熔化的部分。因此,铁尾矿的熔融行为可以用二氧化硅的熔融行为来表示。然而,高温熔池的温度超过…

AIO开放接口平台免费畅享ChatGPT聊天、联网互动、学术等服务!更有DALL·E 3最强AI绘图功能!

免费畅享! AIO平台ChatGPT联网、聊天、学术等服务! AIO开放接口平台 | 服务介绍 ALL IN ONE (AIO)API服务是LLM(大语言模型)开放接口平台:持续接入各种主流的大模型接口,并提供简单、易用、统一的API交互…

开源网安受邀参加数字安全高峰论坛,为数字经济发展保驾护航

​10月19日,“提升数字安全技术,护航数字经济发展”高峰论坛在常州创意产业园圆满完成。本次论坛由常州国家高新区管委会、常州市工业和信息化局、常州市大数据管理中心主办,聚焦“数据安全”主题,邀请了超百位专家及企业代表共同…

WordPress SMTP邮件发送插件 Easy WP SMTP

Easy WP SMTP是一款 WordPress 邮件发送插件,WordPress 中经常用到邮件发送,包括新注册用户的邮件通知、找回密码通知、评论回复通知等。因为云服务器默认不启用 SMTP功能,所以需要安装 SMTP插件来解决这个问题。 SMTP 主机:smtp.…

斜率优化dp

f i min ⁡ ( a j − j i ) f_i\min(a_j - j \times i) fi​min(aj​−ji) 考虑变成点对 ( j , a j ) (j,a_j) (j,aj​),则 f i Y j − X j i f_iY_j-X_ji fi​Yj​−Xj​i 令 i k , f i b ik, f_ib ik,fi​b,得 b Y j − X j k bY_j-X_jk b…

关于OpenMesh与OpenGL

文章目录 OpenMesh官网OpenMesh是什么?他能做什么?直接无源码安装测试报错:效果: 学习openmesh学习openmesh的流程如下:第一步,了解openmesh库的基本概念第二步,查看openmesh的官方示例,了解简单…

【java】【MyBatisPlus】【二】MyBatisPlus常规使用

目录 一、简述 1、概述 2、特性 3、支持数据库 二、标准数据层开发 1、标准数据层CRUD功能 1.1 新增insert 1.2 删除功能deleteById 1.3 修改功能updateById 1.4 查询单个selectById 1.5 查询全部selectList 2、分页功能 2.1 设置MybatisPlus分页拦截器作为Spring管…

LSTM-Attention单维时间序列预测研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

Redis基本命令和常用数据类型

文章目录 前言一、Redis简介二、基本操作1.赋值2.取值3.切换数据库4.查看数据库所有键(key)5.查看键值类型6.移动键值到其他数据库7.设置键值生存时间(两种)8.查看键值生存时间9.查看当前数据库大小10.判断键是否存在11.清空当前数…

IntelliJ IDEA 2020.2.1白票安装使用方法

先安装好idear Plugins 内手动添加第三方插件仓库地址:https://plugins.zhile.io 搜索:IDE Eval Reset插件进行安装 输入https://plugins.zhile.io 手动安装离线插件方法 安装包可以去笔者的CSDN资源库下载 安装mybaties插件

Simulink模型加密共享

1.前言 为了保护知识产权,有时候需要让用户能使用slx模型运行仿真,但是无法查看和修改模型和子系统的结构,这时可以用Simulink coder来生成受保护的模型。主要步骤如下: (1)将slx模型的各个子系统唯一命名…

Nginx负载均衡反向代理动静分离

文章目录 nginx负载均衡&反向代理&动静分离环境说明部署动静分离1.主机lnmp部署一个动态页面,在此以discuz论坛系统为例2.主机n1部署两个静态页面访问动、静态页面 配置负载均衡配置反向代理访问测试 nginx负载均衡&反向代理&动静分离 环境 主机名…

重测序基因组:Pi核酸多样性计算

如何计算核酸多样性 Pi 本期笔记分享关于核酸多样性pi计算的方法和相关技巧,主要包括原始数据整理、分组文件设置、计算原理、操作流程、可视化绘图等步骤。 基因组Pi核酸多样性(Pi nucleic acid diversity)是一种遗传学研究中用来描述种群内…

使用CDN构建读取缓存设计

在构建需要高吞吐量和最小响应时间的系统的API时,缓存几乎是不可避免的。每个在分布式系统上工作的开发人员都曾在某个时候使用过某种缓存机制。在本文中,我们将探讨如何使用CDN构建读取缓存设计,不仅可以优化您的API,还可以降低基…

JVM第十六讲:调试排错 - Java 线程分析之线程Dump分析

调试排错 - Java 线程分析之线程Dump分析 本文是JVM第十六讲,Java 线程分析之线程Dump分析。Thread Dump是非常有用的诊断Java应用问题的工具。 文章目录 调试排错 - Java 线程分析之线程Dump分析1、Thread Dump介绍1.1、什么是Thread Dump1.2、Thread Dump特点1.3、…

maven-default-http-blocker (http://0.0.0.0/): Blocked mirror for repositories

前言 略 说明 新设备上安装了mvn 3.8.5,编译新项目出错: [ERROR] Non-resolvable parent POM for com.admin.project:1.0: Could not transfer artifact com.extend.parent:pom:1.6.9 from/to maven-default-http-blocker (http://0.0.0.0/): Bl…

【LeetCode】 387. 字符串中的第一个唯一字符

题目链接 文章目录 所有方法 复杂度 ( O ( n ) O(n) O(n)、 O ( ∣ Σ ∣ ) O(|\Sigma|) O(∣Σ∣)) Python3方法一:collections.Counter() 统计频次方法二:哈希映射 { key字符:value【首次出现的索引 or -1 出现多次】}方法三: c…

账号合租平台源码Thinkphp6.1|内置详细搭建教程

小白账号合租平台说明 系统采用的是常见的租号平台模式,现在网络上流出的这种类型的源码还很少 平台介绍 1.租号模式,用户可自行选择单独租号或采用合租的模式。 2.支付,采用易支付通用接口 3.邀请返利,为了站长能更好推广推荐了邀请返利功能 4.用户提现功能 5.工单…

社会网络分析软件

UCINET UCINET 6 for Windows

vue3中弹框中的el-select下拉组件显示value而不显示label

1.场景 使用element-ui中的el-select&#xff0c;给选择框赋值时显示的值是value不是label 2.原因分析 3.解决方法 在点击编辑按钮后将获取到的对象中的os属性值改为string类型 <el-select v-model"form.os" clearable placeholder"请选择" style&qu…