1. 程式人生 > >我的kafka學習之路

我的kafka學習之路

初識kafka

Kafka 從何而來?我們為什麼要開發 Kafka ? Kafka 到底是什麼?

Kafka 最初是 Linkedln 的一個內部基礎設施系統。我們發現,雖然有很多資料庫和系統可以用來儲存資料,但在我們的架構裡,剛好缺一個可以幫助處理持續資料流的元件。在開發 Kafka 之前,我們實驗了各種現成的解決方案,從訊息系統到日誌聚合系統,再到 ETL工具,它們都無陸搞足我們的需求。最後 ,我們決定從頭開發一個系統。我們不想只是開發一個能夠儲存資料的系統,比如傳統的關係型資料庫、鍵值儲存引擎、搜尋引擎或快取系統,我們希望能夠把資料看成是持續變化和不斷增長的流,井基於這樣的想主主構建出一個數據系統 。 事實上,是一個數據架構


 

kafka權威指南中寫到

我們認為 Kafka 是一個流平臺:在這個平臺上可以釋出和訂閱資料流,並把它們儲存起來、進行處理,這就是構建 Kafka 的初衷。以這種方式來看待資料確實與人們習慣的想陸有所不同,但它確實在構建應用和架構方面表現出了強大的抽象能力。 Kafka 經常會被拿來與現有的技術作比較:企業級訊息系統、大資料系統(如 Hadoop)和資料整合或 ETL工具。這裡的每一項比較都有一定的道理,但也有失偏頗。Kafka 有點像訊息系統,允許釋出和訂閱訊息流。從這點來看,它類似於 ActiveMQ 、RabbitMQ 或 IBM 的 MQSeries 等產品。儘管看上去有些相似,但 Kafka 與這些傳統的訊息系統仍然存在很多重要的不同點,這些差異使它完全不同於訊息系統。首先,作為一個現代的分散式系統, Kafka 以叢集的方式執行,可以自由伸縮,處理公司的所有應用程式。 Kafka 叢集並不是一組獨立執行的 broker,而是一個可以靈活伸縮的中心平臺,可以處理整個公司所有的資料流。其次, Kafka 可以按照你的要求儲存資料,儲存多久都可以 。作為資料連線層, Kafka 提供了資料傳遞保證 可複製、持久化,保留多長時間完全可以由你來決定。最後,流式處理將資料處理的層次提升到了新高度 。 訊息系統只會傳遞訊息,而 Kafka 的流式處理能力讓你只用很少的程式碼就能夠動態地處理派生流和資料集。Kafka 的這些獨到之處足以讓你刮目相看,它不只是“另一個訊息佇列” 。

(在正式討論Kafka之前,先來了解發布與訂閱訊息系統的概念,並認識這個系統的重要性。資料(訊息)的傳送者(釋出者)不會直接把訊息傳送給接收者,這是釋出與訂閱訊息系統的一個特點。釋出者以某種方式對訊息進行分類,接收者(訂閱者)訂閱它們,以便接收特定型別的訊息。釋出與訂閱系統一般會有一個 broker,也就是釋出訊息的中心點。)

Kafka 就是一款基於釋出與訂閱的梢息系統。它一般被稱為“分散式提交臼志”或者“分散式流平臺”。檔案系統或資料庫提交日誌用來提供所有事務的持久記錄 , 通過重放這些日誌可以重建系統的狀態。同樣地, Kafka 的資料是按照一定順序持久化儲存的,可以按需讀取 。 此外, Kafka 的資料分佈在整個系統裡,具備資料故障保護和效能伸縮能力。


訊息和批次

Kafka 的資料單元被稱為 訊息 。如果你在使用 Kafka 之前已經有資料庫使用經驗,那麼可以把訊息看成是資料庫裡的一個“資料行”或一條“記錄”。訊息由位元組陣列組成,所以對於 Kafka 來說,訊息裡的資料沒有特別的格式或含義。訊息可以有一個可選的元資料 ,也就是鍵。鍵也是一個位元組陣列,與訊息一樣,對於 Kafka 來說也沒有特殊的含義。 當訊息以一種可控的方式寫入不同的分割槽時,會用到鍵。最簡單的例子就是為鍵生成一個一致性雜湊值,然後使用雜湊值對主題分割槽數進行取模,為訊息選取分割槽。這樣可以保證具有相同鍵的訊息總是被寫到相同的分割槽上。
為了提高效率,訊息被分批次寫入 Kafka 。 批次就是一組訊息,這些訊息屬於同一個主題和分割槽。如果每一個訊息都單獨穿行於網路,會導致大量的網路開銷,把訊息分成批次傳輸可以減少網路開銷。不過,這要在時間延遲和吞吐量之間作出權衡:批次越大,單位時間內處理的訊息就越多,單個訊息的傳輸時間就越長。批次資料會被壓縮,這樣可以提升資料的傳輸和儲存能力,但要做更多的計算處理。

模式

對於 Kafka 來說,訊息不過是晦澀難懂的位元組陣列,所以有人建議用一些額外的結構來定義訊息內容,讓它們更易於理解。根據應用程式的需求, 訊息模式 ( schema)有許多可用的選項。像 JSON 和 XML 這些簡單的系統,不僅易用,而且可讀性好。不過,它們缺乏強型別處理能力,不同版本之間的相容性也不是很好。 Kafka 的許多開發者喜歡使用Apache Avro , 它最初是為 Hadoop 開發的一款序列化框架。 Avro 提供了一種緊湊的序列化格式,模式和訊息體是分開的,當模式發生變化時,不需要重新生成程式碼 ; 它還支援強型別和模式進化,其版本既向前相容, 也向後相容。資料格式的一致性對於 Kafka 來說很重要,它消除了訊息讀寫操作之間的輯合性。 如果讀寫操作緊密地桐合在一起,訊息訂閱者需要升級應用程式才能同時處理新舊兩種資料格式。在訊息訂閱者升級了之後,訊息釋出者才能跟著升級,以便使用新的資料格式。新的應用程式如果需要使用資料,就要與訊息釋出者發生耦合,導致開發者需要做很多繁雜的工作。

所以,定義良好的模式,並把它們存放在公共倉庫,可以方便我們理解 Kafka 的訊息結構。

主題和分割槽

Kaflca 的訊息通過主題進行分類。主題就好比資料庫的表,或者檔案系統裡的資料夾。主題可以被分為若干個分割槽 , 一個分割槽就是一個提交日誌。訊息以追加的方式寫入分割槽,然後以先入先出的順序讀取(佇列)。要注意,由於一個主題一般包含幾個分割槽,因此無法在整個主題範圍內保證訊息的順序,但可以保證訊息在單個分割槽內的順序。 Kafka 通過分割槽來實現資料冗餘和伸縮性。分割槽可以分佈在不同的伺服器上,也就是說, 一個主題可以橫跨多個伺服器,以此來提供比單個伺服器更強大的效能。
我們通常會使用流這個詞來描述 Kafka 這類系統的資料。很多時候 , 人們把一個主題的資料看成一個流,不管它有多少個分割槽。流是一組從生產者移動到消費者的資料。當我們討論流式處理時,一般都是這樣描述訊息的。 kafka Streams 、 Apache Samza 和 Storm 這些框架以實時的方式處理訊息,也就是所謂的流式處理。我們可以將流式處理與離線處理進行比較,比如 Hadoop 就是被設計用於在稍後某個時刻處理大量的資料。

生產者和消費者

Kafka 的客戶端就是 Kafka 系統的使用者,它們被分為兩種基本型別 : 生產者和消費者。除此之外,還有其他高階客戶端 API-←用於資料整合的 Kafka Connect API 和用於流式處理的 Kafka Streams。這些高階客戶端 API 使用生產者和消費者作為內部元件,提供了高階的功能。
生產者建立訊息。在其他釋出與訂閱系統中,生產者可能被稱為釋出者或寫入者。一般情況下,一個訊息會被髮布到一個特定的主題上。生產者在預設情況下把訊息均衡地分佈到主題的所有分割槽上,而並不關心特定訊息會被寫到哪個分割槽。不過,在某些情況下,生產者會把訊息直接寫到指定的分割槽。這通常是通過訊息鍵和分割槽器來實現的,分割槽器為鍵生成一個雜湊值,並將其對映到指定的分割槽上。這樣可以保證包含同一個鍵的訊息會被寫到同一個分割槽上。生產者也可以使用自定義的分割槽器,根據不同的業務規則將訊息對映到分割槽。
消費者讀取訊息。在其他釋出與訂閱系統中,消費者可能被稱為訂閱者或讀者。 消費者訂閱一個或多個主題,並按照訊息生成的順序讀取它們。消費者通過檢查訊息的偏移盤來區分已經讀取過的訊息。 偏移量是另一種元資料,它是一個不斷遞增的整數值,在建立訊息時, Kafka 會把它新增到訊息裡。在給定的分割槽裡,每個悄息的偏移量都是唯一的。消費者把每個分割槽最後讀取的悄息偏移量儲存在 Zookeeper 或 Kafka 上,如果悄費者關閉或重啟,它的讀取狀態不會丟失。消費者是消費者群組的一部分,也就是說,會有一個或多個消費者共同讀取一個主題 。 群組保證每個分割槽只能被一個消費者使用 。下圖 所示的群組中,有 3 個消費者同時讀取一個主題。其中的兩個消費者各自讀取一個分割槽,另外一個消費者讀取其他兩個分割槽。消費者與分割槽之間的對映通常被稱為悄費者對分割槽的所有權關係 。通過這種方式,消費者可以消費包含大量訊息的主題。而且,如果一個消費者失效,群組
裡的其他消費者可以接管失效消費者的工作。

 broker和叢集

一個獨立的 Kafka 伺服器被稱為 broker。 broker 接收來自 生產者的訊息,為訊息設定偏移量,並提交訊息到磁碟儲存。 broker 為消費者提供服務,對讀取分割槽的請求作出響應,返回已經提交到磁碟上的訊息。根據特定的硬體及其效能特徵,單個 broker 可以輕鬆處理數千個分割槽以及每秒百萬級的訊息量。
broker 是叢集的組成部分。每個叢集都有一個 broker 同時充當了叢集控制器的角色(自動從叢集的活躍成員中選舉出來)。控制器負責管理工作,包括將分割槽分配給broker和監控broker。在叢集中,一個分割槽從屬於一個 broker, 該 broker 被稱為分割槽的首領 。一個分割槽可以分配給多個 broker,這個時候會發生分割槽複製(見下圖)。這種複製機制為分割槽提供了訊息冗餘,如果有一個 broker 失效,其他 broker 可以接管領導權。不過,相關的消費者和生產者都要重新連線到新的首領。

 多叢集

隨著 Kafka 部署數量的增加,基於以下幾點原因,最好使用多個叢集。
1.資料型別分離
2.安全需求隔離
3.多資料中心(災難恢復)

如果使用多個數據中心,就需要在它們之間複製訊息。這樣,線上應用程式才可以訪問到多個站點的使用者活動資訊。例如,如果一個使用者修改了他們的資料資訊,不管從哪個資料中心都應該能看到這些改動。或者多個站點的監控資料可以被聚集到一個部署了分析程式和告警系統的中心位置。不過, Kafka 的訊息複製機制只能在單個叢集裡進行,不能在多個叢集之間進行。
Kafka 提供了一個叫作 MirrorMaker 的工具,可以用它來實現叢集間的訊息複製。MirrorMaker 的核心元件包含了一個生產者和一個消費者,兩者之間通過一個佇列相連。消費者從一個叢集讀取訊息,生產者把訊息傳送到另一個叢集上。圖 1-8 展示了一個使
用 MirrorMaker 的例子,兩個“本地”叢集的訊息被聚集到一個“聚合”叢集上,然後將該叢集複製到其他資料中心。不過,這種方式在建立複雜的資料管道方面顯得有點力不從心。
多資料中心架構圖如下