Apache Kafka官方文檔翻譯(原創)
Apache Kafka是一個分布式流平臺。準確的說是什麽意思呢?
我們認為流平臺具有三種關鍵能力:
1、讓你對數據流進行發布訂閱。因此他很像一個消息隊列和企業級消息系統。
2、讓你以高容錯的方式存儲數據流。
3、讓你在數據流出現時處理他們。
kafka擅長什麽?
他通常被用在兩大類應用:
1、構建一個能可靠的在系統或應用之間獲取數據的實時的數據流管道。
2、構建一個能轉換或響應數據流的實時流應用。
為了更好的理解kafka是如何做到上面的事,下面我們深入探索kafka的各種姿勢。
首先了解幾個概念:
1、kafka是以集群的方式運行在一臺或多臺服務器上
2、kafka集群數據存儲在我們稱作topic的分類裏
3、每個記錄由一個key,一個value和一個時間戳組成
kafka有下面四個核心APIs:
1、Producer API允許一個應用廣播一個數據流到一個或多個kafka topic
2、Customer API允許一個應用訂閱一個或多個topic,並且處理生產給他們的數據流
3、Stream API 允許應用像一個流處理器,消費從一個或多個topic輸入的數據流,然後向一個或多個topic生產出輸出數據流,在輸入和輸出之間高效的轉換
4、Connector API 允許創建並運行可重復利用的連接kafka topics到現存的應用和數據系統的生產者和消費者。舉個栗子,一個關系型數據庫的connector可以捕獲到表的每一個更改
在kafka中,客戶端與服務端的通信通過一個簡單的,高效的,與語言無關的TCP協議完成。這個協議的版本向後兼容老版本。我們為kafka提供了一個java的客戶端,但是客戶端可以使用很多語言。
Topic 和 Logs
讓我們第一次深入了解kafka為數據流提供的核心抽象概念---the topic
topic是發布記錄的類別或提要名稱。topic在kafka中總是被多重訂閱,因此,一個topic可以有0個,一個,或多個訂閱了其寫入數據的消費者。
對於每個topic,Kafka集群維護一個像這樣的分區日誌:
每個分區都是一個有序的,不可變的記錄序列,這個序列會被不斷的增加一種結構化的提交日誌。在分區中的記錄會被分配一個叫做offset(偏移量)的連續的id號,這個offset是每個在分區中的記錄的唯一識別標示。
kafka集群保存所有的發布記錄,無論他們是否被消費,使用一個可配置的保存時間。例如,保存策略設置為2天,那麽在這個消息被發布後的兩天內,他依然可以被消費,之後他會被丟棄來釋放空間。kafka的是高效和穩定的,表現在他對數據大小的尊重,因此長時間存儲不是問題。
實際上,在每個消費者基礎上保留的唯一元數據是日誌中該消費者的偏移量或位置。這個offset被消費者控制:通常一個消費者在讀取記錄時將會進行線性偏移,但是,實際上,因為位置是由消費者控制,只要他願意,他可以任何循序消費記錄。例如一個消費者可以重置到老的offset去重新處理來自以前的數據,或者往前跳到最近的記錄並從“現在”開始消費。
這種多特征的組合意味著kafka消費者非常輕量-他們來去自如,不會對集群和其他消費者帶來很大影響。例如,你可以使用我們的命令行工具去“tail”所有的topic內容而不會更改被現存消費者消費的記錄。
日誌中的分區有很多用途。一、他們允許日誌量超過單個服務器所承受的大小。每個獨立的分區必須受限於運行它的server,但是一個topic可以有多個分區,因此他可以處理任意大小數據。二、它們作為並行的單元。
Distribution
日誌上的分區被分布在kafka集群的服務器上,每個服務器處理一部分分區的數據和請求。每個分區都跨可配置數量的多機器進行數據復制以保證容錯。
每個分區都有一個被視為leader的服務器,0個或多個服務器作為followers。leader處理所有的讀寫請求,followers被動的復制leader。如果leader掛了,followers中的一個將自動的成為新的leader。每個服務器作為他自己部分分區的leader,同時也作為其他分區的follower,因此在集群中負載非常均衡。
Producers
生產者發布數據到指定的topic。生產者有責任選擇記錄分配到topic的哪個分區。這可以基於輪詢(round-robin)來完成進行簡單的負載均衡,或者根據語義分區函數(假如基於記錄中的一些關鍵字)。
Consumers
消費者用一個消費者組名標記自己,每個記錄發布到一個topic被傳遞到包含每個訂閱消費組的消費者實例。
消費者實例可以在分開的進程中也可以在分開的機器。
如果所有的消費者實例有同樣的消費組號,那麽記錄會很高效的在消費實例中負載均衡。
如果所有的消費者實例有不同的消費組號,那麽每個記錄將廣播到所有消費者進程。
一個兩臺服務器的kafka集群運行四個分區(P0-P3)有兩個消費者組。消費組A有兩個消費實例,組B有四個。
我們發現這個topic有很小的消費組數量,每個消費組代表一個“邏輯訂閱者”。每個組由許多消費者實例組成為了可擴展性與高容錯性。這就是一個訂閱者由一個消費集群代替了原來的單一進程的發布訂閱結構。
在Kafka中實現消費的方式是將日誌中的分區劃分給消費者實例,以便每個實例都是在任何時間點上“公平共享”分區的唯一使用者。這個維護組員的進程由kafka協議動態處理。如果新實例加入組,他們將從其他組的成員接管一些分區;如果一個實例掛了,他的分區將會分給存在的實例。
需要註意的是,在consumer grup中的consumer instances的數量不能多於partitions的數量。
kafka僅提供在一個分區內的完全排序記錄,不是在同一topic不同分區之間的。結合每個partition內部消息數據的有序性和按Key劃分多partitions的能力,對大多數應用都夠用了。
然而,如果你的應用需要的是一個基於全部消息數據的完全的有序隊列,也可以通過一種特殊的方式來達到目的。即為一個topic只劃分一個partition,且在consumer group中只能有一個consumer進程。
Guarantees
(1)一個生產者向指定topic的一個partition發送的消息,將會被按消息的發送順序追加到隊列中。因此對於一個生產者先後發送的消息M1和M2,M1會比M2有一個更小的 offset,並且會更早的出現在日誌中。
(2)一個consumer instance看到的消息順序與它們在Log中存儲的順序相同。
(3)對於一個復制因子為N的topic,可以容忍N-1 server宕機不丟失數據。
Apache Kafka官方文檔翻譯(原創)