程序員經(jīng)典面試題,Kafka讀寫硬盤為什么速度還那么快
在今天的很多程序員招聘里,都會要求能夠熟練運用Apache Kafka等至少一種消息隊列,Apache Kafka也是程序員面試里的??汀T诖蠖鄶?shù)人的映象中,寫磁盤都是比較慢的,可是,為什么Apache Kafka在各大MQ性能的評測中,還能夠擊敗眾多對手,取得不錯的成績呢?
順序?qū)懘疟P
在我們的生產(chǎn)環(huán)境中,為了節(jié)約成本,大部分服務器仍然使用機械磁盤,而非固態(tài)硬盤。我們知道,機械磁盤讀寫數(shù)據(jù),首先需要尋道,將磁頭調(diào)整到對應的磁道上,緊接著,會進行旋轉(zhuǎn),將磁頭旋轉(zhuǎn)到對應的位置上,最后才是讀寫數(shù)據(jù),尋道跟旋轉(zhuǎn),占用了磁盤讀寫的大量時間,所以,Apache Kafka在寫磁盤的時候,大量地使用了追加寫的模式,減少了磁盤尋道與旋轉(zhuǎn)地時間,從而達到更高的磁盤利用率。
大量使用內(nèi)存頁
我們知道,即便是順序?qū)懘疟P,磁盤的讀寫速度任然比內(nèi)存慢慢的多得多,好在操作系統(tǒng)已經(jīng)幫我們解決這個問題了,在Linux操作系統(tǒng)中,Linux會將磁盤中的一些數(shù)據(jù)讀取到內(nèi)存當中,我們稱之為內(nèi)存頁。當需要讀寫硬盤的時候,都優(yōu)先在內(nèi)存頁中進行處理。讀的話大家比較好理解,就是緩存嘛,寫的話如果只寫在緩存沒有落盤不是會形成臟數(shù)據(jù)么?的確如此,只有當臟頁到達一定比例之后,Linux操作系統(tǒng)才會把數(shù)據(jù)刷到磁盤當中。在機器發(fā)生掉電的時候,的確會出現(xiàn)臟數(shù)據(jù)。但是,我們更應該使用分布式寫到多臺機器上來從根本上解決這個問題。
并且,寫在內(nèi)存頁的另外一個好處是減少應用內(nèi)存的使用,我們都知道Apache Kafka是用Java語言編寫的,不得不避免的便是Java的GC問題,隨著應用內(nèi)存的增多,垃圾回收的時間會更多,帶來整體性能的下降。
零拷貝技術的使用
作為一個消息系統(tǒng),不可避免的便是消息的拷貝,常規(guī)的操作,一條消息,需要從創(chuàng)建者的socket到應用,再到操作系統(tǒng)內(nèi)核,然后才能落盤。同樣,一條消息發(fā)送給消費者也要從磁盤到內(nèi)核到應用再到接受者的socket,中間經(jīng)過了多次不是很有必要的拷貝。
在Linux操作系統(tǒng)中,同樣為我們提供了零拷貝技術,零拷貝技術并非真的不用拷貝,而是大大地減少了拷貝次數(shù)。舉個例子,原本從磁盤到接收者Socket中,需要見過內(nèi)核態(tài),又要經(jīng)過Apache Kafka應用,那么有沒有可能直接越過這兩層狀態(tài),達到更少的拷貝次數(shù)呢?Java 的NIO庫,幫我們實現(xiàn)了這一切,借用JavaNIO庫封裝的API,我們可以直接使用Linux操作系統(tǒng)的零拷貝技術,讓系統(tǒng)更快。
總結(jié)
以上三點,便是Apache Kafka雖然使用了硬盤存儲,但是仍然可以速度很快的原因,當然,除此之外,Apache Kafka還有很多特性讓他很快,如果你有興趣,歡迎大家關注我,共同學習,共同進步。大家的支持是我繼續(xù)嘮嗑的動力。