什麼是零拷貝,Netty是如何實現的?
呢作為一個高效能的網路通訊框架,被越來越多網際網路公司關注和重視。最近,有小夥伴在面試過程中被問到Netty是如何實現零拷貝的問題?,今天,我給大家來聊一聊。另外,往期面試題解析中配套的文件我已經準備好,想獲得的可以在我的煮葉簡介中找到。
我們先來看什麼是零拷貝?
1、什麼零拷貝
在計算機中,完成資料傳輸,要麼是通過網路,要麼就是通過本地磁碟。通常完成一次完整I/O互動流程分為兩階段,首先拷貝到系統核心空間,由作業系統來完成;緊接著要拷貝到使用者空間,這個由應用程式來完成,具體互動流程如下圖所示。
那什麼是零拷貝呢?顧名思義,零拷貝的意思包括兩個部分,“零”和“拷貝”:
“拷貝”:就是指資料從一個儲存區域轉移到另一個儲存區域。
“零” :表示次數為0,它表示拷貝資料的次數為0。
合起來“零拷貝”就是不需要將資料從一個儲存區域複製到另一個儲存區域。
2、為什麼要零拷貝
零拷貝主要是指將系統核心空間的記憶體和使用者空間的記憶體實現直接關聯對映,從而省去了資料傳輸過程中的來回拷貝,也就是說,要完成資料傳輸資料拷貝次數為0次。
有這麼一段程式碼,主要將服務端主機磁碟中的檔案從已連線的socket發出去。關鍵實現程式碼如下:
while((n = read(diskfd, buf, BUF_SIZE)) > 0){
write(sockfd, buf , n);
}
以上程式碼是用傳統的IO編寫的,它的執行過程大致是這樣的:
首先,read()方法,會把資料從磁碟迴圈讀取到核心緩衝區,再拷貝到使用者緩衝區。
然後,write()方法先把資料寫入到socket緩衝區,最後寫入網絡卡裝置。
因為,傳統的IO在在資料傳輸過程中拷貝次數太多,導致效能低下。為了減少拷貝次數,增加系統性能,才有了零拷貝的設計。另外,零拷貝並不是指完全沒有檔案的拷貝,只是減少了拷貝的次數。
3、零拷貝在Netty中的實現
從流程圖可以看出,傳統IO的讀寫流程,包括了4次使用者態和核心態的切換,也就是4次上下文切換,4次資料拷貝,其中兩次CPU拷貝以及兩次的DMA拷貝。關於上下文切換和DMA拷貝,在這裡我們就不詳細贅述了,以後可以單獨拍攝一期影片來詳細介紹。想了解的小夥伴可以在評論區回覆666.
那在Netty中,是如何實現零拷貝的呢?有以下三種方式
1. 使用堆外記憶體,也叫直接記憶體。Netty的接收和傳送都採用DIRECT BUFFERS,對應系統底層的mmap機制,直接使用堆外記憶體進行Socket讀寫,不需要進行位元組緩衝區的二次拷貝。
2. 提供了組合Buffer物件,可以聚合多個ByteBuffer物件,使用者只需要像操作一個Buffer一樣方便的對組合Buffer進行操作,避免了傳統通過記憶體拷貝的方式將幾個小Buffer合併成一個大的Buffer,不需要做記憶體拷貝。
3. 的檔案傳輸採用了transferTo方法,直接使用了NIO的sendfile機制,它可以直接將檔案緩衝區的資料傳送到目標Channel,避免了傳統通過迴圈write方式導致的記憶體拷貝問題。
更多幹貨知識,可關注我的主頁簡介!
本文為“Tom彈架構”原創,轉載請註明出處。技術在於分享,我分享我快樂!\ 如果本文對您有幫助,歡迎關注和點贊;如果您有任何建議也可留言評論或私信,您的支援是我堅持創作的動力。 關注微信公眾號『 Tom彈架構 』回覆“666”可獲取更多技術乾貨!
我是被程式設計耽誤的文藝Tom
- 使用橋接模式設計複雜的訊息系統
- 為什麼MySQL索引結構採用B 樹?
- 為什麼Netty執行緒池預設大小為CPU核數的2倍
- 談談你對深克隆和淺克隆的理解
- 什麼是代理,為什麼要用動態代理?
- 什麼是零拷貝,Netty是如何實現的?
- 3分鐘輕鬆理解單執行緒下的HashMap工作原理
- 被面試官問爛的Spring AOP原理,你是怎麼答的?
- Spring為何需要三級快取解決迴圈依賴,而不是二級快取?
- 為什麼Spring中每個Bean都要定義作用域?
- 談談你對Spring Bean的理解
- 趣談裝飾器模式,讓你一輩子不會忘
- 掌握這些招數,你也能寫出HR眼中的高分簡歷
- MongoDB高階應用之資料轉存與恢復(5)
- 圖解MongoDB叢集部署原理(3)
- 爆肝30天,肝出來史上最透徹Spring原理和27道高頻面試題總結
- Spring核心原理之IoC容器初體驗(2)
- Spring核心原理分析之MVC九大元件(1)
- 30個類手寫Spring核心原理之動態資料來源切換(8)
- 【緊急】Log4j又發新版2.17.0,只有徹底搞懂漏洞原因,才能以不變應萬變,小白也能看懂