繼續上一篇 盤一盤高性能設計的那些點(一) 文章,繼續探討高性能設計的一些點!
一、順序訪問
磁盤內容讀取或寫入操作都會涉及到一個【尋址過程】,首先找到需要讀取或寫入的位置,然後去操作磁盤內容讀寫。
所謂順序訪問,就是將以存儲連續的方式寫入、讀取磁盤內容。
下圖爲不同存儲介質順序、隨機訪問性能對比:
就好像快遞員送貨一樣,它會實現規劃好路線,一條線送過去,是最省時省力的。
1、kafka
Kafka 每條消息都會被 append 到相應的 partition 中,順序寫磁盤,效率非常高。是 Kafka 高吞吐率的一個很重要的保障。
2、MySQL
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。
1、Kafka
TransferableRecords::writeTo 方法實現了 sendfile,更高效的實現消息的收發。
2、Netty
依賴於操作系統零拷貝特性直接將緩衝區數據發送到相應的通道。 netty 利用 NIO FileChannel transferTo 方法,通道對通道寫數據。
三、異步非阻塞
異步的着眼點在於剝離主流程。
主流程繼續執行主線任務,異步邏輯開闢支線處理。
1、IO
IO -> NIO -> AIO
2、異步邏輯
基於 EventBus 或者 消息隊列進行異步邏輯任務的處理。
如記錄操作記錄,歷史變更等信息。