文章收錄地址: Java-Bang 專一於系統架構、高可用、高性能、高併發類技術分享
除了消息順序追加、頁緩存等技術,Kafka 還使用零拷貝技術來進一步提高性能。所謂的零拷貝是指將數據直接從磁盤文件複製到網卡設備中,而不須要經由應用程序之手。零拷貝大大提升了應用程序的性能,減小了內核和用戶模式之間的上下文切換。對 Linux 操做系統而言,零拷貝技術依賴於底層的 sendfile() 方法實現。對應於 Java 語言,FileChannal.transferTo() 方法的底層實現就是 sendfile() 方法。java
單純從概念上理解「零拷貝」比較抽象,這裏簡單地介紹一下它。考慮這樣一種經常使用的情形:你須要將靜態內容(相似圖片、文件)展現給用戶。這個情形就意味着須要先將靜態內容從磁盤中複製出來放到一個內存 buf 中,而後將這個 buf 經過套接字(Socket)傳輸給用戶,進而用戶得到靜態內容。這看起來再正常不過了,但實際上這是很低效的流程,咱們把上面的這種情形抽象成下面的過程:git
read(file, tmp_buf, len); write(socket, tmp_buf, len);
首先調用 read() 將靜態內容(這裏假設爲文件 A )讀取到 tmp_buf,而後調用 write() 將 tmp_buf 寫入 Socket,以下圖所示緩存
在這個過程當中,文件 A 經歷了4次複製的過程:架構
從上面的過程能夠看出,數據無緣無故地從內核模式到用戶模式「走了一圈」,浪費了2次複製過程:第一次是從內核模式複製到用戶模式;第二次是從用戶模式再複製回內核模式,即上面4次過程當中的第2步和第3步。並且在上面的過程當中,內核和用戶模式的上下文的切換也是4次。併發
若是採用了零拷貝技術,那麼應用程序能夠直接請求內核把磁盤中的數據傳輸給 Socket,以下圖所示。socket
零拷貝技術經過 DMA(Direct Memory Access)技術將文件內容複製到內核模式下的 Read Buffer 中。不過沒有數據被複制到 Socket Buffer,相反只有包含數據的位置和長度的信息的文件描述符被加到 Socket Buffer 中。DMA 引擎直接將數據從內核模式中傳遞到網卡設備(協議引擎)。這裏數據只經歷了2次複製就從磁盤中傳送出去了,而且上下文切換也變成了2次。零拷貝是針對內核模式而言的,數據在內核模式下實現了零拷貝。高併發
要掌握Kafka的核心實現原理,不單單只是Kafka的日誌格式、日誌索引、日誌清理等方面的內容,也包含底層物理存儲相關的知識點。這樣才能對 Kafka 的整理實現脈絡有比較清晰的認知。加油吧~打工人!性能