繼續上一篇 盤一盤高效能設計的那些點(一) 文章,繼續探討高效能設計的一些點!
磁碟內容讀取或寫入操作都會涉及到一個【定址過程】,首先找到需要讀取或寫入的位置,然後去操作磁碟內容讀寫。
所謂順序存取,就是將以儲存連續的方式寫入、讀取磁碟內容。
下圖為不同儲存媒介順序、隨機存取效能對比:
就好像快遞員送貨一樣,它會實現規劃好路線,一條線送過去,是最省時省力的。
Kafka 每條訊息都會被 append 到相應的 partition 中,順序寫磁碟,效率非常高。是 Kafka 高吞吐率的一個很重要的保障。
Mysql 順序讀寫類檔案包括: InnoDB system tablespace 檔案及 binary log 及 redo log 紀錄檔檔案等
傳統方式,資料從儲存媒介讀取到傳送到網路整個過程會涉及到多次資料拷貝及上下文切換操作,如下:
圖上層為上下文切換過程,下層為拷貝過程。
user context 切換到 kernel context;DAM engine 將資料從磁碟拷貝到核心。
資料從 kernel buffer 拷貝到 user buffer;kernel context 切換到 user context。
user context 切換到 kernel context,資料從 user buffer 拷貝到 socket buffer。
kernel context 切換到 user context,資料從 socket buffer 拷貝到 protocol engine。
mmap 方式演進:
使用者程序共用 kernel buffer。
mmap 上線文切換過程不變,資料傳輸省略掉了 kernel buffer 和 user buffer 之間的拷貝過程,資料直接從 kernel buffer 拷貝到 socket buffer。
Sendfile 方式演進:
Read Write 過程由 Sendfile 機制替代。
Zero copy:
DMA 將資料從儲存媒介拷貝到 kernel buffer 後,不再做任何資料拷貝,直接將帶有資料地址及長度資訊的檔案控制程式碼追加至 socket buffer。
DMA engine 負責將資料從 kernel buffer 傳送至 protocol engine。
TransferableRecords::writeTo 方法實現了 sendfile,更高效的實現訊息的收發。
依賴於作業系統零拷貝特性直接將緩衝區資料傳送到相應的通道。 netty 利用 NIO FileChannel transferTo 方法,通道對通道寫資料。
非同步的著眼點在於剝離主流程。
主流程繼續執行主線任務,非同步邏輯開闢支線處理。
IO -> NIO -> AIO
基於 EventBus 或者 訊息佇列進行非同步邏輯任務的處理。
如記錄操作記錄,歷史變更等資訊。