1. kafka特性:
-
高吞吐量、低延遲:kafka每秒可以處理幾十萬條消息,它的延遲最低只有幾毫秒,每個topic可以分多個partition, consumer group 對partition進行consume操作。
-
可擴展性:kafka集群支持熱擴展
-
持久性、可靠性:消息被持久化到本地磁盤,並且支持數據備份防止數據丟失
-
容錯性:允許集群中節點失敗(若副本數量為n,則允許n-1個節點失敗)
-
高並發:支持數千個客戶端同時讀寫
2. kafka性能
1、磁盤IO
在磁盤IO方能,kafka主要通過順序寫和緩存機制提高性能
2、網絡IO
在網絡IO方面,kafka主要通過緩存機制和消息壓縮機制提高性能
3. kafka文件存儲機制
消息發送時都被發送到一個topic,其本質就是一個目錄,而topic由是由一些Partition組成,Partition是一個Queue的結構,每個Partition中的消息都是有序的,生產的消息被不斷追加到Partition上,其中的每一個消息都被賦予了一個唯一的offset值。
每一個分區中都會有一個或者多個段(segment)結構。一個段結構包含兩種類型的文件:.index后綴的索引文件和.log后綴的數據文件。前一個index文件記錄了消息在整個topic中的序號以及消息在log文件中的偏移位置(offset),通過這兩個信息,kafka可以再后一個log文件中找到這條消息的真實內容
Kafka集群會保存所有的消息,不管消息有沒有被消費;我們可以設定消息的過期時間,只有過期的數據才會被自動清除以釋放磁盤空間。比如我們設置消息過期時間為2天,那么這2天內的所有消息都會被保存到集群中,數據只有超過了兩天才會被清除。
Kafka只維護在Partition中的offset值,因為這個offsite標識着這個partition的message消費到哪條了。Consumer每消費一個消息,offset就會加1。其實消息的狀態完全是由Consumer控制的,Consumer可以跟蹤和重設這個offset值,這樣的話Consumer就可以讀取任意位置的消息。
4. kafka高性能的原因
1、單位數量相同的消息將分發到存在於多個Broker服務節點上的多個Partition中,並利用每個Broker服務節點的計算資源進行獨立處理。
2、在磁盤上進行的文件操作只有采用順序讀和順序寫才能做到高效的磁盤IO性能,kafka對索引index文件始終保證順序讀寫:當在磁盤上記錄一條消息時,始終在文件的末尾進行操作;當在磁盤上讀取一條消息時,通過index順序查找到消息的offset位置,再進行消息讀取。后一種消息讀取操作下,如果index文件過大,Kafka的磁盤操作就會耗費掉相當的時間。所以Kafak需要對index文件和log文件進行分段。
3、kafka對linux操作系統下Page Cache技術的應用,才是其高性能的最大保證。
producer生產消息時,會使用pwrite()系統調用【對應到Java NIO中是FileChannel.write() API】按偏移量寫入數據,並且都會先寫入page cache里。consumer消費消息時,會使用sendfile()系統調用【對應FileChannel.transferTo() API】,零拷貝地將數據從page cache傳輸到broker的Socket buffer,再通過網絡傳輸。
圖中沒有畫出來的還有leader與follower之間的同步,這與consumer是同理的:只要follower處在ISR中,就也能夠通過零拷貝機制將數據從leader所在的broker page cache傳輸到follower所在的broker。
同時,page cache中的數據會隨着內核中flusher線程的調度以及對sync()/fsync()的調用寫回到磁盤,就算進程崩潰,也不用擔心數據丟失。另外,如果consumer要消費的消息不在page cache里,才會去磁盤讀取,並且會順便預讀出一些相鄰的塊放入page cache,以方便下一次讀取。
由此我們可以得出重要的結論:如果Kafka producer的生產速率與consumer的消費速率相差不大,那么就能幾乎只靠對broker page cache的讀寫完成整個生產-消費過程,磁盤訪問非常少。並且Kafka持久化消息到各個topic的partition文件時,是只追加的順序寫,充分利用了磁盤順序訪問快的特性,效率高。