1.順序讀寫
kafka的消息是不斷追加到檔案中的,這個特性使kafka可以充分利用磁盤的順序讀寫性能
順序讀寫不需要硬碟磁頭的尋道時間,隻需很少的扇區旋轉時間,是以速度遠快于随機讀寫
生産者負責寫入資料,Kafka會将消息持久化到磁盤,保證不會丢失資料,Kafka采用了倆個技術提高寫入的速度。
1.順序寫入:在大學的計算機組成(劃重點)裡我們學過,硬碟是機械結構,需要指針尋址找到存儲資料的位置,是以,如果是随機IO,磁盤會進行頻繁的尋址,導緻寫入速度下降。Kafka使用了順序IO提高了磁盤的寫入速度,Kafka會将資料順序插入到檔案末尾,消費者端通過控制偏移量來讀取消息,這樣做會導緻資料無法删除,時間一長,磁盤空間會滿,kafka提供了2種政策來删除資料:基于時間删除和基于partition檔案的大小删除。
2.Memory Mapped Files:這個和Java NIO中的記憶體映射基本相同,在大學的計算機原理裡我們學過(劃重點),mmf直接利用作業系統的Page來實作檔案到實體記憶體的映射,完成之後對實體記憶體的操作會直接同步到硬碟。mmf通過記憶體映射的方式大大提高了IO速率,省去了使用者空間到核心空間的複制。它的缺點顯而易見--不可靠,當發生當機而資料未同步到硬碟時,資料會丢失,Kafka提供了produce.type參數來控制是否主動的進行重新整理,如果kafka寫入到mmp後立即flush再傳回給生産者則為同步模式,反之為異步模式。
2.零拷貝
在這之前先來了解一下零拷貝(直接讓作業系統的 Cache 中的資料發送到網卡後傳輸給下遊的消費者):平時從伺服器讀取靜态檔案時,伺服器先将檔案從複制到核心空間,再複制到使用者空間,最後再複制到核心空間并通過網卡發送出去,而零拷貝則是直接從核心到核心再到網卡,省去了使用者空間的複制。
Kafka把所有的消息存放到一個檔案中,當消費者需要資料的時候直接将檔案發送給消費者,比如10W的消息共10M,全部發送給消費者,10M的消息在内網中傳輸是非常快的,假如需要1s,那麼kafka的tps就是10w。Zero copy對應的是Linux中sendfile函數,這個函數會接受一個offsize來确定從哪裡開始讀取。現實中,不可能将整個檔案全部發給消費者,他通過消費者傳遞過來的偏移量來使用零拷貝讀取指定内容的資料傳回給消費者。
在Linux kernel2.2 之後出現了一種叫做"零拷貝(zero-copy)"系統調用機制,就是跳過“使用者緩沖區”的拷貝,建立一個磁盤空間和記憶體的直接映射,資料不再複制到“使用者态緩沖區”,系統上下文切換減少為2次,可以提升一倍的性能。
3.分區
kafka中的topic中的内容可以被分為多分partition存在,每個partition又分為多個段segment,是以每次操作都是針對一小部分做操作,很輕便,并且增加
并行操作
的能力
4.批量發送
kafka允許進行批量發送消息,producter發送消息的時候,可以将消息緩存在本地,等到了固定條件發送到kafka
- 等消息條數到固定條數
- 一段時間發送一次
5.資料壓縮
Kafka還支援對消息集合進行壓縮,Producer可以通過GZIP或Snappy格式對消息集合進行壓縮。
壓縮的好處就是減少傳輸的資料量,減輕對網絡傳輸的壓力。
Producer壓縮之後,在Consumer需進行解壓,雖然增加了CPU的工作,但在對大資料處理上,瓶頸在網絡上而不是CPU,是以這個成本很值得
批量發送
和
資料壓縮
一起使用,單條做資料壓縮的話,效果不明顯
Kafka的設計目标是高吞吐量,它比其它消息系統快的原因展現在以下幾方面:
1、Kafka操作的是序列檔案I / O(序列檔案的特征是按順序寫,按順序讀),為保證順序,Kafka強制點對點的按順序傳遞消息,這意味着,一個consumer在消息流(或分區)中隻有一個位置。
2、Kafka不儲存消息的狀态,即消息是否被“消費”。一般的消息系統需要儲存消息的狀态,并且還需要以随機通路的形式更新消息的狀态。而Kafka 的做法是儲存Consumer在Topic分區中的位置offset,在offset之前的消息是已被“消費”的,在offset之後則為未“消費”的,并且offset是可以任意移動的,這樣就消除了大部分的随機IO。
3、Kafka支援點對點的批量消息傳遞。
4、Kafka的消息存儲在OS pagecache(頁緩存,page cache的大小為一頁,通常為4K,在Linux讀寫檔案時,它用于緩存檔案的邏輯内容,進而加快對磁盤上映像和資料的通路)。
每天一點成長,歡迎指正!