1. 程式人生 > >【轉】kafka-告訴你什麼是kafka

【轉】kafka-告訴你什麼是kafka

文章轉自:http://orchome.com/5

Kafka作為一個分散式的流平臺,這到底意味著什麼?

我們認為,一個流處理平臺具有三個關鍵能力:

  1. 釋出和訂閱訊息(流),在這方面,它類似於一個訊息佇列或企業訊息系統。

  2. 以容錯的方式儲存訊息(流)。

  3. 在訊息流發生時處理它們。

什麼是kakfa的優勢?

它應用於2大類應用:

  1. 構建實時的流資料管道,可靠地獲取系統和應用程式之間的資料。

  2. 構建實時流的應用程式,對資料流進行轉換或反應。

要了解kafka是如何做這些事情的,讓我們從下到上深入探討kafka的能力。

首先幾個概念:

  1. kafka作為一個叢集執行在一個或多個伺服器上。

  2. kafka叢集儲存的訊息是以topic為類別記錄的。

  3. 每個訊息(也叫記錄record,我習慣叫訊息)是由一個key,一個value和時間戳構成。

kafka有四個核心API:

  • 應用程式使用 Producer API 釋出訊息到1個或多個topic(主題)。

  • 應用程式使用 Consumer API 來訂閱一個或多個topic,並處理產生的訊息。

  • 應用程式使用 Streams API 充當一個流處理器,從1個或多個topic消費輸入流,並生產一個輸出流到1個或多個輸出topic,有效地將輸入流轉換到輸出流。

  • Connector API允許構建或執行可重複使用的生產者或消費者,將topic連線到現有的應用程式或資料系統。例如,一個關係資料庫的聯結器可捕獲每一個變化。

Client和Server之間的通訊,是通過一條簡單、高效能並且和開發語言無關的TCP協議。並且該協議保持與老版本的相容。Kafka提供了Java Client(客戶端)。除了Java Client外,還有非常多的其它程式語言的Client

首先來了解一下Kafka所使用的基本術語:

Topic

Kafka將訊息種子(Feed)分門別類,每一類的訊息稱之為一個主題(Topic).

Producer

釋出訊息的物件稱之為主題生產者(Kafka topic producer)

Consumer

訂閱訊息並處理髮布的訊息的種子的物件稱之為主題消費者(consumers)

Broker

已釋出的訊息儲存在一組伺服器中,稱之為Kafka叢集。叢集中的每一個伺服器都是一個代理(Broker). 消費者可以訂閱一個或多個主題(topic),並從Broker拉資料,從而消費這些已釋出的訊息。

主題和日誌 (Topic和Log)

讓我們更深入的瞭解Kafka中的Topic。

Topic是釋出的訊息的類別或者種子Feed名。對於每一個Topic,Kafka叢集維護這一個分割槽的log,就像下圖中的示例:

每一個分割槽都是一個順序的、不可變的訊息佇列, 並且可以持續的新增。分割槽中的訊息都被分了一個序列號,稱之為偏移量(offset),在每個分割槽中此偏移量都是唯一的。

Kafka叢集保持所有的訊息,直到它們過期, 無論訊息是否被消費了。 實際上消費者所持有的僅有的元資料就是這個偏移量,也就是消費者在這個log中的位置。 這個偏移量由消費者控制:正常情況當消費者消費訊息的時候,偏移量也線性的的增加。但是實際偏移量由消費者控制,消費者可以將偏移量重置為更老的一個偏移量,重新讀取訊息。 可以看到這種設計對消費者來說操作自如, 一個消費者的操作不會影響其它消費者對此log的處理。 再說說分割槽。Kafka中採用分割槽的設計有幾個目的。一是可以處理更多的訊息,不受單臺伺服器的限制。Topic擁有多個分割槽意味著它可以不受限的處理更多的資料。第二,分割槽可以作為並行處理的單元,稍後會談到這一點。

分散式(Distribution)

Log的分割槽被分佈到叢集中的多個伺服器上。每個伺服器處理它分到的分割槽。 根據配置每個分割槽還可以複製到其它伺服器作為備份容錯。 每個分割槽有一個leader,零或多個follower。Leader處理此分割槽的所有的讀寫請求,而follower被動的複製資料。如果leader宕機,其它的一個follower會被推舉為新的leader。 一臺伺服器可能同時是一個分割槽的leader,另一個分割槽的follower。 這樣可以平衡負載,避免所有的請求都只讓一臺或者某幾臺伺服器處理。

Geo-Replication(異地資料同步技術)

Kafka MirrorMaker為群集提供geo-replication支援。藉助MirrorMaker,訊息可以跨多個數據中心或雲區域進行復制。 您可以在active/passive場景中用於備份和恢復; 或者在active/passive方案中將資料置於更接近使用者的位置,或資料本地化。

生產者(Producers)

生產者往某個Topic上釋出訊息。生產者也負責選擇釋出到Topic上的哪一個分割槽。最簡單的方式從分割槽列表中輪流選擇。也可以根據某種演算法依照權重選擇分割槽。開發者負責如何選擇分割槽的演算法。

消費者(Consumers)

通常來講,訊息模型可以分為兩種, 佇列和釋出-訂閱式。 佇列的處理方式是 一組消費者從伺服器讀取訊息,一條訊息只有其中的一個消費者來處理。在釋出-訂閱模型中,訊息被廣播給所有的消費者,接收到訊息的消費者都可以處理此訊息。Kafka為這兩種模型提供了單一的消費者抽象模型: 消費者組 (consumer group)。 消費者用一個消費者組名標記自己。 一個釋出在Topic上訊息被分發給此消費者組中的一個消費者。 假如所有的消費者都在一個組中,那麼這就變成了queue模型。 假如所有的消費者都在不同的組中,那麼就完全變成了釋出-訂閱模型。 更通用的, 我們可以建立一些消費者組作為邏輯上的訂閱者。每個組包含數目不等的消費者, 一個組內多個消費者可以用來擴充套件效能和容錯。正如下圖所示:

2個kafka叢集託管4個分割槽(P0-P3),2個消費者組,消費組A有2個消費者例項,消費組B有4個。

正像傳統的訊息系統一樣,Kafka保證訊息的順序不變。 再詳細扯幾句。傳統的佇列模型保持訊息,並且保證它們的先後順序不變。但是, 儘管伺服器保證了訊息的順序,訊息還是非同步的傳送給各個消費者,消費者收到訊息的先後順序不能保證了。這也意味著並行消費將不能保證訊息的先後順序。用過傳統的訊息系統的同學肯定清楚,訊息的順序處理很讓人頭痛。如果只讓一個消費者處理訊息,又違背了並行處理的初衷。 在這一點上Kafka做的更好,儘管並沒有完全解決上述問題。 Kafka採用了一種分而治之的策略:分割槽。 因為Topic分割槽中訊息只能由消費者組中的唯一一個消費者處理,所以訊息肯定是按照先後順序進行處理的。但是它也僅僅是保證Topic的一個分割槽順序處理,不能保證跨分割槽的訊息先後處理順序。 所以,如果你想要順序的處理Topic的所有訊息,那就只提供一個分割槽。

Kafka的保證(Guarantees)

  • 生產者傳送到一個特定的Topic的分割槽上,訊息將會按照它們傳送的順序依次加入,也就是說,如果一個訊息M1和M2使用相同的producer傳送,M1先發送,那麼M1將比M2的offset低,並且優先的出現在日誌中。

  • 消費者收到的訊息也是此順序。

  • 如果一個Topic配置了複製因子(replication factor)為N, 那麼可以允許N-1伺服器宕機而不丟失任何已經提交(committed)的訊息。

有關這些保證的更多詳細資訊,請參見文件的設計部分。

kafka作為一個訊息系統

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

傳統的訊息有兩種模式:佇列和釋出訂閱。 在佇列模式中,消費者池從伺服器讀取訊息(每個訊息只被其中一個讀取); 釋出訂閱模式:訊息廣播給所有的消費者。這兩種模式都有優缺點,佇列的優點是允許多個消費者瓜分處理資料,這樣可以擴充套件處理。但是,佇列不像多個訂閱者,一旦訊息者程序讀取後故障了,那麼訊息就丟了。而釋出和訂閱允許你廣播資料到多個消費者,由於每個訂閱者都訂閱了訊息,所以沒辦法縮放處理。

kafka中消費者組有兩個概念:佇列:消費者組(consumer group)允許同名的消費者組成員瓜分處理。釋出訂閱:允許你廣播訊息給多個消費者組(不同名)。

kafka的每個topic都具有這兩種模式。

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

傳統的訊息系統按順序儲存資料,如果多個消費者從佇列消費,則伺服器按儲存的順序傳送訊息,但是,儘管伺服器按順序傳送,訊息非同步傳遞到消費者,因此訊息可能亂序到達消費者。這意味著訊息存在並行消費的情況,順序就無法保證。訊息系統常常通過僅設1個消費者來解決這個問題,但是這意味著沒用到並行處理。

kafka做的更好。通過並行topic的parition —— kafka提供了順序保證和負載均衡。每個partition僅由同一個消費者組中的一個消費者消費到。並確保消費者是該partition的唯一消費者,並按順序消費資料。每個topic有多個分割槽,則需要對多個消費者做負載均衡,但請注意,相同的消費者組中不能有比分割槽更多的消費者,否則多出的消費者一直處於空等待,不會收到訊息。

kafka作為一個儲存系統

所有釋出訊息到訊息佇列和消費分離的系統,實際上都充當了一個儲存系統(釋出的訊息先儲存起來)。Kafka比別的系統的優勢是它是一個非常高效能的儲存系統。

寫入到kafka的資料將寫到磁碟並複製到叢集中保證容錯性。並允許生產者等待訊息應答,直到訊息完全寫入。

kafka的磁碟結構 - 無論你伺服器上有50KB或50TB,執行是相同的。

client來控制讀取資料的位置。你還可以認為kafka是一種專用於高效能,低延遲,提交日誌儲存,複製,和傳播特殊用途的分散式檔案系統。

kafka的流處理

僅僅讀,寫和儲存是不夠的,kafka的目標是實時的流處理。

在kafka中,流處理持續獲取輸入topic的資料,進行處理加工,然後寫入輸出topic。例如,一個零售APP,接收銷售和出貨的輸入流,統計數量或調整價格後輸出。

可以直接使用producer和consumer API進行簡單的處理。對於複雜的轉換,Kafka提供了更強大的Streams API。可構建聚合計算或連線流到一起的複雜應用程式。

助於解決此類應用面臨的硬性問題:處理無序的資料,程式碼更改的再處理,執行狀態計算等。

Sterams API在Kafka中的核心:使用producer和consumer API作為輸入,利用Kafka做狀態儲存,使用相同的組機制在stream處理器例項之間進行容錯保障。

拼在一起

訊息傳遞,儲存和流處理的組合看似反常,但對於Kafka作為流式處理平臺的作用至關重要。

像HDFS這樣的分散式檔案系統允許儲存靜態檔案來進行批處理。這樣系統可以有效地儲存和處理來自過去的歷史資料。

傳統企業的訊息系統允許在你訂閱之後處理未來的訊息:在未來資料到達時處理它。

Kafka結合了這兩種能力,這種組合對於kafka作為流處理應用和流資料管道平臺是至關重要的。

批處理以及訊息驅動應用程式的流處理的概念:通過組合儲存和低延遲訂閱,流處理應用可以用相同的方式對待過去和未來的資料。它是一個單一的應用程式,它可以處理歷史的儲存資料,當它處理到最後一個訊息時,它進入等待未來的資料到達,而不是結束。

同樣,對於流資料管道(pipeline),訂閱實時事件的組合使得可以將Kafka用於非常低延遲的管道;但是,可靠地儲存資料的能力使得它可以將其用於必須保證傳遞的關鍵資料,或與僅定期載入資料或長時間維護的離線系統整合在一起。流處理可以在資料到達時轉換它。