成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

美團面試:說說Netty的零拷貝技術(shù)?

開發(fā) 前端 存儲架構(gòu)
操作系統(tǒng)有用戶態(tài)和內(nèi)核態(tài)之分,這是因為計算機體系結(jié)構(gòu)中的操作系統(tǒng)設(shè)計了兩個不同的執(zhí)行環(huán)境,以提供不同的功能和特權(quán)級別。

零拷貝技術(shù)(Zero-Copy)是一個大家耳熟能詳?shù)募夹g(shù)名詞了,它主要用于提升 IO(Input & Output)的傳輸性能。

那么問題來了,為什么零拷貝技術(shù)能提升 IO 性能?

一、零拷貝技術(shù)和性能

在傳統(tǒng)的 IO 操作中,當我們需要讀取并傳輸數(shù)據(jù)時,我們需要在用戶態(tài)(用戶空間)和內(nèi)核態(tài)(內(nèi)核空間)中進行數(shù)據(jù)拷貝,它的執(zhí)行流程如下:

圖片圖片

從上述流程我們可以看出,在傳統(tǒng)的 IO 操作中,我們是需要 4 次拷貝和 4 次上下文切換(用戶態(tài)和內(nèi)核態(tài)的切換)的。

而每次數(shù)據(jù)拷貝和上下文切換都有時間成本,會讓程序的執(zhí)行時間變成,所以零拷貝技術(shù)的出現(xiàn)就是為了減少數(shù)據(jù)的拷貝次數(shù)以及上下文的切換次數(shù)的。

1.1 什么是用戶態(tài)和內(nèi)核態(tài)?

操作系統(tǒng)有用戶態(tài)和內(nèi)核態(tài)之分,這是因為計算機體系結(jié)構(gòu)中的操作系統(tǒng)設(shè)計了兩個不同的執(zhí)行環(huán)境,以提供不同的功能和特權(quán)級別。

  • 用戶態(tài)(User Mode)是指應(yīng)用程序運行時的執(zhí)行環(huán)境。在用戶態(tài)下,應(yīng)用程序只能訪問受限資源,如應(yīng)用程序自身的內(nèi)存空間、CPU 寄存器等,并且不能直接訪問操作系統(tǒng)的底層資源和硬件設(shè)備。
  • 內(nèi)核態(tài)(Kernel Mode)是指操作系統(tǒng)內(nèi)核運行時的執(zhí)行環(huán)境。在內(nèi)核態(tài)下,操作系統(tǒng)具有更高的權(quán)限,可以直接訪問系統(tǒng)的硬件和底層資源,如 CPU、內(nèi)存、設(shè)備驅(qū)動程序等。

1.2 什么是DMA?

DMA(Direct Memory Access,直接內(nèi)存訪問)技術(shù),繞過 CPU,直接在內(nèi)存和外設(shè)之間進行數(shù)據(jù)傳輸。這樣可以減少 CPU 的參與,提高數(shù)據(jù)傳輸?shù)男省?/p>

二、Linux零拷貝技術(shù)

Linux 下實現(xiàn)零拷貝的主要實現(xiàn)技術(shù)是 MMap、sendFile,它們的具體介紹如下。

2.1 MMap

MMap(Memory Map)是 Linux 操作系統(tǒng)中提供的一種將文件映射到進程地址空間的一種機制,通過 MMap 進程可以像訪問內(nèi)存一樣訪問文件,而無需顯式的復(fù)制操作。

使用 MMap 可以把 IO 執(zhí)行流程優(yōu)化成以下執(zhí)行步驟:

圖片圖片

傳統(tǒng)的 IO 需要四次拷貝和四次上下文(用戶態(tài)和內(nèi)核態(tài))切換,而 MMap 只需要三次拷貝和四次上下文切換,從而能夠提升程序整體的執(zhí)行效率,并且節(jié)省了程序的內(nèi)存空間。

2.2 senFile 方法

在 Linux 操作系統(tǒng)中 sendFile() 是一個系統(tǒng)調(diào)用函數(shù),用于高效地將文件數(shù)據(jù)從內(nèi)核空間直接傳輸?shù)骄W(wǎng)絡(luò)套接字(Socket)上,從而實現(xiàn)零拷貝技術(shù)。這個函數(shù)的主要目的是減少 CPU 上下文切換以及內(nèi)存復(fù)制操作,提高文件傳輸性能。

使用 sendFile() 可以把 IO 執(zhí)行流程優(yōu)化成以下執(zhí)行步驟:

圖片圖片

三、Netty零拷貝技術(shù)

Netty 中的零拷貝和傳統(tǒng) Linux 的零拷貝技術(shù)的實現(xiàn)不太一樣,Netty 中的零拷貝技術(shù)主要是通過優(yōu)化用戶態(tài)的操作來提升 IO 的執(zhí)行速度,從而實現(xiàn)零拷貝的。

PS:所有可以提升 IO 執(zhí)行效率的操作或手段都可以稱之為零拷貝技術(shù)。

Netty 中的零拷貝技術(shù)主要有以下 5 種實現(xiàn):

  1. 使用堆外內(nèi)存:避免 JVM 堆內(nèi)存到堆外內(nèi)存的數(shù)據(jù)拷貝,從而提升了 IO 的操作性能。
  2. 使用 CompositeByteBuf 合并對象:可以組合多個 Buffer 對象合并成一個邏輯上的對象,避免通過傳統(tǒng)內(nèi)存拷貝的方式將幾個 Buffer 合并成一個大的 Buffer。
  3. 通過 Unpooled.wrappedBuffer 合并數(shù)據(jù):可以將 byte 數(shù)組包裝成 ByteBuf 對象,包裝過程中不會產(chǎn)生內(nèi)存拷貝。
  4. 使用 ByteBuf.slice 共享對象:操作與 Unpooled.wrappedBuffer 相反,slice 操作可以將一個 ByteBuf 對象切分成多個 ByteBuf 對象,切分過程中不會產(chǎn)生內(nèi)存拷貝,底層共享一個 byte 數(shù)組的存儲空間。
  5. 使用 FileRegion 實現(xiàn)零拷貝:FileRegion 底層封裝了 FileChannel#transferTo() 方法,可以將文件緩沖區(qū)的數(shù)據(jù)直接傳輸?shù)侥繕?Channel,避免內(nèi)核緩沖區(qū)和用戶態(tài)緩沖區(qū)之間的數(shù)據(jù)拷貝,這屬于操作系統(tǒng)級別的零拷貝。

它們的具體實現(xiàn)如下。

3.1 使用堆外內(nèi)存

正常情況下,JVM 需要將數(shù)據(jù)從 JVM 堆內(nèi)存拷貝到堆外內(nèi)存進行業(yè)務(wù)執(zhí)行的,這是因為:

  1. 操作系統(tǒng)并不感知 JVM 的堆內(nèi)存,而且 JVM 的內(nèi)存布局與操作系統(tǒng)所分配的是不一樣的,操作系統(tǒng)并不會按照 JVM 的行為來讀寫數(shù)據(jù)。
  2. 同一個對象的內(nèi)存地址隨著 JVM GC 的執(zhí)行可能會隨時發(fā)生變化,例如 JVM GC 的過程中會通過壓縮來減少內(nèi)存碎片,這就涉及對象移動的問題了。

而 Netty 在進行 I/O 操作時都是使用的堆外內(nèi)存,可以避免數(shù)據(jù)從 JVM 堆內(nèi)存到堆外內(nèi)存的拷貝。

3.2 使用CompositeByteBuf合并對象

CompositeByteBuf 可以理解為一個虛擬的 Buffer 對象,它是由多個 ByteBuf 組合而成,但是在 CompositeByteBuf 內(nèi)部保存著每個 ByteBuf 的引用關(guān)系,從邏輯上構(gòu)成一個整體。使用 CompositeByteBuf 我們可以合并兩個 ByteBuf 對象,從而避免兩個對象合并時需要兩次 CPU 拷貝操作的問題,在沒有使用 CompositeByteBuf 時,我們的操作是這樣的:

ByteBuf httpBuf = Unpooled.buffer(header.readableBytes() + body.readableBytes());
httpBuf.writeBytes(header);
httpBuf.writeBytes(body);

而實現(xiàn) header 和 body 這兩個 ByteBuf 的合并,需要先初始化一個新的 httpBuf,然后再將 header 和 body 分別拷貝到新的 httpBuf。合并過程中涉及兩次 CPU 拷貝,這非常浪費性能,所以我們就可以使用 CompositeByteBuf 了,它的使用如下:

CompositeByteBuf httpBuf = Unpooled.compositeBuffer();
httpBuf.addComponents(true, header, body);

CompositeByteBuf 通過調(diào)用 addComponents() 方法來添加多個 ByteBuf,但是底層的 byte 數(shù)組是復(fù)用的,不會發(fā)生內(nèi)存拷貝。

3.3 通過Unpooled.wrappedBuffer合并數(shù)據(jù)

Unpooled.wrappedBuffer 的操作類似,使用它可以將不同的數(shù)據(jù)源的一個或者多個數(shù)據(jù)包裝成一個大的 ByteBuf 對象,其中數(shù)據(jù)源的類型包括 byte[]、ByteBuf、ByteBuffer。包裝的過程中不會發(fā)生數(shù)據(jù)拷貝操作,包裝后生成的 ByteBuf 對象和原始 ByteBuf 對象是共享底層的 byte 數(shù)組。

3.4 使用 ByteBuf.slice 共享對象

ByteBuf.slice 和 Unpooled.wrappedBuffer 的邏輯正好相反,ByteBuf.slice 是將一個 ByteBuf 對象切分成多個共享同一個底層存儲的 ByteBuf 對象,從而避免對象分割時的數(shù)據(jù)拷貝,它的使用如下:

ByteBuf httpBuf = ...
ByteBuf header = httpBuf.slice(0, 6);
ByteBuf body = httpBuf.slice(6, 4);

3.5 使用 FileRegion 實現(xiàn)文件零拷貝

FileRegion 底層封裝了 FileChannel#transferTo() 方法,可以將文件緩沖區(qū)的數(shù)據(jù)直接傳輸?shù)侥繕?Channel,避免內(nèi)核緩沖區(qū)和用戶態(tài)緩沖區(qū)之間的數(shù)據(jù)拷貝,這屬于操作系統(tǒng)級別的零拷貝。

以下是 FileRegion 的默認實現(xiàn)類 DefaultFileRegion 的使用案例:

@Override
public void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
    RandomAccessFile raf = null;
    long length = -1;
    try {
        raf = new RandomAccessFile(msg, "r");
        length = raf.length();
    } catch (Exception e) {
        ctx.writeAndFlush("ERR: " + e.getClass().getSimpleName() + ": " + e.getMessage() + '\n');
        return;
    } finally {
        if (length < 0 && raf != null) {
            raf.close();
        }
    }
    ctx.write("OK: " + raf.length() + '\n');
    if (ctx.pipeline().get(SslHandler.class) == null) {
        // SSL not enabled - can use zero-copy file transfer.
        ctx.write(new DefaultFileRegion(raf.getChannel(), 0, length));
    } else {
        // SSL enabled - cannot use zero-copy file transfer.
        ctx.write(new ChunkedFile(raf));
    }
    ctx.writeAndFlush("\n");
}

從上述代碼可以看出,可以通過 DefaultFileRegion 將文件內(nèi)容直接寫入到 NioSocketChannel 中,從而避免了內(nèi)核緩沖區(qū)和用戶態(tài)緩沖區(qū)之間的數(shù)據(jù)拷貝。

責(zé)任編輯:武曉燕 來源: Java中文社群
相關(guān)推薦

2024-06-24 00:09:00

零拷貝技術(shù)MMapsendFile

2024-12-04 14:45:14

零拷貝技術(shù)CPU 拷貝Zero-copy

2024-09-20 08:36:43

零拷貝數(shù)據(jù)傳輸DMA

2024-03-22 06:56:24

零拷貝技術(shù)數(shù)據(jù)傳輸數(shù)據(jù)拷貝

2024-07-31 08:28:37

DMAIOMMap

2025-04-10 03:00:00

2021-03-12 13:57:13

零拷貝技術(shù)

2022-05-05 13:57:43

Buffer設(shè)備MYSQL

2022-09-23 08:47:01

DMA網(wǎng)卡CPU

2013-08-20 13:11:58

技術(shù)美團

2018-04-23 09:50:54

2024-05-30 08:04:20

Netty核心組件架構(gòu)

2025-04-27 08:25:00

Netty零拷貝內(nèi)存

2020-11-11 10:05:04

數(shù)據(jù)庫分庫分表美團面試

2023-03-28 21:33:53

面試隔離MVCC

2022-05-16 08:22:37

零拷貝Netty

2017-06-01 10:52:35

互聯(lián)網(wǎng)

2017-05-26 16:42:06

2016-11-23 19:09:39

javanetty

2024-12-26 17:04:47

點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 日韩精品一区二区三区中文在线 | 在线国产一区 | 国产在线网站 | 黄片毛片免费观看 | 美国一级黄色片 | 国产精品久久国产精品 | 午夜免费视频观看 | 国产三级精品视频 | 日韩喷潮| 台湾a级理论片在线观看 | 亚洲第一区国产精品 | 在线免费观看视频黄 | 精品av| av在线播放网 | 精品真实国产乱文在线 | 91亚洲精品国偷拍自产在线观看 | 国产一二区视频 | 亚洲精品黄色 | 久久免费精品 | 一区二区久久 | www成人免费 | 久久久亚洲 | 亚洲a视频 | 中文字幕高清av | 久久国| 天堂视频中文在线 | 日韩免费av网站 | 久草视| 日韩一区二区在线视频 | 日韩影院在线 | 欧美日韩精品久久久免费观看 | 欧美日韩大陆 | 中文字幕av一区 | 成人精品视频 | 黄网站在线观看 | 日产久久| 四虎影院在线观看av | 欧美成人精品激情在线观看 | 国产精品精品久久久 | 看av片网站 | 在线播放中文 |