女朋友看了也懂的Kafka(上篇)


@

前言:為什么需要Kafka

舉個例子:麥當勞點餐時,當我們選擇外帶的時候,餐廳制作好餐之后會放在一個取餐台,而且取餐台是按照不同的取餐碼尾號分開放置的,按照餐品的產出順序進行放置的。這時候我們可以在我們空閑的時候去取餐,而餐廳也不用等待我們拿完餐再生產。而這個取餐台就像一個消息隊列。我們現在想想如果沒有這個取餐台會發生什么?餐廳不斷需要顧客及時取走,不然會嚴重影響到餐廳的出餐和訂單處理。那消費者也要關注取餐的信息,自己的時間安排自由度就下降了。so,取餐台這個中間緩沖的對象就可以接觸消費者和餐廳的強綁定關系,讓餐廳和消費者都可以自由化做各自的事情。

Kafka所扮演的角色就是類似當前取餐台的功能,當然起作用不僅僅是緩沖,在接下來的內容中一起揭開kafka的面紗,一窺其工作機理和設計思想。

1.初識kafka

我們先來看看Kafka是怎么定義的?

kafka是一個分布式的基於發布/訂閱模式的消息隊列。

那啥是消息隊列啊。如我們開篇講到的那個取餐台就是一個消息隊列。就是在消息傳輸過程中保存消息的容器。其本質就是:

消息發送者(我們稱之為生產者,多形象)——>MQ(message queue消息隊列,消息保存的容器)——>消息接受者(消息的消費者)

消息隊列就是可以接受生產者發送的消息並保存起來,隊列Queue,按照消息接受的順序存儲,然后等待消費者進行消費消息。消息隊列的作用就是保存消息並轉發消息。

1.1 消息隊列的好處:

1)解耦

允許我們獨立的擴展或修改兩邊的處理過程,只要確保它們遵守同樣的接口約束。

2)可恢復性

系統的一部分組件失效時,不會影響到整個系統。消息隊列降低了進程間的耦合度,所以即使一個處理消息的進程掛掉,加入隊列中的消息仍然可以在系統恢復后被處理。

3)緩沖

有助於控制和優化數據流經過系統的速度,解決生產消息和消費消息的處理速度不一致的情況。

4)靈活性 & 峰值處理能力 (削峰)

在訪問量劇增的情況下,應用仍然需要繼續發揮作用,但是這樣的突發流量並不常見。如果為以能處理這類峰值訪問為標准來投入資源隨時待命無疑是巨大的浪費。使用消息隊列能夠使關鍵組件頂住突發的訪問壓力,而不會因為突發的超負荷的請求而完全崩潰。比如:618,雙十一等活動,00:00 大量的手速點擊訪問,如果沒有消息隊列作為緩沖,所有請求都打到Redis,mysql等服務器,他們也扛不住啊。

5)異步通信

很多時候,用戶不想也不需要立即處理消息。消息隊列提供了異步處理機制,允許用戶把一個消息放入隊列,但並不立即處理它。想向隊列中放入多少消息就放多少,然后在需要的時候再去處理它們。

1.2 消息隊列的兩種模式

(1)點對點模式(一對一,消費者主動拉取數據,消息收到后消息清除)

消息生產者生產消息發送到Queue中,然后消息消費者從Queue中取出並且消費消息。

消息被消費以后,queue中不再有存儲,所以消息消費者不可能消費到已經被消費的消息。Queue支持存在多個消費者,但是對一個消息而言,只會有一個消費者可以消費。

在這里插入圖片描述

2)發布/訂閱模式(一對多,消費者消費數據之后不會清除消息)

消息生產者(發布)將消息發布到topic中,同時有多個消息消費者(訂閱)消費該消息。和點對點方式不同,發布到topic的消息會被所有訂閱者消費。

發布-訂閱(Publish/Subscribe)模式(又被稱為觀察者模式,屬於行為型模式的一種,它定義了一種一對多的依賴關系,讓多個觀察者對象同時監聽某一個主題對象。這個主題對象在狀態變化時,會通知所有的觀察者對象,使他們能夠自動更新自己。

在這里插入圖片描述

我們看看傳統的MQ有什么問題?

沒有消息隊列我們怎么做?

假設現在我們的應用程序需要往別處發送監控信息,可以直接在應用程序和另一個可以在儀表盤上顯示度量指標的應用程序之間建立連接 然后通過這個連接推送度量指標,

我們可以這樣做:

在這里插入圖片描述

這是剛接觸監控系統時簡單問題的應對方案。過了不久,你需要分析更長時間片段的度量指標,而此時的儀表盤程序滿足不了需求,於是,你啟動了一個新的服務來接收度盤指標。該服務把度量指標保存起來,然后進行分析。與此同時,你修改了原來的應用程序, 把度量指標同時發送到兩個儀表盤系統上。

現在,你又多了3個可以生成度量指標 應用 程序,它們都與這兩個服務直接相連。而你的同事認為最好可以對這些服務進行輪詢以便 獲得告警功能,於是你為每一個應用程序增加了一個服務器,用於提供度量指標。再過一陣子,有更多的應用程序出於各自的目的,都從這些服務器獲取度主指標。這時的架構看起來就像下圖所示一樣,節點間的連接一團糟。

在這里插入圖片描述

傳統MQ怎么做?

我們創建一個基於發布訂閱的消息隊列, 用於接收來自其他應用程序的度量指標,井為其他系統提供了一個查詢服務器。

在這里插入圖片描述

這時候一切都看起來這么清爽和簡單,但是當我們和度量指標進行了一輪“艱苦奮戰”之后,其他同事也要和各自的任務進行battle。另一個同事也正在跟日志消息奮戰。還有另一個同事正在跟蹤網站用戶的行為,為負責機器學習開發的同事提供信息 ,同時為管理團隊生成報告。你和同事們使用相同的方式創建這些系統,解輯信息的發布者和訂閱者。然后發現世界好像又不美好了?看圖:

在這里插入圖片描述

由於不同的業務任務,我們產生了多個消息隊列進行各自業務的處理,但是這里有很多重復的地方。而且由於不同的業務模塊,開發人員需要為各自的業務指標任務維護一套內容,而且之后或許還有其他的業務需要構建新的消息隊列進行處理,資源浪費且每天維護這些內容,出現BUG的排查等等都會帶來極大的不便性。但是又因為傳統消息隊列中的一個消息只能被消費一次,這時候我們就想,如果消息隊列可以對於不同的業務的消費者看做不同的消費者,他們都可以消費消息隊列中的消息就可以共用這些消息系統了。豈不是美滋滋,即便是后邊需要增加業務,也不用獨立的使用新的消息隊列,世界又變得美好萬分。

這時候,Kafka就”閃亮登場“了

Kafka的數據按照一定的順序持久化保存,可以按需讀取,通過對於不同的群組的消費者重新數據的消費狀態實現多消費者共同消費消息等。具體的數據一致性保證以及生產者消費者寫入和讀取數據是怎么進行的,在后邊的內容會與展開講述。

2. Kafka基本架構

2.1 前備知識

1.消息和批次

Kafka 的數據單元被稱為消息。消息由字節數組組成,所以對於Kafka來說,消息里的數據沒有特別的格式或含義。消息可以有一個可選的元數據,也就是鍵。鍵也是一個字節數組,與消息一樣,對於Kafka來說也沒有特殊的含義。消息以一種可控的方式寫入不同的分區時,會用到鍵。最簡單的例子就是為鍵生成一個一致性散列值,然后使用散列值對主題分區數進行取模,為消息選取分區。

\[patitionnum = mod(hash(key) , partitions) \]

這樣可以保證具有相同鍵的消息總是被寫到相同的分區上。為了提高效率,消息被分批次寫入 Kafka 。批次就是一組消息,這些消息屬於同一個主題和分區。如果每 個消息都單獨在網絡傳輸,會導致大量的網絡開銷,把消息分成批次傳輸可以減少網絡開銷。不過,這要在時間延遲和吞吐量之間作出權衡:批次越大,單位時間內處理的消息就越多,單個消息的傳輸時間就越長。批次數據會被壓縮,這樣可以提升數據的傳輸和存儲能力,但要做更多的計算處理。

2.消息模式

對於Kafka而言,消息的底層是一組字節數組,是我們難以辨識的內容。為了更好的理解這些消息,就有開發者提出用額外的一種結構來定義消息內容。比如常見的JSON和XML。這些結構不僅易用,且可讀性好。Kafka一般采用Avro。Avro提供了一種緊湊的序列化格式,其模式和消息體是分開的。另外Avro也是由Doug Cutting創建的哦。因為Avro的一些特性,很適合Kafka這樣的消息隊列。消除了消息讀寫操作之間的耦合性。

如果讀寫操作緊密地耦合在一起,消息訂閱者需要升級應用程序才能同時處理新舊兩種數據格式。在消息訂閱者升級了之后,消息發布者才能跟着升級,以便使用新的數據格式。新的 應用程序如果需要使用數據,就要與消息發布者發生耦合,導致開發者需要做很多繁雜操作。

preview

在對於當前架構進行拆分看待前,我們先來關注一些Kafka獨到的機制和單元:
圖片引用來自知乎老劉

2.2 架構分析

1)Producer :消息生產者,就是向kafka broker發消息的客戶端

生產者創建消息。一般情況下,一個消息會被發布到一個特定的主題上。生產者在默認情況下把消息均衡地分布到主題的所有分區上,而並不關心特定消息會被寫到哪個分區。不過,在某些情況下,生產 者會把消息直接寫到指定的分區。這通常是通過消息鍵和分區器來實現的,分區器為鍵生 成一個散列值,並將其映射到指定的分區上。這樣可以保證包含同一個鍵的消息會被寫到 同一個分區上。生產者也可以使用自定義的分區器,根據不同的業務規則將消息映射到分區。

生產者具體的一些消息寫入細節會在下一個文章進行講述。畢竟一個篇幅如果太長,也不能做到詳盡,也怕小伙伴沒有時間看完。

2)Consumer :消息消費者,向kafka broker取消息的客戶端

消費者讀取消息。消費者訂閱一個或多個主題,並按照消息生成的順序讀取它們。消費者通過檢查消息的偏移量來區 分已經讀取過的消息。 偏移量是另一種元數據,它是一個不斷遞增的整數值,在創建消息時, Kafka 會把它添加到消息里。在給定的分區里,每個悄息的偏移量都是唯一的。消費者把每個分區最后讀取的悄息偏移量保存在 Zookeeper或Kafka 上,如果悄費者關閉或重啟,它的讀取狀態不會丟失。

消費者是消費者群組的一部分,也就是說,會有一個或多個消費者共同讀取一個主題。群組保證每個分區只能被一個消費者使用 。

在這里插入圖片描述

有3消費者同時讀取1個主題。其中的兩個消費者各自讀取一個分區,另外一個消費者讀取其他兩個分區。消費者與分區之間的映射通常被稱為消費者對分區的所有權關系。

通過這種方式,消費者可以消費包含大量消息的主題。而且,如果一個消費者失效,群組里的其他消費者可以接管失效消費者的工作。

3)Consumer Group (CG):消費者組,由多個consumer組成。消費者組內每個消費者負責消費不同分區的數據,一個分區只能由一個組內消費者消費;消費者組之間互不影響。所有的消費者都屬於某個消費者組,即消費者組是邏輯上的一個訂閱者。

消費者組,組中有多個消費者。

​ 組中消費者的個數最好 = topic分區數
​ 如果消費者組中消費者個數>topic分區數,此時有個別消費者沒有分區可以消費
​ 如果消費者組中消費者個數<topic分區數,此時有個別消費者需要消費多個分區的數據

**4)Broker **:一台kafka服務器就是一個broker。一個集群由多個broker組成。一個broker可以容納多個topic。

broker 接收來自生產者的消息,為消息設置偏移量,並提交消息到磁盤保存。 broker 為消費者提供服務,對讀取分區的請求作出響應,返 回已經提交到磁盤上的消息。根據特定的硬件及其性能特征,單個 broker 可以輕松處理數千個分區以及每秒百萬級的消息量。

broker 是集群的組成部分。每個集群都有一個 broker 同時充當了集群控制器的角色Collector(自動從集群的活躍成員中選舉出來)。控制器負責管理工作,包括將分區分配給 broker 和監控 broker。在集群中, 一個分區從屬於一個 broker, 該broker 被稱為分區的首領。一個分區可以分配給多個 broke ,這個時候會發生分區復制。這種復制機制為分區提供 了消息冗余,如果有一個 broker 失效,其他 broker 可以接管領導權。不過,相關的消費者和生產者都要重新連接到新的首領。

在這里插入圖片描述

分區復制

5)Topic :可以理解為一個隊列,生產者和消費者面向的都是一個topic

6)Partition:為了實現擴展性,一個非常大的topic可以分布到多個broker(即服務器)上,一個topic可以分為多個partition,每個partition是一個有序的隊列;

7)Replica:副本,為保證集群中的某個節點發生故障時,該節點上的partition數據不丟失,且kafka仍然能夠繼續工作,kafka提供了副本機制,一個topic的每個分區都有若干個副本,一個leader和若干個follower

8)leader:每個分區多個副本的“主”,生產者發送數據的對象,以及消費者消費數據的對象都是leader。

9)follower:每個分區多個副本中的“從”,實時從leader中同步數據,保持和leader數據的同步。leader發生故障時,某個follower會成為新的leader。

2.3Kafka 特點

1.多個生產者

Kafka 可以無縫地支持多個生產者,不管客戶端在使用單個主題還是多個主題。所以它很適合用來從多個前端系統收集數據,並以統 的格式對外提供數據。

2.多個消費者

Kafka 也支持多個消費者從一個單獨的消息流上讀取數據,而且消費者之間互不影響。這與其他隊列系統不同,其他隊列系統的消息一旦被一個客戶端讀 取,其他客戶端就無法再讀取它。另外,多個消費者可以組成一個群組,它們共享一個消息流,並保證整個群組對每個給定的消息只處理一次。

3.基於磁盤的數據存儲

Kafka 的數據 保留特性。消息被提交到磁盤,根據設置的保留規則進行保存。每個主題可以設置單獨的保留規則,以便滿足不同消費者的需求,各個主題可以保留不同數量的消息。消費者可能會因為處理速度慢或突發的流量高峰導致無陸及時讀取消息,而持久化數據可以保證數據 不會丟失。消費者可以在進行應用程序維護時離線一小段時間,而無需擔心消息丟失或堵塞在生產者端。消費者可以被關閉,但消息會繼續保留在 Kafka 里。消費者可以從上次中 斷的地方繼續處理消息。

4.伸縮性

為了能夠輕松處理大量數據, Kafka 一開始就被設計成一個具有靈活伸縮性的系統。用戶在開發階段可以先使用單個 broker ,再擴展到包含3個 broker 的小型開發集群,然后隨着數據量不斷增長,部署到生產環境的集群可能包含上百個 broker 。對在線集群進行擴展絲毫不影響整體系統的可用性。也就是說,一個包含多個 broker 的集群,即使個別Broker失效,仍然可以持續地為客戶提供服務。

5.高性能

前面提到的所有特性,讓 Kafka 成為了一個高性能的發布與訂閱消息系統。通過橫向擴展生產者、消費者和 broker, Kafka 可以輕松處理巨大的消息流。在處理大量數據的同時, 它還能保證亞秒級的消息延遲。

3 總結

我們通過麥當勞的例子開始進入消息隊列,並從點對點業務到發布訂閱的消息隊列以及他們存在的弊端引入Kafka。我們知道了Kafka是一個流平台,將數據看做是持續變化和不斷增長的流,可以通過發布和訂閱數據流,並把他們保存起來進行處理的數據系統。我們稱之為數據系統是因為kafka有別於消息系統的分布式部署方式,可以自由伸縮、處理企業內所有的應用程序。kafka不僅僅是傳遞消息,其還可以數據的可復制、持久化,其保留時長由我們來進行設置。

也了解了Kafka的基礎架構,Kafka的組成以及自個的作用和簡單做了什么事情。對於Kafka大致有一個比較簡單的了解,在下篇內容中我們將走入Kafka內部到底是做了什么。以及生產者消費者如何寫入和消費數據的,如何在寫入和消費的時候保證的數據一致性。解決節點失效以及內部的選舉機制。

我們要仰望星空,亦需腳踏實地。怕什么真理無窮,進一寸有一寸的歡喜。我是清風,希望這篇文章對你有幫助。如有不准確之處,還請評論區留言討論。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM