kafka数据在服务端时怎么写入的

学习背景

接着上篇,我们来聊聊kafka数据在服务端怎么写入的

服务端写入

在介绍服务端的写流程之前,我们先要理解服务端的几个角色之间的关系。

假设我们有一个由3个broker组成的kafka集群,我们在这个集群上创建一个topic叫做shitu-topic,他有10个分区,每个分区有3个副本。那么partition和broker的关系假设如下。

kafka partition关系

因为每个partition有3个副本,所以每个partition的副本都会均匀的分布在这三台机器上,我们取shitu-topic-0的副本来观察。

在三个broker上,每个broker的log存储目录都有一个shitu-topic-0目录,我们可以成为shitu-topic-0分区,但是同一个时间,只有broker-0上的leader副本对外提供服务,broker-1和broker-2需要去到broker-0上同步消息。在shitu-topic-0目录下就是存储的实际的日志文件。日志文件里包含三个主要的文件内容.log文件存储实际的消息,.index文件存储索引,.timeindex文件存储时间索引。我们把这三个文件合称为一个logsegment日志段,每个log文件只要超过1G就会产生一个新的段文件。日志段文件的命名是以当前段内第一条消息的offset来命名的,这里因为是新创建的topic,第一条消息是0,所以都是0。因为消息是顺序写入的,所以只有最后一个日志段是激活的我们称为active segemnt,活跃段。比如这里活跃段就是00000000000020123000开头的段。

kafka leader-flower关系

研究消息的写入,就是研究这些文件时怎么产生的,让我们来看一下段文件里每个文件的组织格式。

写入文件

log文件

.log文件存储实际的写入日志,也就是实际的数据存储位置。kafka的log文件存储格式经过了3次变化,目前使用的日志格式称为V2版本,我们取这个版本的日志格式来做讲解。

log文件格式

上图左侧显示的是log文件的格式,我们把log文件内存储的的消息集合称为record batch,而每条消息我们称为一条record,每条record的格式如右边所示。record batch内的字段主要记录的整个log文件的全局属性,比如log文件的起始偏移量,文件长度,epoch,时间戳等等,不做详细解释,也不是重点。

我们说一下每条消息的格式,我们知道每条消息除了实际的消息内容value外,伴随着每条消息的产生,还会产生这条消息的额外附带的信息,比如消息的偏移量,offsset,时间戳timestamp等等。kafka在设计消息的存储时花了很大的心思。

这里我解释一下varint,varlong类型,简单的说,就是可变长的类型。比如一条消息的偏移量是int存储容量是4字节,比如存储10这个偏移量,虽然前面大部分是0,但是实际存储还是需要4字节。而varint则可以根据数据的范围选择合适的存储,比如还是10,那么实际记录这个值1个字节就够了。这样,当写入消息时,比如写入2条消息,偏移量分别是10和11,如果分别存储这两个偏移量,需要

2 * 4B = 8b

而如果使用varint存储,则只需要

2 * 1B + 4B(基础偏移量) = 6B

这里如果不是2条消息,而是10000条消息,那么这个优化就会非常有用。kafka这么做是为了尽最大的可能使用存储空间。当然除了数据格式上的优化,kafka还对数据进行了压缩,也就是records是可以配置不同的压缩算法进行压缩的,比如ZIP。

index文件

.index记录偏移量到实际消息的映射关系。一个很简单的述求,我们想知道某个偏移量的日志的内容,那么我们就需要一种能根据偏移量定位到消息的格式。

index文件的格式由相对偏移量realtive offset和物理偏移量position组成。当一条消息写入时,根据消息的偏移量计算出这条消息的相对偏移量,比如写入的是20123025这条消息,那么用20123025-20123000 = 25得到相对偏移量25,再记录下这消息的起始物理地址1024,即可组成对这条消息的索引。需要·注意的是,这里的索引是稀疏索引,也就是不是每条消息都会产生索引,而是每隔一些消息产生索引,这样能减少索引的文件大小。

每一条索引的需要4B的相对偏偏移量和4B的物理地址偏移量,一共8B,kafka的服务端在设置index文件最大大小时要求index文件必须是索引项的整数倍,如果不是,则会自动转换成最接近的整数倍的数字。

index文件

大家这里肯定很好奇那么怎么利用相对偏移量来查找消息,我们解释一下,其实对消息的查找可以概述为根据二分法查找。比如想要查找20123050这条偏移量的消息,先根据这个偏移量,去到我们当前副本的segement集合中根据segement的起始偏移量找到对应的segement,所有的segement的信息是根据相对偏移量以跳表的形式记录的。找到的对应的segement后先计算出相对偏移量20123050-20123000 = 50,然后根据50这个相对偏移量,我们去到相对偏量数组里,使用二分查找找到[20,75]这个相对偏移量范围,那么我们可以在log文件里从1024字节开始,逐条消息的解析,并计算出消息的偏移量是不是50,直到2147字节这个结束的位置为止。如果能找到,说明消息在本partition内,不能我们再换另外的partition查找。

timeindex文件

timeidnex记录时间戳到实际消息的映射关系,我们介绍了index文件的格式,再来理解timeindex文件的格式就容易多了。timeindex文件和index文件的格式类似,由时间戳相对偏移量和消息相对偏移量组成。时间戳相对偏移量根据消息的写入时间来计算,比如写入时间是1733001000,用这个写入的时间减去timeindex文件的起始时间1733000000得到1000这个相对时间戳偏移量。

timeindex文件

timeindex文件的查找我们就不说了,大家可以参考index文件。需要注意一点timeindex文件的时间戳是可以设置的,虽然一般kafka服务端会采取自动设置消息写入时间的配置,即log.message.timestamp.type=LogAppendTime,这种情况下因为时间戳由服务器端设置,能够保证时间戳递增。但是如果服务端设置的是CreateTime,并且producer自己设置了消息的生产时间,那么有可能造成timeIndex的写入失败,因为timeindex要求写入的时间必须是递增的。如果不递增,则拒绝本次写入。还有就是,timeindex文件和index文件虽然都是索引,但是他们并不是每条索引项一一对应的,大家从图中也能看出来。

根据timeindex查找对应消息的过程也和index文件的查找类似,不过因为timeindex本身是根据时间戳来查找,所以会有一步先查找每个timeindex文件的最大时间戳,直到找到一个大于查找时间并且最接近查找时间的timeindex文件。这里有点绕,举个例子,第一个timeindex文件的最大时间戳10000,第二个timeindex文件最大时间戳23000,第三个timeindex文件最大时间戳50000,要查找时间戳为15000的消息,那么因为timeindex文件的时间戳是顺序递增的,很明显,第三个文件的消息都是在15000之后产生的,第一个文件的消息都是在15000之前产生的,那么理所应当的,正好拥有大于15000的时间戳23000的第二个文件理论上应该包含15000这个时间戳写入的消息,所以找到第二个文件。找到对应的文件后再去到到对应的这个timeindex文件根据时间偏移量索引找到这个对应的消息(找不到就换partition)。

写入过程

介绍完毕实际的文件内容,我们再来归纳一下数据的写入过程。这里不会介绍副本之间的同步的问题,只介绍在leader副本上数据的写入。

当消息通过client发送到broker上时,broker根据消息的topic找到这个topic的leadder副本。leadter副本根据消息的信息计算出消息归属的parititon。找到parititon后根据偏移量设置计算出消息的偏移量和时间戳,再找到对应的active segement,在index文件中追加消息,并根据需要决定是否写入index文件和timeindex文件。

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

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

相关文章

rabbitmq原理及命令

目录 一、RabbitMQ原理1、交换机(Exchange)fanoutdirecttopicheaders(很少用到) 2、队列Queue3、Virtual Hosts4、基础对象 二、RabbitMQ的一些基本操作:1、用户管理2、用户角色3、vhost4、开启web管理接口5、批量删除队列 一、Ra…

Kali Linux怎么开python虚拟环境

相信很多朋友再学习的过程中都会遇到一些pip失效,或者报错的时候,他们要求我们要使用虚拟环境,但是不知道怎么搭建,下面这篇文章就来告诉你如何搭建虚拟环境,这个方法在所有Linux的服务器都通用,就两行命令…

【博主推荐】C# Winform 拼图小游戏源码详解(附源码)

文章目录 前言摘要1.设计来源拼图小游戏讲解1.1 拼图主界面设计1.2 一般难度拼图效果1.3 普通难度拼图效果1.4 困难难度拼图效果1.5 地域难度拼图效果1.6 内置五种拼图效果 2.效果和源码2.1 动态效果2.2 源代码 源码下载结束语 前言 在数字浪潮汹涌澎湃的时代,程序开…

React Native学习笔记(三)

一 组件简介 1.1 简介 RN中的核心组件,是对原生组件的封装 原生组件:Android或ios内的组件核心组件:RN中常用的,来自react-native的组件 原生组件 在 Android 开发中是使用 Kotlin 或 Java 来编写视图;在 iOS 开发…

视觉语言动作模型VLA的持续升级:从π0之参考基线Octo到OpenVLA、TinyVLA、DeeR-VLA、3D-VLA

第一部分 VLA模型π0之参考基线Octo 1.1 Octo的提出背景与其整体架构 1.1.1 Octo的提出背景与相关工作 许多研究使用从机器人收集的大量轨迹数据集来训练策略 从早期使用自主数据收集来扩展策略训练的工作[71,48,41,19-Robonet,27,30]到最近探索将现代基于transformer的策略…

C与指针。

目录 1_指针理解 1.1变量的值 1.2变量的地址 1.3指针 1.4取变量的地址 2_分析指针 2.1分析指针变量的要素 2.2根据需求定义指针变量 3_指针的使用 3.1指针对变量的读操作 3.2指针对变量的写操作 4_指针占用空间的大小与位移 4.1指针占用空间的大小 4.2指针的位移…

单片机学习笔记 15. 串口通信(理论)

更多单片机学习笔记:单片机学习笔记 1. 点亮一个LED灯单片机学习笔记 2. LED灯闪烁单片机学习笔记 3. LED灯流水灯单片机学习笔记 4. 蜂鸣器滴~滴~滴~单片机学习笔记 5. 数码管静态显示单片机学习笔记 6. 数码管动态显示单片机学习笔记 7. 独立键盘单片机学习笔记 8…

树莓派5+文心一言 -> 智能音箱

一、简介 效果:运行起来后,可以连续对话 硬件:树莓派5、麦克风、音箱,成本500-1000 软件:snowboy作为唤醒词、百度语音作为语音识别、brain作为指令匹配、百度文心一言作为对话模块、微软的edge-tts语音合成... 二…

SAP SD学习笔记17 - 投诉处理3 - Credit/Debit Memo依赖,Credit/Debit Memo

上一章讲了 请求书(发票)的取消。 SAP SD学习笔记16 - 请求书的取消 - VF11-CSDN博客 再往上几章,讲了下图里面的返品传票: SAP SD学习笔记14 - 投诉处理1 - 返品处理(退货处理)的流程以及系统实操&#…

Linux服务器使用JupyterLab

一、JupyterLab的配置 1. conda配置 自行搜索conda安装与配置。 2. 环境创建 (1)创建环境 conda create -n jupyter python3.10(2)激活环境 conda activate jupyter(3)安装jupyter包 pip install -i…

Flutter:页面滚动

1、单一页面,没有列表没分页的,推荐使用:SingleChildScrollView() return Scaffold(backgroundColor: Color(0xffF6F6F6),body: SingleChildScrollView(child: _buildView()) );2、列表没分页,如购物车页,每个item之间…

使用GitZip for github插件下载git仓库中的单个文件

背景:git仓库不知道抽什么疯,下载不了单个文件,点击下载没有反应,遂找寻其他方法,在这里简单记录下。 使用GitZip for github插件下载仓库中的单个文件 1、首先在浏览器安装插件,并确保为打开状态。 2、然…

Unet改进57:在不同位置添加SFHF

本文内容:在不同位置添加CBAM注意力机制 论文简介 由于恶劣的大气条件或独特的降解机制,自然图像会遭受各种退化现象。这种多样性使得为各种恢复任务设计一个通用框架具有挑战性。现有的图像恢复方法没有探索不同退化现象之间的共性,而是侧重于在有限的恢复先验下对网络结构…

数据结构(初阶7)---七大排序法(堆排序,快速排序,归并排序,希尔排序,冒泡排序,选择排序,插入排序)(详解)

排序 1.插入排序2.希尔排序3.冒泡排序4.选择排序(双头排序优化版)5.堆排序6.快速排序1). 双指针法2).前后指针法3).非递归法 7.归并排序1).递归版本(递归的回退就是归并)2).非递归版本(迭代版本) 计算机执行的最多的操作之一就有排序,排序是一项极其重要的技能 接下…

DataWhale—PumpkinBook(TASK07支持向量机)

课程开源地址及相关视频链接:(当然这里也希望大家支持一下正版西瓜书和南瓜书图书,支持文睿、秦州等等致力于开源生态建设的大佬✿✿ヽ(▽)ノ✿) Datawhale-学用 AI,从此开始 【吃瓜教程】《机器学习公式详解》(南瓜…

【Python数据分析五十个小案例】使用自然语言处理(NLP)技术分析 Twitter 情感

博客主页:小馒头学python 本文专栏: Python爬虫五十个小案例 专栏简介:分享五十个Python爬虫小案例 项目简介 什么是情感分析 情感分析(Sentiment Analysis)是文本分析的一部分,旨在识别文本中传递的情感信息&…

【数据结构与算法】排序算法(上)——插入排序与选择排序

文章目录 一、常见的排序算法二、插入排序2.1、直接插入排序2.2、希尔排序( 缩小增量排序 ) 三、选择排序3.1、直接选择排序3.2、堆排序3.2.1、堆排序的代码实现 一、常见的排序算法 常见排序算法中有四大排序算法,第一是插入排序,二是选择排序&#xff…

Educator头歌:离散数学 - 图论

第1关&#xff1a;图的概念 任务描述 本关任务&#xff1a;学习图的基本概念&#xff0c;完成相关练习。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a;图的概念。 图的概念 1.一个图G是一个有序三元组G<V,R,ϕ>&#xff0c;其中V是非空顶点集合&am…

oracle RAC各版本集群总结和常用命令汇总

oracle RAC学习 RAC介绍 RAC&#xff1a;高可用集群&#xff0c;负载均衡集群&#xff0c;高性能计算集群 RAC是⼀种⾼可⽤&#xff0c;⾼性能&#xff0c;负载均衡的share-everything的集群 8i:内存融合雏形 内存融合雏形&#xff08;Oracle Parallel Server&#xff09;…

数据资产管理是什么?为什么重要?核心组成部分(分类分级、登记追踪、质量管理、安全合规)、实施方法、未来趋势、战略意义

文章目录 一、引言&#xff1a;数据的新时代二、什么是数据资产管理&#xff1f;2.1 定义2.2 核心功能 三、为什么数据资产管理至关重要&#xff1f;3.1 面对的数据管理挑战 四、数据资产管理的核心组成部分4.1 数据分类与分级4.2 数据资产登记与追踪4.3 数据质量管理4.4 数据安…