高效原因
- CommitLog順序寫, 存儲了MessagBody、message key、tag等信息
- ConsumeQueue隨機讀 + 操作系統的PageCache + 零拷貝技術ZeroCopy
2.1 零拷貝技術
read(file, tmp_buf, len);
write(socket, tmp_buf, len);
例子:將一個File讀取並發送出去(Linux有兩個上下文,內核態,用戶態)
- File文件的經歷了4次copy
- 調用read,將文件拷貝到了kernel內核態
- CPU控制 kernel態的數據copy到用戶態
- 調用write時,user態下的內容會copy到內核態的socket的buffer中
- 最后將內核態socket buffer的數據copy到網卡設備中傳送
- 缺點:增加了上下文切換、浪費了2次無效拷貝(即步驟2和3)
2.2 ZeroCopy
請求kernel直接把disk的data傳輸給socket,而不是通過應用程序傳輸。Zero copy大大提高了應用程序的性能,減少不必要的內核緩沖區跟用戶緩沖區間的拷貝,從而減少CPU的開銷和減少了kernel和user模式的上下文切換,達到性能的提升
對應零拷貝技術有mmap及sendfile
2.2.1 mmap:小文件傳輸快
RocketMQ 選擇這種方式,mmap+write 方式,小塊數據傳輸,效果會比 sendfile 更好
2.2.2 sendfile:大文件傳輸比mmap快
2.3 Java中的TransferTo()實現了Zero-Copy
2.4 應用:Kafka、Netty、RocketMQ等都采用了零拷貝技術