Kafka原始碼分析(一)

2022-06-06 08:51:10 字數 4720 閱讀 1180

apache kafka® 是 乙個分布式流處理平台. 這到底意味著什麼呢?

我們知道流處理平台有以下三種特性:

它可以用於兩大類別的應用:

為了理解kafka是如何做到以上所說的功能,從下面開始,我們將深入探索kafka的特性。.

首先是一些概念:

kafka有四個核心的api:

讓我們首先深入了解下kafka的核心概念:提供一串流式的記錄— topic 。

topic 就是資料主題,是資料記錄發布的地方,可以用來區分業務系統。kafka中的topics總是多訂閱者模式,乙個topic可以擁有乙個或者多個消費者來訂閱它的資料。

對於每乙個topic, kafka集群都會維持乙個分割槽日誌,如下所示:

每個分割槽都是有序且順序不可變的記錄集,並且不斷地追加到結構化的commit log檔案。分割槽中的每乙個記錄都會分配乙個id號來表示順序,我們稱之為offset,offset用來唯一的標識分割槽中每一條記錄。

kafka 集群保留所有發布的記錄—無論他們是否已被消費—並通過乙個可配置的引數——保留期限來控制. 舉個例子, 如果保留策略設定為2天,一條記錄發布後兩天內,可以隨時被消費,兩天過後這條記錄會被拋棄並釋放磁碟空間。kafka的效能和資料大小無關,所以長時間儲存資料沒有什麼問題.

事實上,在每乙個消費者中唯一儲存的元資料是offset(偏移量)即消費在log中的位置.偏移量由消費者所控制:通常在讀取記錄後,消費者會以線性的方式增加偏移量,但是實際上,由於這個位置由消費者控制,所以消費者可以採用任何順序來消費記錄。例如,乙個消費者可以重置到乙個舊的偏移量,從而重新處理過去的資料;也可以跳過最近的記錄,從"現在"開始消費。

這些細節說明kafka 消費者是非常廉價的—消費者的增加和減少,對集群或者其他消費者沒有多大的影響。比如,你可以使用命令列工具,對一些topic內容執行 tail操作,並不會影響已存在的消費者消費資料。

日誌中的 partition(分割槽)有以下幾個用途。第一,當日誌大小超過了單台伺服器的限制,允許日誌進行擴充套件。每個單獨的分割槽都必須受限於主機的檔案限制,不過乙個主題可能有多個分割槽,因此可以處理無限量的資料。第二,可以作為並行的單元集—關於這一點,更多細節如下

日誌的分割槽partition(分布)在kafka集群的伺服器上。每個伺服器在處理資料和請求時,共享這些分割槽。每乙個分割槽都會在已配置的伺服器上進行備份,確保容錯性.

每個分割槽都有一台server作為「leader」,零颱或者多台server作為follwersleader server處理一切對partition(分割槽)的讀寫請求,而follwers只需被動的同步leader上的資料。當leader宕機了,followers中的一台伺服器會自動成為新的leader。每台server都會成為某些分割槽的leader和某些分割槽的follower,因此集群的負載是平衡的。

生產者可以將資料發布到所選擇的topic(主題)中。生產者負責將記錄分配到topic的哪乙個partition(分割槽)中。可以使用迴圈的方式來簡單地實現負載均衡,也可以根據某些語義分割槽函式(例如:記錄中的key)來完成。下面會介紹更多關於分割槽的使用。

消費者使用乙個消費組名稱來進行標識,發布到topic中的每條記錄被分配給訂閱消費組中的乙個消費者例項.消費者例項可以分布在多個程序中或者多個機器上。

如果所有的消費者例項在同一消費組中,訊息記錄會負載平衡到每乙個消費者例項.

如果所有的消費者例項在不同的消費組中,每條訊息記錄會廣播到所有的消費者程序.

如圖,這個 kafka 集群有兩台 server 的,四個分割槽(p0-p3)和兩個消費者組。消費組a有兩個消費者,消費組b有四個消費者。

通常情況下,每個 topic 都會有一些消費組,乙個消費組對應乙個"邏輯訂閱者"。乙個消費組由許多消費者例項組成,便於擴充套件和容錯。這就是發布和訂閱的概念,只不過訂閱者是一組消費者而不是單個的程序。

在kafka中實現消費的方式是將日誌中的分割槽劃分到每乙個消費者例項上,以便在任何時間,每個例項都是分割槽唯一的消費者。維護消費組中的消費關係由kafka協議動態處理。如果新的例項加入組,他們將從組中其他成員處接管一些 partition 分割槽;如果乙個例項消失,擁有的分割槽將被分發到剩餘的例項。

kafka 只保證分區內的記錄是有序的,而不保證主題中不同分割槽的順序。每個 partition 分割槽按照key值排序足以滿足大多數應用程式的需求。但如果你需要總記錄在所有記錄的上面,可使用僅有乙個分割槽的主題來實現,這意味著每個消費者組只有乙個消費者程序。

high-level kafka給予以下保證:

kafka streams的概念與傳統的企業訊息系統相比如何?

傳統的訊息系統有兩個模組: 佇列 和 發布-訂閱。 在佇列中,消費者池從server讀取資料,每條記錄被池子中的乙個消費者消費; 在發布訂閱中,記錄被廣播到所有的消費者。兩者均有優缺點。 佇列的優點在於它允許你將處理資料的過程分給多個消費者例項,使你可以擴充套件處理過程。 不好的是,佇列不是多訂閱者模式的—一旦乙個程序讀取了資料,資料就會被丟棄。 而發布-訂閱系統允許你廣播資料到多個程序,但是無法進行擴充套件處理,因為每條訊息都會傳送給所有的訂閱者。

消費組在kafka有兩層概念。在佇列中,消費組允許你將處理過程分發給一系列程序(消費組中的成員)。 在發布訂閱中,kafka允許你將訊息廣播給多個消費組。

kafka的優勢在於每個topic都有以下特性—可以擴充套件處理並且允許多訂閱者模式—不需要只選擇其中乙個.

kafka相比於傳統訊息佇列還具有更嚴格的順序保證

傳統佇列在伺服器上儲存有序的記錄,如果多個消費者消費佇列中的資料, 伺服器將按照儲存順序輸出記錄。 雖然伺服器按順序輸出記錄,但是記錄被非同步傳遞給消費者, 因此記錄可能會無序的到達不同的消費者。這意味著在並行消耗的情況下, 記錄的順序是丟失的。因此訊息系統通常使用「唯一消費者」的概念,即只讓乙個程序從佇列中消費, 但這就意味著不能夠並行地處理資料。

kafka 設計的更好。topic中的partition是乙個並行的概念。 kafka能夠為乙個消費者池提供順序保證和負載平衡,是通過將topic中的partition分配給消費者組中的消費者來實現的, 以便每個分割槽由消費組中的乙個消費者消耗。通過這樣,我們能夠確保消費者是該分割槽的唯一讀者,並按順序消費資料。 眾多分割槽保證了多個消費者例項間的負載均衡。但請注意,消費者組中的消費者例項個數不能超過分割槽的數量。

許多訊息佇列可以發布訊息,除了消費訊息之外還可以充當中間資料的儲存系統。那麼kafka作為乙個優秀的儲存系統有什麼不同呢?

資料寫入kafka後被寫到磁碟,並且進行備份以便容錯。直到完全備份,kafka才讓生產者認為完成寫入,即使寫入失敗kafka也會確保繼續寫入

kafka使用磁碟結構,具有很好的擴充套件性—50kb和50tb的資料在server上表現一致。

可以儲存大量資料,並且可通過客戶端控制它讀取資料的位置,您可認為kafka是一種高效能、低延遲、具備日誌儲存、備份和傳播功能的分布式檔案系統。

kafka 流處理不僅僅用來讀寫和儲存流式資料,它最終的目的是為了能夠進行實時的流處理。

在kafka中,流處理器不斷地從輸入的topic獲取流資料,處理資料後,再不斷生產流資料到輸出的topic中去。

例如,零售應用程式可能會接收銷售和出貨的輸入流,經過**調整計算後,再輸出一串流式資料。

簡單的資料處理可以直接用生產者和消費者的api。對於複雜的資料變換,kafka提供了streams api。 stream api 允許應用做一些複雜的處理,比如將流資料聚合或者join。

這一功能有助於解決以下這種應用程式所面臨的問題:處理無序資料,當消費端**變更後重新處理輸入,執行有狀態計算等。

streams api建立在kafka的核心之上:它使用producer和consumer api作為輸入,使用kafka進行有狀態的儲存, 並在流處理器例項之間使用相同的消費組機制來實現容錯。

將訊息、儲存和流處理結合起來,使得kafka看上去不一般,但這是它作為流平台所備的.

像hdfs這樣的分布式檔案系統可以儲存用於批處理的靜態檔案。 乙個系統如果可以儲存和處理歷史資料是非常不錯的。

傳統的企業訊息系統允許處理訂閱後到達的資料。以這種方式來構建應用程式,並用它來處理即將到達的資料。

kafka結合了上面所說的兩種特性。作為乙個流應用程式平台或者流資料管道,這兩個特性,對於kafka 來說是至關重要的。

通過組合儲存和低延遲訂閱,流式應用程式可以以同樣的方式處理過去和未來的資料。 乙個單一的應用程式可以處理歷史記錄的資料,並且可以持續不斷地處理以後到達的資料,而不是在到達最後一條記錄時結束程序。 這是乙個廣泛的流處理概念,其中包含批處理以及訊息驅動應用程式

同樣,作為流資料管道,能夠訂閱實時事件使得kafk具有非常低的延遲; 同時kafka還具有可靠儲存資料的特性,可用來儲存重要的支付資料, 或者與離線系統進行互動,系統可間歇性地載入資料,也可在停機維護後再次載入資料。流處理功能使得資料可以在到達時轉換資料。

kafka原始碼分析 kafkaconsumer

kafkaconsumer 對於多執行緒訪問是不安全的,通過使用acquire 跟release 方法來操作atomiclong currentthread字段 儲存當前訪問執行緒id 有多個執行緒同時訪問丟擲concurrentmodificationexception,來防止對個執行緒同時訪問。...

Kafka原始碼分析之KafkaProducer

kafkaproducer是乙個kafka客戶端實現,可以發布記錄records至kafka集群。kafkaproducer是執行緒安全的,多執行緒之間共享單獨乙個producer例項通常會比多個producer例項要快。kafkaproducer包含一組快取池空間,儲存尚未傳輸到集群的記錄reco...

kafka原始碼分析 scheduler分析

kafka scheduler用於執行作業的排程程式。控制乙個在後台定期重複執行或者延遲排程的作業!主要有一下操作 初始化任務以便可以接受任務排程 def startup 當任務排程完成關閉。def shutdown 延遲佇列實現 排程任務 def schedule name string,fun ...