1. 程式人生 > >《KAFKA官方文件》簡介

《KAFKA官方文件》簡介

原文連結

Kafka是一個分散式的流平臺。這意味著什麼?

我們認為流平臺有3個核心的能力

  1. 允許釋出和訂閱記錄流。在這方面類似訊息佇列和企業級的訊息系統。
  2. 允許以容錯的方式儲存記錄流。
  3. 允許以流的形式處理記錄。

Kafka擅長於做什麼?

它被用於兩大類應用:

  1. 在應用間構建實時的資料流通道
  2. 構建傳輸或處理資料流的實時流式應用

幾個概念:

  • Kafka以叢集模式執行在1或多臺伺服器上
  • Kafka以topics的形式儲存資料流
  • 每一個記錄包含一個key、一個value和一個timestamp

Kafka有4個核心API:

  • Producer API:用於應用程式將資料流傳送到一個或多個Kafka topics
  • Consumer API:用於應用程式訂閱一個或多個topics並處理被髮送到這些topics中的資料
  • Streams API:允許應用程式作為流處理器,處理來自一個或多個topics的資料並將處理結果傳送到一個或多個topics中,有效的將輸入流轉化為輸出流
  • Connector API:用於構建和執行將Kafka topics和現有應用或資料系統連線的可重用的produers和consumers。例如,如連結到關係資料庫的聯結器可能會捕獲某個表所有的變更

kafka-apis

Kafka客戶端和服務端之間的通訊是建立在簡單的、高效的、語言無關的TCP協議上的。此協議帶有版本且向後相容。我們為Kafka提供了Java客戶端,但是客戶端可以使用多種語言。

Topics and Logs

Topic是釋出記錄的類別。Kafka中的Topics一般是多訂閱者的,也就是一個Topic可以有0個或多個Consumer訂閱它的資料。

對於每個主題,Kafka會會維護一個如下所示的分割槽日誌:

每個分割槽是一個有序的,以不可變的記錄順序追加的Commit Log。分割槽中的每個記錄都有一個連續的ID,稱為Offset,唯一標識分割槽內的記錄。

Kafka叢集使用記錄儲存時間的配置來儲存所有已釋出的記錄(無論他們是否被消費)。例如,配置策略為兩天,那麼在一條記錄釋出兩天內,這條記錄是可以被消費的,之後將被丟棄以騰出空間。Kafka的效能和資料量無關,所以儲存長時間的資料並不會成為問題。

log_consumer

實際上唯一需要儲存的元資料是消費者的消費進度,即消費日誌的偏移量(Offset)。這個Offset是由Consumer控制的:通常消費者會在讀取記錄時以線性方式提升Offset,但是事實上,由於Offset由Consumer控制,因此它可以以任何順序消費記錄。例如一個Consumer可以通過重置Offset來處理過去的資料或者跳過部分資料。

這個特徵意味著Kafka的Consumer可以消費“過去”和“將來”的資料而不對叢集和其他Consumer不造成太大的影響。例如,可以使用命令列工具tail來獲取Topic尾部的內容而不對已經在消費Consumer造成影響。

分割槽日誌有幾個目的。第一,使伺服器能承載日誌的大小,每個分割槽的日誌必須可以被儲存在單個伺服器上,但是一個Topic可以擁有多個分割槽,那麼它可以處理任意大小的資料量。第二,它們作為並行度的單位(更多的是這點的考慮)。

Distribution

分割槽日誌分佈在叢集中伺服器中,每個伺服器處理一部分分割槽的資料和請求。每個分割槽可以配置分佈的伺服器,以實現容錯。

每個分割槽擁有一個Leader節點,和零或多個Follower。Leader處理該分割槽所有的讀寫請求,Follower複製Leader資料。如果Leader節點宕機,將會有一個Follower節點自動的轉化為Leader。每個節點成為其部分分割槽的Leader,併成為剩餘分割槽的Follower,這樣整個叢集的負載將比較均衡。

Producers

Producer傳送資料到它選擇的Topic。Producer負責決定將資料傳送到Topic的那個分割槽上。這可以通過簡單的迴圈方式來平衡負載,或則可以根據某些語義來決定分割槽(例如基於資料中一些關鍵字)。

Consumers

Consumer使用一個group name來標識自己的身份,每條被髮送到一個Topic的訊息都將被分發到屬於同一個group的Consumer的一個例項中(group name相同的Consumer屬於一個組,一個Topic的一條訊息會被這個組中的一個Consumer例項消費)。Consumer例項可以在單獨的程序中或者單獨的機器上。

如果所有的Consumer例項都是屬於一個group的,那麼所有的訊息將被均衡的分發給每個例項。

如果所有的Consumer都屬於不同的group,那麼每條訊息將被廣播給所有的Consumer。

consumer-groups

(上圖)一個包含兩個Server的Kafka叢集,擁有四個分割槽(P0-P3),有兩個Consumer group:Group A和Group B。Group有C1、C2兩個Consumer,GroupB有C3、C4、C5、C6四個Consumer。

更常見的是,Topic有少量的Consumer group,每一個都是“一個邏輯上的訂閱者”。每個group包含多個Consumer例項,為了可伸縮性和容錯性。這就是一個釋出-訂閱模式,只是訂閱方是一個叢集。

Kafka中消費的實現方式是“公平”的將分割槽分配給Consumer,每一個時刻分割槽都擁有它唯一的消費者。Consumer成員關係有Kafka程度動態維護。如果新的Consumer加入了分割槽,那麼它會從這個分割槽其他的Consumer中分配走一部分分割槽;如果部分Consumer例項宕機,它的分割槽會被其他Consumer例項接管。

Kafka只保證同一個分割槽內記錄的順序,而不是同一個Topic的不同分割槽間資料的順序。每個分割槽順序結合按Key分配分割槽的能力,能滿足大多數程式的需求。如果需要全域性的順序,可以使用只有一個分割槽的Topic,這意味著每個group只能有一個Consumer例項(因為一個分割槽同一時刻只能被一份Consumer消費——多加的Consumer只能用於容錯)。

Guarantees

Kafka高階API中提供一些能力:

被一個Producer傳送到特定Topic分割槽的訊息將按照他們的傳送順序被新增到日誌中。這意味著,如果M1、M2是被同一個Producer傳送出來的,且M1先發送,那麼M1擁有更小的Offset,在日誌中的位置更靠前。

Consumer按照訊息的儲存順序在日誌檔案中查詢訊息。

對於複製配置引數為N的Topic,我們能容忍N-1的伺服器故障,而不會丟失已經Commit的資料。有關這些保證更詳細的資訊,參見文件的設計部分。

Kafka as a Messaging System

Kafka的流模式和傳統的訊息系統有什麼區別?

訊息傳統上有兩種模式:佇列和釋出-訂閱。在佇列中,一群Consumer從一個Server讀取資料,每條訊息被其中一個Consumer讀取。在釋出-訂閱中,訊息被廣播給所有的Consumer。這兩種模式有各自的優缺點。佇列模式的優點是你可以在多個消費者例項上分配資料處理,從而允許你對程式進行“伸縮”。確定是佇列不是多使用者的,一旦訊息被一個Consumer讀取就不會再給其他Consumer。釋出訂閱模式允許廣播資料到多個Consumer,那麼就沒辦法對單個Consumer進行伸縮。

Kafka的Consumer group包含兩個概念。與佇列一樣,消費組允許通過一些程序來劃分處理(每個程序處理一部分)。與釋出訂閱一樣,Kafka允許廣播訊息到不同的Consumer group。

Kafka模式的優勢是每個Topic都擁有佇列和釋出-訂閱兩種模式。

Kafka比傳統的訊息系統有更強的順序保證。

傳統的訊息系統在伺服器上按順序儲存訊息,如果多個Consumer從佇列中消費訊息,伺服器按照儲存的順序輸出訊息。然後伺服器雖然按照順序輸出訊息,但是訊息將被非同步的傳遞給Consumer,所以他們將以不確定的順序到達Consumer。這意味著在並行消費中將丟失訊息順序。傳統訊息系統通常採用“唯一消費者”的概念只讓一個Consumer進行消費,但這就丟失了並行處理的能力。

Kafka做的更好一些。通過提供分割槽的概念,Kafka能提供消費叢集順序和負載的平衡。這是通過將分割槽分配個一個Consumer group中唯一的一個Consumer而實現的,一個分割槽只會被一個分組中的一個Consumer進行消費。通過這麼實現,能讓一個Consumer消費一個分割槽並按照順序處理訊息。因為存在多個分割槽,所有可以在多個Consumer例項上實現負載均衡。注意,一個分組內的Consumer例項數不能超過分割槽數。

Kafka as a Storage System

任何將傳送訊息和消費結構的訊息佇列都有效的用作一個訊息的儲存系統。不同的是Kafka是一個更好的儲存系統。

被寫入到Kafka的資料將被寫入磁碟並複製以保證容錯。Kafka允許Producer等待確定,以保證Producer可以確認訊息被成功持久化並複製完成。

Kafka使用的儲存結構,使其提供相同的能力,無論是儲存50KB或者50TB持久化資料。

因為允許客戶端控制讀取的位置,可以將Kafka視為高效能,低延遲的日誌儲存、複製、傳播的分散式系統。

Kafka for Stream Processing

僅僅是讀寫和儲存流資料是不夠的,Kafka的目標是對流失資料的實時處理。

在Kafka中,Stream Producer從輸入的Topic中讀取資料,執行一些操作,生成輸出流到輸出的Topic中。

例如,零售的應用程式將收到銷售和出貨的輸入流,並輸出根據該資料計算的重排序和價格調整後的資料流。

可以使用Producer和Consumer實現簡單的處理。對於更復雜的轉換,Kafka提供的完成的Stream API,允許構建將流中資料聚合或將流連線到一起的應用。

這用於解決以下的一些困難:處理無需的資料,執行有狀態的計算等。

Stream API基於Kafka的核心函式古劍:使用Producer和Consumer API用於輸入,使用Kafka作為有狀態的儲存,使用group機制來實現Stream處理器的容錯。

Putting the Pieces Together

訊息、儲存和流處理這種組合看是不尋常,但是Kafka作為流式平臺這是必須的。

類似HDFS的分散式檔案系統儲存靜態的檔案用於批處理。這種的系統允許儲存和處理歷史資料。

傳統的企業訊息系統允許處理在你訂閱之後的未來的資料。以這種方式構建的應用程式在未來資料到達時進行處理。

Kafka組合這些能力,並且組合這些對Kafka作為流應用平臺和流資料通道至關重要。

通過組合儲存和低延遲的訂閱,流應用程式能以相同的方式處理過去和未來的資料。一個單一的程式可以處理過去的歷史資料,並且不會在達到一個位置時停止,而是能繼續處理將來到達的資料。這是一個廣泛的流處理的概念,其中包含批處理和訊息驅動的應用程式。

同樣,對於資料流通道,組合訂閱機制和實時事件使Kafka成為非常低延遲的管道;資料的儲存能力使其能和可能會進行停機維護的週期性處理資料的離線系統整合,或用於必須保證資料被確認交付的場景。流處理程式可以在資料到達後進行處理。

其他關閉Kafka提供的API、功能,參閱其他文件。


丞一

丞一

中介軟體技術專家 at 螞蟻金服丞一,目前就職於螞蟻金服,熱衷於研究分散式系統相關的技術;微信公眾號:MessageQueue,歡迎交流;