Kafka 零拷贝(Zero-Copy)技术详解

文章目录

    • 1. 什么是零拷贝
    • 2. Kafka 如何实现零拷贝
      • 2.1 sendfile 系统调用
      • 2.2 mmap 内存映射
    • 3. 传统拷贝 vs 零拷贝
      • 3.1 传统文件传输流程
      • 3.2 零拷贝文件传输流程
    • 4. Kafka 零拷贝的具体实现
      • 4.1 消息消费时的零拷贝
      • 4.2 日志段文件的零拷贝
    • 5. 零拷贝带来的性能优势
    • 6. 零拷贝的适用场景
    • 7. Kafka 零拷贝的局限性
    • 8. 性能对比数据
    • kafka 的零拷贝原理

1. 什么是零拷贝

零拷贝(Zero-Copy)是一种高效的数据传输技术,它允许数据在不需要CPU参与拷贝的情况下,直接从存储设备传输到网络接口卡(NIC)。在传统的数据传输过程中,数据需要在用户空间和内核空间之间多次拷贝,而零拷贝技术可以显著减少这些不必要的拷贝操作。

2. Kafka 如何实现零拷贝

Kafka 主要通过以下两种机制实现零拷贝:

2.1 sendfile 系统调用

Kafka 使用 Linux 的 sendfile() 系统调用实现零拷贝:

#include <sys/sendfile.h>ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);

工作流程:

  1. 磁盘文件通过 DMA 拷贝到内核缓冲区(Page Cache)
  2. 内核缓冲区直接通过 DMA 拷贝到网卡缓冲区
  3. 整个过程完全在内核空间完成,避免了用户空间和内核空间之间的数据拷贝

2.2 mmap 内存映射

Kafka 日志文件的索引(.index 和 .timeindex 文件)使用内存映射(mmap)技术:

// Kafka 中 mmap 的实现
this.index = new MappedByteBuffer(indexFile.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, indexFile.length())
);

3. 传统拷贝 vs 零拷贝

3.1 传统文件传输流程

1. 磁盘 -> 内核缓冲区 (DMA 拷贝)
2. 内核缓冲区 -> 用户缓冲区 (CPU 拷贝)
3. 用户缓冲区 -> socket 缓冲区 (CPU 拷贝)
4. socket 缓冲区 -> 网卡 (DMA 拷贝)

共涉及:4 次上下文切换 + 2 次 CPU 拷贝 + 2 次 DMA 拷贝

3.2 零拷贝文件传输流程

1. 磁盘 -> 内核缓冲区 (DMA 拷贝)
2. 内核缓冲区 -> 网卡 (DMA 拷贝)

共涉及:2 次上下文切换 + 0 次 CPU 拷贝 + 2 次 DMA 拷贝

4. Kafka 零拷贝的具体实现

4.1 消息消费时的零拷贝

Kafka 消费者获取消息时,Broker 使用 FileChannel.transferTo() 方法(底层调用 sendfile):

// Kafka 中的实现
public long transferFrom(FileChannel fileChannel, long position, long count) throws IOException {return fileChannel.transferTo(position, count, socketChannel);
}

4.2 日志段文件的零拷贝

Kafka 的日志段(LogSegment)使用 FileChannelMappedByteBuffer

// Kafka LogSegment 部分源码
val logFile = new File(dir, filename + LogFileSuffix)
val channel = new RandomAccessFile(logFile, "rw").getChannel()
val mappedByteBuffer = channel.map(FileChannel.MapMode.READ_WRITE, 0, maxSegmentSize)

5. 零拷贝带来的性能优势

  1. 减少 CPU 使用率:避免了不必要的 CPU 拷贝操作
  2. 减少内存带宽占用:数据不需要在用户空间和内核空间之间来回拷贝
  3. 提高吞吐量:减少了数据传输路径上的延迟
  4. 降低上下文切换:减少了用户态和内核态之间的切换次数

6. 零拷贝的适用场景

  1. 大文件传输
  2. 高吞吐量的消息系统(如 Kafka)
  3. 静态内容服务器(如 Nginx)
  4. 视频流媒体服务

7. Kafka 零拷贝的局限性

  1. 不适合小文件:零拷贝的优势在大文件传输时更明显
  2. 需要操作系统支持:依赖于 Linux 的 sendfile 和 mmap
  3. 内存映射的缺陷:mmap 可能导致内存占用过高
  4. 不能修改数据:零拷贝通常是只读操作

8. 性能对比数据

指标传统拷贝零拷贝提升幅度
CPU 使用率50-70%
吞吐量2-3 倍
内存占用30-50%
延迟30-40%

Kafka 通过零拷贝技术实现了极高的吞吐量(可达百万级 QPS),这也是 Kafka 能够成为高性能消息系统的关键设计之一。

kafka 的零拷贝原理

零拷贝是一种减少数据拷贝的机制,能够有效提升数据的效率
它的原理是:将磁盘文件映射到内存,用户通过修改内存就能修改磁盘文件。使用这种方式可以获取很大的 I/O 提升,省去了用户空间到内核空间复制的开销。

零拷贝指计算机执行 IO 操作时,CPU 不需要将数据从一个存储区域复制到另一个存储区域,从而可以减少上下文切换以及 CPU 拷贝时间。一种I/O 操作优化技术。
传统的IO编写的,它的执行过程大致是这样的:
1、从磁盘中读取目标文件内容拷贝到内核缓冲区
2、CPU控制器再把内核缓冲区的数据赋值到用户空间的缓冲区中
3、接着在应用程序中,调用write()方法,把用户空间缓冲区中的数据拷贝到内核下的Socket Buffer中。
4、最后,把在内核模式下的SocketBuffer中的数据赋值到网卡缓冲区(NIC Buffer)
5、网卡缓冲区再把数据传输到目标服务器上。
在这个过程中我们可以发现,数据从磁盘到最终发送出去,要经历4次拷贝,而在这四次拷贝过
程中,有两次拷贝是浪费的,分别是:
1、从内核空间赋值到用户空间
2、从用户空间再次复制到内核空间
除此之外,由于用户空间和内核空间的切换会带来CPU的上线文切换,对于CPU性能也会造成性能影响。
而零拷贝,就是把这两次多于的拷贝省略掉,应用程序可以直接把磁盘中的数据从内核中直接传输给Socket,而不需要再经过应用程序所在的用户空间

零拷贝通过DMA(Direct Memory Access)技术把文件内容复制到内核空间中的Read Buffer,
接着把包含数据位置和长度信息的文件描述符加载到Socket Buffer中,DMA引擎直接可以把
数据从内核空间中传递给网卡设备。在这个流程中,数据只经历了两次拷贝就发送到了网卡中,并且减少了2次cpu的上下文切换,对于效率有非常大的提高。
在程序中实现零拷贝的方式有三种:
1、在Linux中,零拷贝技术依赖于底层的sendfile()方法实现
2、在Java中,FileChannal.transferTo() 方法的底层调用的就是 sendfile() 方法。
3、MMAP 文件映射机制。它的原理是,将磁盘文件映射到内存, 用户通过修改内存就能修改磁盘文件。使
用这种方式可以获取很大的I/O提升,省去了用户空间到内核空间复制的开销。

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

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

相关文章

Vue 中 v-for 的使用及 Vue2 与 Vue3 的区别

v-for 基本用法v-for 是 Vue 中用于循环渲染列表的指令&#xff0c;基本语法如下&#xff1a;运行<!-- Vue2 和 Vue3 通用基本语法 --> <div v-for"(item, index) in items" :key"item.id">{{ index }} - {{ item.name }} </div>Vue2 和…

本地搭建dify+deepseek智能体

今天开始搭建智能体&#xff0c;学习一下&#xff0c;也是公司转型所需。(Windows下的docker安装给我差点干破防了&#xff0c;安装了一周docker才成功。我真就要放弃的时候&#xff0c;又意外成功了/(ㄒoㄒ)/~~)0、准备阶段 配置Windows10的基本配置。 按下键盘Windows键&…

网络常识-SSE对比Websocket

SSE&#xff08;Server-Sent Events&#xff09;和Websocket都是用于实现服务器与客户端实时通信的技术&#xff0c;但它们的设计理念、通信模式和适用场景有显著区别。以下从核心差异和适用场景两方面具体说明&#xff1a; 一、核心区别维度SSE&#xff08;Server-Sent Events…

lamp架构部署wordpress

CentOS 7主机&#xff1a;lamp.example.comIP&#xff1a;192.168.100.101、关闭防火墙与selinux# 关闭防火墙systemctl stop firewalldsystemctl disable firewalld# 关闭selinuxvim /etc/selinux/config # 或vim /etc/sysconfig/selinuxSELINUXdisabled:wq# 重启reboot 2、开…

DC6v-36V转3.2V1A恒流驱动芯片WT7017

DC6v-36V转3.2V1A恒流驱动芯片WT7017WT7017是一款于连续工作模式下的降压LED恒流转换器&#xff0c;可驱动单只或多只LED,内置高精度电流检测器&#xff0c;能通过外置电阻设定输出电流,开关式1A恒流芯片。软启动、高达1MHZ开关频率,开路保护,输入范围在6V-40VDC内都能稳定可靠…

js如何循环HTMLCollection

场景 当使用document.getElementsByClassName方法获取一个包含DOM节点的集合arr时&#xff0c;正常的forEach和map操作都会报一个arr.map is not a function的错误因为这里的arr并不是标准的 数组 (Array)&#xff0c;而是一个 HTMLCollection 解决 使用document.querySelector…

Dart 逆袭之路:Flutter 4.0 如何推动移动端开发变革?

本文深入探讨 Dart 语言在 Flutter 4.0 框架下如何推动移动端开发变革。开篇回顾 Dart 诞生背景与初期困境&#xff0c;阐述其在与 Flutter 结合后崭露头角。进而详细剖析 Flutter 4.0&#xff0c;从全新渲染引擎带来的性能飞跃、丰富实用新组件简化开发&#xff0c;到手势系统…

基于MATLAB的卷积神经网络手写数字识别

一、系统架构设计 #mermaid-svg-QQU8judlmQgHc2Lh {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-QQU8judlmQgHc2Lh .error-icon{fill:#552222;}#mermaid-svg-QQU8judlmQgHc2Lh .error-text{fill:#552222;stroke:#5…

从废弃到珍宝——旧物二手回收小程序系统的价值发现之旅

在我们的生活中&#xff0c;总有一些旧物因为各种原因而被遗弃在角落&#xff0c;它们或许不再新潮&#xff0c;或许不再实用&#xff0c;但它们却承载着我们的记忆和情感。旧物二手回收小程序系统的出现&#xff0c;让这些被遗忘的旧物重新焕发了生机&#xff0c;开启了一段从…

从0开始学习Java+AI知识点总结-16.web基础知识

一、SpringBoot Web 入门开发SpringBoot 简化了传统 Spring 应用的配置流程&#xff0c;通过 "约定大于配置" 的理念实现快速开发。以下是入门核心要点&#xff1a;1. 工程创建与依赖配置工程初始化&#xff1a;通过 Spring Initializr 创建工程&#xff0c;选择Spri…

代码随想录Day51:图论(岛屿数量 深搜广搜、岛屿的最大面积)

一、实战 99岛屿数量 深搜 99. 岛屿数量 本题中每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成&#xff0c;也就是说斜角度链接是不算的。思路是用遇到一个没有遍历过的节点陆地&#xff0c;计数器就加一&#xff0c;然后把该节点陆地所能遍历到的陆地都标记上。在…

读取数据excel

import pandas as pd from datetime import datetimedef generate_questions():excel_path df pd.read_excel(excel_path)theme []time_list []tag1 []tag2 []tag3 []word_count 800questions []for index, row in df.iterrows():if isinstance(row[时间], datetime):…

前端环境安装

1.vsCode 下载链接&#xff1a;Visual Studio Code - Code Editing. Redefined 添加一个wiz code扩展&#xff08;提示你需要升级的依赖&#xff09; wiz code 使用方法 效果 2.git 下载链接&#xff1a;Git - Downloads 先下载 Homebrew&#xff08;https://brew.sh/ &a…

零基础学Java第十八讲---抽象类和接口(3)

续接上一讲 目录 一、内部类 1、内部类的分类 2、静态内部类 3、实例内部类---未被static修饰的成员内部类 4、局部内部类 5、匿名内部类 二、Object类 1、获取对象信息 2、equals方法 3、hashcode方法 一、内部类 当⼀个事物的内部&#xff0c;还有⼀个部分需要⼀个…

字节数据流

记录 干货&#xff5c;8000字长文&#xff0c;深度介绍Flink在字节跳动数据流的实践 字节跳动基于Flink的MQ-Hive实时数据集成

Vision Master的C#脚本与opencv联合编程

需要在VM的C#脚本设置string类型Out变量和float类型OutF变量&#xff0c;python的输出信息会在Out变量显示 using System; using System.IO; using Script.Methods; using System.Diagnostics; using System.Net.Sockets; using System.Text; using System.Threading;public pa…

运维工作架构流程搭建

前言 在解决了运维是干什么的&#xff0c;运维的工作的意义后&#xff0c;这一章我们系统性的讲讲运维工作流程搭建&#xff0c;希望大家能通过我的分享有所收获&#xff0c;这一章干货满满。 一、网络服务器架构 按照一般的访问方式&#xff0c;按照我自己的理解画了一个网络服…

安全存储之 SAES+HUK 使用技巧和常见问题 LAT1543

关键字&#xff1a;AES&#xff0c;SAES, HUK, DHUK, 安全存储 引言 近年来&#xff0c;嵌入式设备信息安全被越来越多地提及&#xff0c;从智能穿戴产品、智能工业设备到物联网产品都对设备信息安全提出了要求&#xff0c;比如基础的安全启动&#xff0c;安全升级&#xff0…

ubuntu 20.04 搭建多用户远程桌面共享及同时在线使用

使用效果: 物理机: 远程桌面用户: 实现过程: 1.使用脚本安装xrdp并修改配置及启动服务 setup_xrdp.sh sudo apt update sudo apt install xrdp -ysudo systemctl enable xrdp sudo systemctl start xrdp#sudo vim /etc/xrdp/startwm.sh #unset DBUS_SESSION_BUS_ADDRES…

[激光原理与应用-287]:理论 - 波动光学 - 电磁波既能承载能量,又能承载信息?

电磁波既能承载能量&#xff0c;又能承载信息&#xff0c;这一特性源于其物理本质和调制技术的结合。以下从能量承载和信息承载两方面进行详细解析&#xff1a;一、电磁波如何承载能量&#xff1f;电磁波的能量承载源于其电场和磁场的周期性振荡&#xff0c;具体机制如下&#…