当前位置: 首页 > news >正文

揭秘 Kafka 高性能之谜:一文读懂背后的设计精粹与技术实现

        Kafka在性能方面有着显著的优势,这也使得Kafka的应用非常广泛,那kakfa的性能为何如此优异呢?本文将带你探寻kafka高性能之谜。

        kafka的高性能概括起来有如下几点:顺序写入磁盘与I/O优化、批量处理、页缓存、零拷贝技术、分区并行处理、高效的消息压缩。下面将分别极少这几方面的内容。

一、顺序写入磁盘与I/O优化        

        人们对于磁盘速度慢的普遍印象,使得人们对于持久化的架构提供强有力的性能产生怀疑。事实上,磁盘的速度快慢取决于使用磁盘的方式,而且设计合理的磁盘结构通常可以和网络一样快。

        关于磁盘性能的关键事实是,磁盘的吞吐量和过去十年里磁盘的寻址不同。使用6个7200rpm、SATA接口、RAID-5的磁盘阵列在JBOD配置下的顺序写入的性能约为600MB/s,但随机写入的性能仅约为100k/s,相差6000倍以上。因为线性的读取和写入是磁盘使用模式中最有规律的,并且由操作系统进行大量的优化,现代操作系统提供了read-ahead和write-behind技术。

        read-ahead:操作系统文件预读,linux系统内核将指定文件的某区域预读进页缓存起来,便于对该区域进行读取时,不会因缺页而阻塞。预读可以有效地减少磁盘的寻址次数和应用程序的I/O等待时间。

        write-behind:将多个小型的逻辑合并成一次大型的物理磁盘写入。

        1.1 数据在kafka中是如何存储的

        一个主题对应多个分区,每个分区又有多个副本,一个副本对应一个日志(Log),为了防止Log过大,Kafka又引入了日志分段(LogSegment),将log切分成多个LogSegmnt,相当于一个巨型文件被平均分成多个相对较小的文件,这样便于消息的维护和清理。

        事实上,Log和LogSegment也不是纯粹物理意义上的概念,Log在物理上只以文件夹的形式存储,而每个LogSegment对应于磁盘上一个日志文件和两个索引文件,以及可能的其他文件。下图描述了主题、分区与副本、日志之间的关系。

        在Log中追加消息时是 顺序写入 的,只有最后一个LogSegment才能执行写入操作,在此之前所有的LogSegment都不能写入数据。日志中还存在索引文件,可以高效的定位消息,提高效率。

        从这里就能看出,日志的内容是顺序写入的,所以磁盘的性能比随机写入要好的多,这是kafka高性能的第一个原因

二、批量处理

        批量处理提高性能很好理解,将多次操作合并为一次操作.

        生产者发送消息时支持批量发送消息,将多条消息积累到一个批次中,然后一次性发送给Kafka Broker,这样可以减少网络I/O次数,显著提升吞吐量,并降低延迟,尤其是在网络带宽成为瓶颈时。

        在消费者端,Kafka也支持批处理的机制。消费者可以在处理完一批消息后,一起提交这些消息的偏移量(Offset),而不是每次消费一条消息就立即提交Offset。这种批量提交策略有助于减少与Kafka Broker之间的通信开销,同时也能保证了整体消费进度的一致性。

        在broker端,可以通过write-behind等技术,将多次磁盘操作合并为一个,减少刷盘操作。

        这是Kafka高性能的第二个原因

三、页缓存技术

        页缓存是操作系统实现的一种主要的磁盘缓存,以此用来减少对磁盘I/O的操作。具体来说就是把磁盘中的数据缓存到内存中,把对磁盘的访问变为对内存的访问。

        当一个进程准备读取磁盘上的文件时,操作系统会先查看读取的数据所在的页(page)是否在页缓存(pagecache)中,如果存在则直接返回数据,从而避免了对物理磁盘的I/O操作;如果没有命中,则操作系统会像磁盘发起读取请求并将读取的数据页存入页缓存,之后再将数据返回给进程。同样一个进程需要将数据写入磁盘,那么操作系统也会检测数据对应的页是否在页缓存中,如果不存在则会先在页缓存中添加相应的页,最后将数据写入对应的页。被修改的页也就变成了脏页,操作系统会在合适的时间把脏页写入磁盘,以保持数据的一致性。

        Linux操作系统中vm.dirty_background_ratio参数用来指定当脏页数量达到系统内存的百分之多少后会触发pdflush/flush/kdmflush等后台回写进程的运行来处理脏页。

        kafka中大量的使用了页缓存,这也是kafka实现高吞吐量的重要因素之一。虽然消息都是先被写入页缓存,然后由操作系统负责具体的刷盘任务,但在kafka中同样提供了同步刷盘即阶段性强制刷盘(fsyc)的功能。

        这是Kafka高性能的第三个原因。但有一种情况需要引起注意,会导致页缓存失效。在kafka出现严重挤压时,生产者开始时的确是把消息写入到了页缓存,但由于消费者处理速度过慢,挤压严重,那页缓存中的数据会不断的被置换到磁盘上,当消费者消费消息时,可能需要从磁盘读取了,这对性能是极大的损耗,所以要尽量避免kafka出现严重的积压情况。

四、零拷贝技术

        磁盘可以说是计算机系统最慢的硬件之一,读写速度相差内存10倍以上,所以针对磁盘的优化技术非常多,比如零拷贝、直接I/O、异步I/O等等,这些优化的目的是为了提高系统的吞吐量,这里主要介绍零拷贝。

        我们以文件传输作为切入点,来分析I/O工作方式,以及如何优化传输文件的性能。

        4.1 DMA 技术

        在没有DMA技术前,I/O是这样工作的:               

  1. CPU发出对应的指令给磁盘控制器,然后返回;
  2. 磁盘控制器收到指令后,开始准备数据,会把数据放到磁盘控制器的内部缓冲区中,然后产生一个中断;
  3. CPU收到中断信号后,停下手头的工作,接着把磁盘控制器的缓冲区的数据一次一个字节地读进自己的寄存器,然后再把寄存器里的数据写入到内存,而在数据传输的期间,CPU无法执行其他任务。

        

        可以看到整个数据传输过程,都需要CPU亲自参与搬运数据的过程,而且这个过程,CPU是不能做其他事情的。简单的搬运几个字符数据是没问题的,但是如果我们用千兆网卡或者硬盘传输大量数据的时候,都用CPU来搬运的话,肯定忙不过来。

        于是DMA技术就诞生了,也就是直接内存访问(Direct Memory Acess)技术。简单理解就是,DMA方式无需处理器的干预,在内存与I/O之间进行快速数据交换。在进行I/O设备的内存的数据传输的时候,数据搬运工作全部交给DMA控制器,而CPU不在参与任何数据搬运相关的事情,这样CPU就可以去处理别的事情。

  1. 用户进程调用read方法,向操作系统发出I/O请求,请求读取数据到自己的内存中,进程进入阻塞状态;
  2. 操作系统收到请求后,进一步将I/O请求发送到DMA,然后让CPU执行其他任务;
  3. DMA进一步将I/O请求发送给磁盘;
  4. 磁盘收到DMA的I/O请求,把数据从磁盘读取到磁盘控制器的缓冲区中,当磁盘控制器的缓冲区被读满后,向DMA发起中断信号,告知自己缓冲区已满;
  5. DMA收到磁盘的信号,将磁盘控制器缓冲区中的数据拷贝到内核缓冲区中,此时不占用CPU,CPU可以执行其他任务;
  6. 当DMA读取了足够多的数据,就会发送中断信号给CPU;
  7. CPU收到DMA的信号,知道数据已经准备好,于是将数据从内核拷贝到用户空间,系统调用返回。

        可以看到,整个数据传输过程,CPU不在参与数据搬运的工作,而是全程由DMA完成,但是CPU在这个过程中也是必不可少的,因为传输什么数据,从哪里传输到哪里,都需要CPU来告诉DMA控制器。

        4.2 文件传输

        如果服务端要提供文件传输功能,我们能想到的最简单的方式:将磁盘上的文件读取出来,然后通过网络协议发送给客户端。

        传统I/O的工作方式是,数据读取和写入是从用户空间到内核空间来回复制,内核空间的数据是通过操作系统层面的I/O接口从磁盘读取或写入的。

        首先,期间共发生了4次用户态与内核态的上下文切换,因为发生了两次系统调用,一次是read,一次是write,每次系统调用都得先从用户态切换到内核态,等内核完成任务后,再从内核态切换会用户态。

        上线文切换成本并不小,一次切换需要耗时几十纳秒到几微妙,虽然看上去时间很短,但是在高并发的场景下,这类时间容易被累计放大,从而影响系统整体性能。

        其次,发生了四次数据拷贝,其中两次是DMA的拷贝,另外两次则是通过CPU拷贝的:

  1. 第一次拷贝:把磁盘上的数据拷贝到操作系统内核的缓冲区里,这个拷贝过程是通过DMA搬运的。
  2. 第二次拷贝:把内核缓冲区的数据拷贝到用户的缓冲区里,于是我们应用程序就可以使用这部分数据了,这个拷贝过程则是由CPU完成的。
  3. 第三次拷贝:把刚拷贝到用户缓冲区里的数据再拷贝到内核socket的缓冲区里,这个过程依然是CPU完成的。
  4. 第四次拷贝:把内核socket缓冲区里的数据,拷贝到网卡缓冲区里,这个过程又是由DMA搬运的。

        看这个文件的传输过程,我们只是搬运一份数据,结果却搬运了4次,过多的数据拷贝无疑会消耗CPU资源,大大降低系统性能。

        这种简单又传统的方式,存在冗余的上下文切换和数据拷贝,在高并发系统里是非常糟糕的,多了很多不必要的开销,会严重影响系统性能。所以要想提高文件传输的性能,就要减少用户态与内核态的上下问切换与内存拷贝的次数。

        4.3 零拷贝

        Linux 内核从 2.4 版本开始,对于网卡支持SG-DMA技术的情况下,sendFile()系统调用的过程发生了变化。

  1. 通过DMA将磁盘上的数据拷贝到内核缓冲区中;
  2. 缓冲区描述符和数据长度传输到socket缓冲区,这样网卡的SG-DMA控制器就可以直接将内核缓冲区中的数据拷贝到网卡缓冲区里,此过程不需要将数据从操作系统内科拷贝到socket缓冲区。​​​​​​​

        就是所谓的零拷贝技术,因为我们没有在内存层面去拷贝数据,也就是全程没有通过CPU来搬运数据,所有的数据都通过DMA来进行传输。与传统方式相比,减少了两次上下文切换和数据拷贝次数,只需要两次上下文切换就可以完成文件传输,而且两次数据拷贝都不要CPU的参与,所以,零拷贝技术可以把文件传输的性能提高至少一倍以上。

        kafka在数据传输中尽可能减少数据复制环节,利用操作系统提供的零拷贝技术,将数据直接从文件缓存区传递到网络协议栈,降低了CPU开销和延迟。这是kafka高性能的第四个原因

五、分区并行处理

        这个很好理解,Kafka将主题拆分为多个分区,并且可以在不同的broker节点上分布这些分区,实现了并行处理能力,从而能够扩展以应对高并发场景下的读写需求。

        这是kafka高性能的第五个原因

六、高效的消息压缩

        支持消息压缩功能,在不影响消息传递速度的同时降低网络带宽消耗,进一步提升整体性能。

        常见的压缩算法是数据量越大压缩效果越好,一条消息通常不会太大,这就导致压缩效果不太好。而Kafka实现的压缩方式是将多条消息一起进行压缩,这样可以保证比较好的压缩效果。        

        producer将消息进行压缩,发往broker,broker保存消息。这里需要注意,producer和broker的压缩算法要一致,broker端有参数可以配置压缩算法,默认值是producer即保持生产者的压缩算法。如果两端的压缩算法不一致,producer用一种压缩算法,发到broker后 broker需要对压缩消息进行解压,解压后在按照broker设置的压缩算法进行压缩,然后在保存,多了许多额外的操作,会导致broker的CPU变高,导致吞吐量下降,效率降低。消费者与broker有同样的问题。常用的压缩算法有GZIO、SNAPPY、LZ4。

        将多条消息进行压缩处理,这是kafka高性能的第六个原因

七、总结

        关于kafka高性能的原因就介绍到这里,不知道你学会了吗,欢迎留言讨论。

相关文章:

揭秘 Kafka 高性能之谜:一文读懂背后的设计精粹与技术实现

Kafka在性能方面有着显著的优势,这也使得Kafka的应用非常广泛,那kakfa的性能为何如此优异呢?本文将带你探寻kafka高性能之谜。 kafka的高性能概括起来有如下几点:顺序写入磁盘与I/O优化、批量处理、页缓存、零拷贝技术、分区并行处…...

canvas绘制美国国旗(USA Flag)

查看专栏目录 canvas实例应用100专栏,提供canvas的基础知识,高级动画,相关应用扩展等信息。canvas作为html的一部分,是图像图标地图可视化的一个重要的基础,学好了canvas,在其他的一些应用上将会起到非常重…...

Python中的`__all__`魔法函数使用详解

概要 Python是一门灵活而强大的编程语言,提供了各种机制来控制模块的导入和访问。其中,__all__魔法函数是一种用于限制模块导入的机制,可以明确指定哪些变量、函数或类可以被导入。本文将深入探讨__all__的作用、用法以及示例,以…...

Studio One 6 mac 6.5.2 激活版 数字音乐编曲创作

PreSonus Studio One是PreSonus出品的一款功能强大的音乐创作软件。主要为用户提供音乐创作、录音、编辑、制作等功能。它可以让你创造音乐,无限的轨道,无限的MIDI和乐器轨道,虚拟乐器和效果通道,这些都是强大和完美的。 软件下载…...

GitHub图床TyporaPicGo相关配置

本文作者: slience_me 文章目录 GitHub图床&Typora&PicGo相关配置1. Github配置2. picGo配置3. Typora配置 GitHub图床&Typora&PicGo相关配置 关于Typora旧版的百度网盘下载路径 链接:https://pan.baidu.com/s/12mq-dMqWnRRoreGo4MTbKg?…...

FireAlpaca:轻量级、免费的Mac/Win绘图软件,让你的创意如火燃烧!

FireAlpaca是一款轻量级、免费的绘图软件,适用于Mac和Win系统,让你的创作过程更加快捷、简便。无论是绘制漫画、插图、设计作品还是进行简单的图片编辑,FireAlpaca都能满足你的需求。 首先,FireAlpaca具有直观友好的用户界面&…...

用 Python 制作可视化 GUI 界面,一键实现自动分类管理文件!

经常杂乱无章的文件夹会让我们找不到所想要的文件,因此小编特意制作了一个可视化GUI界面,通过输入路径一键点击实现文件分门别类的归档。 不同的文件后缀归类为不同的类别 我们先罗列一下大致有几类文件,根据文件的后缀来设定,大…...

【STM32】USB程序烧录需要重新上电 软件复位方法

文章目录 一、问题二、解决思路2.1 直接插拔USB2.2 给芯片复位 三、解决方法3.1 别人的解决方法3.2 在下载界面进行设置 一、问题 最近学习STM32的USB功能,主要是想要使用虚拟串口功能(VCP),发现每次烧录之后都需要重新上电才可以…...

Java数据结构与算法:图算法之深度优先搜索(DFS)

Java数据结构与算法:图算法之深度优先搜索(DFS) 大家好,我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编,一个热爱编程的程序猿。今天,让我们一起探索图算法中的深度优先搜索(DFS&…...

SpringBoot整合QQ邮箱发送验证码

一、QQ开启SMTP 打开QQ邮箱&#xff0c;点击设置&#xff0c;进入账号&#xff0c;往下滑后&#xff0c;看见服务状态后&#xff0c;点击管理服务 进入管理服务后&#xff0c;打开服务&#xff0c;然后获取授权码 二 、导入依赖 <!-- 邮箱--><dependency>&…...

云虚拟主机怎么修改代码?如何修改部署在虚拟主机的网站代码?

很多站长成功创建网站之后&#xff0c;或多或少都会对网站代码进行适当修改。比如boke112百科使用YIA主题后&#xff0c;也根据自己的需要进行了多个方面的小修改。 那么如果网站是部署在虚拟主机上的&#xff0c;那么应该如何修改这些网站代码呢&#xff1f;其实&#xff0c;…...

电脑加固态硬盘有什么好处

电脑加固态硬盘有很多好处&#xff0c;以下是一些主要的优点&#xff1a; 1. 启动速度更快&#xff1a;固态硬盘&#xff08;SSD&#xff09;的启动速度比传统机械硬盘&#xff08;HDD&#xff09;快得多。这是因为固态硬盘没有旋转部件&#xff0c;而传统硬盘的读写头需要不断…...

LabVIEW电火花线切割放电点位置

介绍了一个电火花线切割放电点位置分布评价系统&#xff0c;特别是在系统组成、硬件选择和LabVIEW软件应用方面。 本系统由两个主要部分组成&#xff1a;硬件和软件。硬件部分包括电流传感器、高速数据采集卡、开关电源、电阻和导线。软件部分则由LabVIEW编程环境构成&#xf…...

信通院发布《全球数字经济白皮书 (2023年)》解析

文章目录 前言一、白皮书目录二、白皮书核心观点(一)主要国家优化政策布局,数字经济政策导向更加明晰、体系更加完善(二) 数字经济加速构筑经济复苏关键支撑(三)全球数字经济多极化趋势进一步深化(四)数字经济重点领域发展成效显著三、白皮书的主要内容前言 当前,世…...

Spring5系列学习文章分享---第三篇(AOP概念+原理+动态代理+术语+Aspect+操作案例(注解与配置方式))

目录 AOP概念AOP底层原理AOP(JDK动态代理)使用 JDK 动态代理&#xff0c;使用 Proxy 类里面的方法创建代理对象**编写** **JDK** 动态代理代码 AOP(术语)AOP操作&#xff08;准备工作&#xff09;**AOP** **操作&#xff08;**AspectJ注解)**AOP** **操作&#xff08;**AspectJ…...

BL0942 内置时钟免校准计量芯片 用于智能家居领域 上海贝岭 低成本 使用指南

BL0939是上海贝岭股份有限公司开发的一款用于智能家居领域进行电能测量的专用芯片&#xff0c;支持两路测量&#xff0c;可同时进行计量和漏电故障检测&#xff0c;漏电检测电流可设&#xff0c;响应时间快&#xff0c;具有体积小&#xff0c;外围电路简单&#xff0c;成本低廉…...

【算法专题】动态规划之路径问题

动态规划2.0 动态规划 - - - 路径问题1. 不同路径2. 不同路径Ⅱ3. 珠宝的最高价值4. 下降路径最小和5. 最小路径和6. 地下城游戏 动态规划 - - - 路径问题 1. 不同路径 题目链接 -> Leetcode -62.不同路径 Leetcode -62.不同路径 题目&#xff1a;一个机器人位于一个 m …...

Python range函数

Python中的range()函数是一个强大的工具&#xff0c;用于生成一系列的整数。它在循环、迭代和序列生成等方面都有广泛的应用。本文将深入探讨range()函数的用法&#xff0c;提供详细的示例代码&#xff0c;并讨论其在Python编程中的实际应用。 什么是range()函数&#xff1f; …...

Unity中实现捏脸系统

前言 目前市面上常见的捏脸一般是基于BlendShapes和控制骨骼点坐标两种方案实现的。后者能够控制的精细程度更高&#xff0c;同时使用BlendShapes来控制表情。 控制骨骼点坐标 比如找到控制鼻子的骨骼节点修改localScale缩放&#xff0c;调节鼻子大小。 BlendShapes控制表…...

openssl3.2 - 检查rsa证书和私钥是否匹配(快速手搓一个工具)

文章目录 openssl3.2 - 检查rsa证书和私钥是否匹配(快速手搓一个工具)概述效果笔记编程环境界面控件的设置增加文件拖拽的类RSA证书和key是否匹配的实现在程序中加入环境变量备注备注END openssl3.2 - 检查rsa证书和私钥是否匹配(快速手搓一个工具) 概述 在学习openssl官方的…...

关于网络协议的笔记

简介&#xff1a; 协议&#xff0c; 网络协议的简称&#xff0c;网络协议是通信计算机双方必须共同遵从的一组约定。如怎么样建立连 接、怎么样互相识别等。只有遵守这个约定&#xff0c;计算机之间才能相互通信交流。它的 三要素是&#xff1a;语 法、语义、时序。 为了使数…...

【江科大】STM32:USART串口(理论部分)上

串口 全双工&#xff1a;可以进行同步通信 单端信号&#xff1a;信号线传输的就是单端信号。&#xff08;也就是与地线&#xff08;GND&#xff09;的电势差&#xff09; 缺点&#xff1a;防干扰能力差 原因&#xff1a;当信号从A点传输到B点&#xff0c;理想条件是A&#xff0…...

深入了解Linux中常见的五种文件类型

了解文件类型对于正确理解和管理文件系统非常重要。希望本文能够帮助您更好地了解Linux中常见的文件类型及其在ls -l命令输出中的表示方式。​ 在Linux操作系统中&#xff0c;文件是操作系统中最基本的概念之一。在Linux中&#xff0c;每个文件都有一个特定的类型&#xff0c;这…...

SSM项目集成Spring Security 4.X版本(使用spring-security.xml 配置文件方式)

目录 前言 实战开发&#xff1a; 一、Spring Security整合到SSM项目 1. pom文件引入包 2. web.xml 配置 3. 添加 spring-security.xml 文件 二、Spring Security实战应用 1. 项目结构 2. pom文件引入 3. web.xml 配置 4. Spring 配置 applicationContext.xml 5. sp…...

如何生成开发语言的排名图表

1、解释说明 生成开发语言排名图表&#xff0c;通常需要以下几个步骤&#xff1a; - 首先&#xff0c;我们需要收集一些关于不同编程语言的统计数据&#xff0c;例如使用人数、市场份额等。这些数据可以从各种来源获取&#xff0c;例如网站、报告、数据库等。 - 然后&#x…...

有哪些简单好用、适合中小型企业的CRM系统?

阅读本文&#xff0c;你将了解&#xff1a;一、中小型企业对CRM系统的主要需求&#xff1b;二、盘点四款好用的CRM系统&#xff1b;三、CRM系统实施策略和优秀实践。 在快速变化的商业环境中&#xff0c;中小型企业面临着独特的挑战&#xff1a;如何在有限的资源下高效地管理客…...

Unity 适配器模式(实例详解)

文章目录 简介1. **Input Adapter 示例**2. **Component Adapter 示例**3. **网络数据解析适配器**4. **物理引擎适配**5. **跨平台服务适配** 简介 Unity中的适配器模式&#xff08;Adapter Pattern&#xff09;主要用于将一个类的接口转换为另一个接口&#xff0c;以便于原本…...

Spring boot项目java bean和xml互转

Spring boot项目实现java bean和xml互转 项目场景&#xff1a;互转方法使用jackson进行互转使用jaxws进行xml与bean的互转 搞定收工&#xff01; 项目场景&#xff1a; 工作中需要给下游第三方收费系统做数据挡板&#xff0c;由于下游系统使用的是soap webservice,里面涉及各种…...

数字证书和数字证书认证机构和数字根证书,CA,RCA

文章目录 一、 数字证书1、什么是数字证书2、数字证书干什么的3、风险 二、数字证书认证机构&#xff08;Certificate Authority&#xff0c;缩写为CA&#xff09;参考文章 一、 数字证书 维基百科 公开密钥认证&#xff08;英语&#xff1a;Public key certificate&#xff…...

java web mvc-08-Grails 入门介绍

拓展阅读 Spring Web MVC-00-重学 mvc mvc-01-Model-View-Controller 概览 web mvc-03-JFinal web mvc-04-Apache Wicket web mvc-05-JSF JavaServer Faces web mvc-06-play framework intro web mvc-07-Vaadin web mvc-08-Grails 开源 The jdbc pool for java.(java …...