Kafka 支持高吞吐量、高度分布式、容錯性強的平臺,能夠以低延遲傳遞消息。
有幾種技術(shù)使 Apache Kafka 如此快速:
- 低延遲消息傳遞
- 批量數(shù)據(jù)和壓縮
- 水平擴展
低延遲消息傳遞
大多數(shù)傳統(tǒng)的數(shù)據(jù)系統(tǒng)使用隨機存取內(nèi)存(RAM)進行數(shù)據(jù)存儲,因為RAM提供了極低的延遲。讓我們看看使用RAM的優(yōu)缺點。
- 優(yōu)點: 這種方法使它們變得非??焖?。
- 缺點: RAM的成本遠高于磁盤,特別是當系統(tǒng)中有數(shù)百GBPS的數(shù)據(jù)流時。
Kafka 避免了隨機存取內(nèi)存,它通過順序I/O和零拷貝原理實現(xiàn)低延遲消息傳遞。
順序I/O:
Kafka 在存儲和緩存消息時大量依賴文件系統(tǒng)。有一種普遍的看法是“磁盤很慢”,這意味著高尋址時間。想象一下,如果我們可以避免尋址時間,我們可以實現(xiàn)與RAM一樣低的延遲。Kafka 通過順序I/O來實現(xiàn)這一點。
Kafka 的基本概念是日志(log);這是一種僅附加、完全有序的數(shù)據(jù)結(jié)構(gòu)。
下面是一個演示日志流(隊列)的圖示,生產(chǎn)者以不可變和單調(diào)的方式在日志流的末尾追加,而訂閱者/消費者可以維護自己的指針以指示當前消息的處理。
來源:https://kafka.apache.org/intro.html
每當生產(chǎn)者發(fā)布一條消息時,它都會收到包含記錄偏移量的確認。第一條發(fā)布到分區(qū)的記錄的偏移量為0,第二條為1,以此類推,以遞增的順序。消費者從由偏移量指定的位置消費數(shù)據(jù),然后定期將其位置保存在日志中以進行提交。保存偏移量的目的是讓另一個消費者在消費者實例崩潰時可以從其位置恢復。
零拷貝原理:
當我們從內(nèi)存中提取數(shù)據(jù)并將其發(fā)送到網(wǎng)絡(luò)時會發(fā)生什么。
- 從內(nèi)存中提取數(shù)據(jù),它會將數(shù)據(jù)從內(nèi)核上下文復制到應用程序上下文
- 將這些數(shù)據(jù)發(fā)送到互聯(lián)網(wǎng),它會將數(shù)據(jù)從應用程序上下文復制到內(nèi)核上下文。
圖像概念來自:https://developer.ibm.com/articles/j-zerocopy/
正如您所看到的,將數(shù)據(jù)在內(nèi)核上下文和應用程序上下文之間進行復制是多余的,這會消耗CPU周期和內(nèi)存帶寬,尤其是在數(shù)據(jù)量很大時會導致性能下降。這正是零拷貝原則要解決的問題。
圖像概念來自:https://developer.ibm.com/articles/j-zerocopy/
批量數(shù)據(jù)和壓縮
高效的壓縮需要將多個消息一起壓縮,而不是分別壓縮每個消息。
Kafka 支持這一點,允許遞歸消息集。一批消息可以被聚合在一起壓縮,并以這種形式發(fā)送到服務器。這批消息將以壓縮形式寫入,保持在日志中并只能由消費者解壓縮。
假設(shè)帶寬為10MB/s,一次性發(fā)送10MB數(shù)據(jù)比逐個發(fā)送10000條消息要快得多(假設(shè)每條消息占用100字節(jié))。
壓縮會提高消費者的吞吐量,但會增加一些解壓縮成本。
Kafka 支持 GZIP 和 SnAppy 壓縮協(xié)議。
水平擴展
首先讓我們了解什么是垂直擴展。假設(shè)對于傳統(tǒng)數(shù)據(jù)庫服務器,當負載增加時,處理的一種方法是添加更多的資源,例如 CPU、RAM、SSD 等。這被稱為垂直擴展。它有一些缺點,如下所示:
- 每臺硬件都有限制,無法無限制地向上擴展
- 如果機器宕機怎么辦?通常需要停機時間
水平擴展通過添加更多的機器來解決相同的問題。
Kafka 具有在數(shù)千臺機器之間為單個主題擁有數(shù)千個分區(qū)的能力,這意味著 Kafka 可以處理大量負載。