詳細說明零拷貝

詳細說明零拷貝

  • 【一】零拷貝介紹
    • 【1】說明
    • 【2】為什么需要零拷貝?—— 傳統數據傳輸的問題
    • 【3】零拷貝的核心優化
    • 【4】零拷貝的實現方式
      • (1)mmap(內存映射)
      • (2)sendfile(Linux 系統調用)
      • (3)其他零拷貝實現
    • 【5】零拷貝的核心價值
  • 【二】NIO的零拷貝MappedByteBuffer(內存映射文件)
  • 【三】Kafka的零拷貝
  • 【四】Nginx的零拷貝

【一】零拷貝介紹

【1】說明

零拷貝(Zero-Copy)是一種減少數據在內存中不必要復制的技術,核心目標是在數據傳輸(如文件讀寫、網絡發送)過程中,避免 CPU 參與冗余的數據拷貝操作,從而提升性能(減少 CPU 占用、降低內存帶寬消耗、減少用戶態與內核態切換開銷)。

【2】為什么需要零拷貝?—— 傳統數據傳輸的問題

在傳統數據傳輸流程中(例如 “從磁盤文件讀取數據并通過網絡發送”),數據需要經過多次拷貝和狀態切換,效率極低。以下是具體流程:

傳統流程(以 “讀取文件并發送到網絡” 為例):
(1)第一次拷貝(DMA 拷貝):CPU 發起 DMA(直接內存訪問)請求,磁盤控制器將數據從磁盤讀取到內核緩沖區(內核態內存),此過程不占用 CPU。
(2)第二次拷貝(CPU 拷貝):數據從內核緩沖區拷貝到用戶緩沖區(用戶態內存),此時 CPU 參與拷貝,用戶進程可訪問數據。
(3)第三次拷貝(CPU 拷貝):用戶進程將數據從用戶緩沖區拷貝到Socket 緩沖區(內核態中為網絡傳輸準備的緩沖區),CPU 再次參與。
(4)第四次拷貝(DMA 拷貝):DMA 將 Socket 緩沖區的數據發送到網絡接口(如網卡),不占用 CPU。

額外開銷:
(1)用戶態與內核態切換:步驟 1→2(內核態→用戶態)、步驟 2→3(用戶態→內核態),每次切換需保存 / 恢復寄存器、刷新 TLB 等,開銷較大。
(2)CPU 冗余拷貝:步驟 2 和步驟 3 的拷貝由 CPU 執行,會占用 CPU 資源,尤其在大文件或高并發場景下,會成為性能瓶頸。

【3】零拷貝的核心優化

零拷貝并非 “完全不拷貝”(數據最終仍需從源設備到目標設備),而是減少 CPU 參與的拷貝次數(保留必要的 DMA 拷貝,因 DMA 不占用 CPU),并減少用戶態與內核態的切換。

【4】零拷貝的實現方式

不同操作系統(如 Linux、Windows)提供了多種零拷貝機制,以下是最常用的幾種:

(1)mmap(內存映射)

原理:將內核緩沖區與用戶緩沖區映射到同一塊物理內存,使用戶進程可直接訪問內核緩沖區,避免 “內核緩沖區→用戶緩沖區” 的 CPU 拷貝。

流程(以 “讀文件并發送網絡” 為例):
(1)磁盤數據通過 DMA 拷貝到內核緩沖區。
(2)調用mmap()將內核緩沖區與用戶進程的虛擬地址空間映射(無數據拷貝,僅建立地址映射關系)。
(3)用戶進程直接操作 “映射后的內存”(本質是內核緩沖區),無需拷貝到用戶緩沖區。
(4)數據從內核緩沖區拷貝到 Socket 緩沖區(CPU 拷貝),再通過 DMA 發送到網絡。

優勢:
(1)減少 1 次 CPU 拷貝(省去 “內核→用戶” 的拷貝)。
(2)用戶態與內核態切換次數從 2 次減少到 1 次(僅mmap()和write()各 1 次切換)。

缺點:
(1)仍存在 “內核緩沖區→Socket 緩沖區” 的 CPU 拷貝。
(2)若映射的文件被修改,可能導致用戶進程崩潰(需謹慎處理)。

應用:
(1)大文件讀寫(如數據庫表文件映射)。
(2)Kafka 的日志文件讀寫(通過 mmap 將磁盤文件映射到內存,提升讀寫效率)。

(2)sendfile(Linux 系統調用)

原理:直接在內核空間完成數據從文件到網絡的傳輸,完全避免用戶態參與,減少 CPU 拷貝和狀態切換。

流程(以 “讀文件并發送網絡” 為例):
(1)磁盤數據通過 DMA 拷貝到內核緩沖區。
(2)調用sendfile()系統調用,內核直接將數據從內核緩沖區拷貝到 Socket 緩沖區(早期為 CPU 拷貝)。
(3)DMA 將 Socket 緩沖區數據發送到網絡。

優化(Linux 2.4+):
引入DMA scatter-gather(分散 - 聚集) 技術:內核無需將數據拷貝到 Socket 緩沖區,而是直接告訴網卡 “數據在內核緩沖區的位置和長度”,網卡通過 DMA 直接從內核緩沖區讀取數據并發送到網絡。此時流程簡化為:
(1)磁盤→內核緩沖區(DMA 拷貝)。
(2)內核緩沖區→網絡(DMA scatter-gather,無 CPU 拷貝)。

優勢:
(1)完全避免用戶態與內核態切換(僅 1 次sendfile()調用)。
(2)無 CPU 拷貝(僅 2 次 DMA 拷貝),效率極高。

缺點:
(1)僅適用于 “文件→網絡” 的單向傳輸(無法在用戶態處理數據)。

應用:
(1)Web 服務器(Nginx 默認啟用sendfile模塊,加速靜態文件傳輸)。
(2)視頻點播、大文件下載等場景。

(3)其他零拷貝實現

(1)Windows:TransmitFile:功能類似sendfile,用于文件到網絡的零拷貝傳輸。
(2)Java NIO:FileChannel.transferTo()/transferFrom():底層調用操作系統的零拷貝接口(如 Linux 的sendfile、Windows 的TransmitFile),實現文件通道與其他通道(如 SocketChannel)的直接數據傳輸。

傳輸方式 數據拷貝次數(CPU) 數據拷貝次數(DMA) 用戶態?內核態切換次數 適用場景
傳統(read+write) 2 次(內核→用戶、用戶→Socket) 2 次(磁盤→內核、Socket→網絡) 4 次(read 進入內核、返回用戶;write 進入內核、返回用戶) 需用戶態處理數據的場景
mmap+write 1 次(內核→Socket) 2 次 2 次(mmap、write 各 1 次) 需用戶態處理數據,且數據量大
sendfile(優化后) 0 次 2 次 1 次(僅 sendfile 調用) 純文件→網絡傳輸(無需用戶處理)

【5】零拷貝的核心價值

(1)減少 CPU 占用:避免冗余的 CPU 拷貝,釋放 CPU 資源用于其他任務。
(2)降低內存帶寬消耗:減少數據在內存中的重復存儲,節省內存帶寬。
(3)減少狀態切換:用戶態與內核態切換開銷大,零拷貝可大幅減少切換次數。

這些優勢在高并發、大文件傳輸場景(如視頻流服務、日志收集、消息中間件)中尤為重要,能顯著提升系統吞吐量。

【二】NIO的零拷貝MappedByteBuffer(內存映射文件)

通過內存映射將文件直接映射到用戶進程的地址空間,操作內存即可等同于操作文件,避免了傳統 IO 的read()/write()拷貝。
應用場景:
(1)大文件的隨機讀寫(如數據庫索引文件、日志文件)。
(2)需要頻繁訪問文件內容的場景(如解析大型 CSV/XML)。

import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;public class MappedFileExample {public static void main(String[] args) throws Exception {try (RandomAccessFile file = new RandomAccessFile("data.txt", "rw");FileChannel channel = file.getChannel()) {// 映射文件的前1024字節到內存(讀寫模式)MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_WRITE,  // 模式:讀寫0,  // 起始位置1024  // 映射長度);// 直接操作內存(等同于操作文件)buffer.put("Hello Zero-Copy".getBytes());// 無需顯式flush,內核會自動同步到磁盤(可通過force()強制同步)buffer.force();}}
}

文件數據通過內存映射被 “映射” 到用戶空間的虛擬內存,用戶操作MappedByteBuffer時,由操作系統負責數據與磁盤的同步(通過頁緩存機制),避免了用戶空間與內核空間的拷貝。

【三】Kafka的零拷貝

Kafka 作為高吞吐量的消息隊列,其高性能的核心原因之一就是大量使用零拷貝:
(1)生產者寫入數據時,數據先寫入頁緩存(內核空間),避免用戶空間拷貝。
(2)消費者讀取數據時,通過sendfile()將頁緩存中的數據直接發送到網絡套接字,全程無用戶空間與內核空間的拷貝。
(3)數據持久化到磁盤時,利用操作系統的頁緩存同步機制,減少物理 IO 次數。

【四】Nginx的零拷貝

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/91204.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/91204.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/91204.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

docker部署自己寫的c++http服務器教程

我用的是ubuntu 22.04環境下 qt c 寫的應用程序,是終端程序,不是界面,然后用linuxdeployqt工具將其打包成了AppImage可執行文件,以上是部署前的準備工作,需要確保AppImage可執行文件在自己的ubuntu上可以運行才能執行以…

Caffeine 緩存庫的常用功能使用介紹

🧑 博主簡介:CSDN博客專家,歷代文學網(PC端可以訪問:https://literature.sinhy.com/#/?__c1000,移動端可微信小程序搜索“歷代文學”)總架構師,15年工作經驗,精通Java編…

C# _列表(List<T>)_ 字典(Dictionary<TKey, TValue>)

目錄 列表(List)特點 創建列表 RemoveAll 刪除與之條件相匹配的數據 會返回刪除的個數 Capacity 獲取或設置列表的容量 更多方法可參照上篇文章:C#_ArrayList動態數組 字典(Dictionary)特點 定義一個字典 向字…

【實時Linux實戰系列】實時網絡控制與調度

在實時控制系統中,網絡調度是確保實時數據流傳輸和處理不受延遲影響的關鍵。實時網絡控制與調度技術對于工業自動化、金融交易、多媒體流等領域至關重要。通過合理設計網絡調度策略,可以顯著提高系統的實時性和可靠性。本文將介紹如何在實時控制系統中實…

Qwen3-Coder:介紹及使用 -- 超強AI編程助手

更多內容:XiaoJ的知識星球 目錄一、Qwen3-Coder模型介紹1.預訓練階段(Pre-Training)2.后訓練階段(Post-Training)1)Scaling Code RL: Hard to Solve, Easy to Verify2)Scaling Long-Horizon RL二…

uniapp 如果進入頁面輸入框自動聚焦,此時快速返回頁面或者跳轉到下一個頁面,輸入法頂上來的頁面出現半屏的黑屏問題。

如果進入頁面輸入框自動聚焦,此時快速返回頁面或者跳轉到下一個頁面,輸入法頂上來的頁面出現半屏的黑屏問題。輸入法出來后,設置了自動將頁面頂上來的配置:pages.json"softinputMode": "adjustResize""g…

深入了解 Kubernetes(k8s):從概念到實踐

目錄 一、k8s 核心概念 二、k8s 的優勢 三、k8s 架構組件 控制平面組件 節點組件 四、k8s docker 運行前后端分離項目的例子 1. 準備前端項目 2. 準備后端項目 3. 創建 k8s 部署配置文件 4. 部署應用到 k8s 集群 在當今云計算和容器化技術飛速發展的時代&#xff0c…

Android User版本默認用test-keys,如何改用release-keys

Android User版本 默認用test-keys, 如何改用release-keys 開發云 - 一站式云服務平臺 --- build/core/Makefile | 5 1 file changed, 5 insertions() diff --git a/build/core/Makefile b/build/core/Makefile index --- a/build/core/Makefile b/build/core…

從零開始學習Dify-數據庫數據可視化(五)

概述上一篇文章我們圍繞 Excel 文件展開數據可視化教學,逐步掌握了數據導入、圖表構建和 AI 智能分析。在實際業務環境中,很多數據并不是保存在表格中,而是存儲于數據庫系統中,尤其是最常見的 MySQL。本篇作為本系列的第五篇&…

使用vue2和 element-ui 做一個點餐收銀臺系統前端靜態項目

今天給大家分享一個 關于點餐收銀臺的靜態網站,最近一直在練習前端項目,就使用vue2和 element-ui 做了一個 這樣簡單的 收銀臺系統。先給大家看一下 做出來的樣子。 因為是練習項目 所以頁面功能還是比較簡單的。 使用的技術是: 技術棧 Vu…

Spring Boot自動配置原理深度解析

Spring Boot自動配置原理深度解析 一、自動配置核心概念 1.1 什么是自動配置 Spring Boot自動配置(Auto-Configuration)是其核心特性之一,能夠根據項目依賴自動配置Spring應用程序。例如: 當檢測到H2數據庫依賴時,自動配置內存數據庫當存在Sp…

關于 Apache Ignite 中 Job 調度(Job Scheduling)與沖突控制(Collision Control) 的機制說明

這段內容是關于 Apache Ignite 中 Job 調度(Job Scheduling)與沖突控制(Collision Control) 的機制說明。我來為你逐段解析,幫助你深入理解其原理和使用方式。🔍 一、核心概念:Job 調度與 Colli…

網絡資源模板--基于Android Studio 實現的課程管理App

目錄 一、測試環境說明 二、項目簡介 三、項目演示 四、部設計詳情(部分) 登錄頁 首頁 五、項目源碼 一、測試環境說明 電腦環境 Windows 11 編寫語言 JAVA 開發軟件 Android Studio (2020) 開發軟件只要大于等于測試版本即可(近幾年官網直接下載也可…

ROUGE-WE:詞向量化革新的文本生成評估框架

一、ROUGE 基礎與核心局限 ROUGE(Recall-Oriented Understudy for Gisting Evaluation) 是自動文本摘要與機器翻譯的主流評估指標,由 Chin-Yew Lin 在2004年發表的論文中首次系統提出。其核心變體包括: ROUGE-N:基于…

MGER綜合實驗

一.拓撲二、實驗需求 1、R5為ISP,只能進行IP地址配置,其所有地址均配為公有IP地址; 2、R1和R5間使用PPP的PAP認證,R5為主認證方; R2與R5之間使用ppp的CHAP認證,R5為主認證方; R3與R5之間使用HDLC封裝; 3、R1、R2、R3構建一個MGRE環…

高可用集群Keepalived、Redis、NoSQL數據庫Redis基礎管理

1. 總結負載均衡常見的算法 輪詢 (Round Robin):按順序將請求依次分配給后端服務器,適合服務器性能相近的場景。 加權輪詢 (Weighted Round Robin):在輪詢的基礎上,根據服務器的權重分配請求。 隨機 (Random):隨機選…

【深度學習】獨熱編碼(One-Hot Encoding)

獨熱編碼(One-Hot Encoding) 在機器學習中,數據預處理是不可或缺的關鍵一步。面對各種非數值類型的分類數據(Categorical Data),如何將其轉換為機器學習模型能夠“理解”的語言呢?獨熱編碼&…

Promise完全體總結

我們在上篇文章提到了異步會導致無法通過返回值來獲取函數的執行結果,我們通過傳入一個回調函數的方式,以參數的形式獲取到了我們想要獲取的數據,但是這樣如果需要對數據進行多次操作導致形成回調地獄那種不便于閱讀以及護理的代碼。為了解決…

SpringJDBC源碼初探-DataSource類

一、DataSource接口核心作用 DataSource是JDBC規范的核心接口,位于javax.sql包中,用于替代傳統的DriverManager獲取數據庫連接。Spring框架通過org.springframework.jdbc.datasource包對該接口進行了增強,提供連接池管理、事務綁定等高級特性…

C語言(08)——關于指針(逐漸清晰版)

為了更好地理解本篇文章的知識內容,讀者可以將以下文章作為補充知識進行閱讀 : C語言————原碼 補碼 反碼 (超絕詳細解釋)-CSDN博客 C語言————二、八、十、十六進制的相互轉換-CSDN博客 C語言————斐波那契數列的理解…