什麼是Kafka?它有四個關鍵概念值得我們去學習

2019-11-03     IT技術分享

1 kafka 是什麼

Apache kafka is a distributed streaming platform,即官方定義 kafka 是一個分布式流式計算平台 。而在大部分企業開發人員中,都是把 kafka 當成消息系統使用,即 它是一個分布式消息隊列,很少會使用 kafka 的流式計算。它有四個關鍵概念:

topic

kafka 把收到的消息按 topic 進行分類,因此可以理解為 topic 是一種類別

producer

往 kafka 發送消息的用戶

consumer

接收 kafka 消息的用戶

borker

kafka 集群可以由多個 kafka 實例組成,每個實例(server)稱為 broker

無論是 kafka broker 本身,還是 producer 或者 consumer,都依賴於 zookeeper 集群保存一些 meta 信息,保證系統可用性,以及使用 zookeeper 的選舉機制。

2 消息隊列實現原理

點對點模式

一對一, 消費者主動拉取數據,消息收到後消息清除 。點對點模式通常是一個基於拉取或輪詢的消息發送模型。此模型中,消費者從隊列主動拉取信息,而不是消息系統推送消息給消費者,並且, 消息只能被一個且只有一個消費者接收處理 ,即使有多個消息監聽者也是如此。

發布訂閱模式

一對多,數據生產後, 推送給所有訂閱者 。發布訂閱模型則是一個 基於推送的 消息傳送模型。發布訂閱模型可以有多種不同的訂閱者,臨時訂閱者只在主動監聽主題時才接收消息,而持久訂閱者則監聽主題的所有消息,即使當前訂閱者不可用,處於離線狀態。

3 消息隊列的作用

解耦

服務與服務之間不需要緊密結合,可以獨立擴展,只要確保它們遵守一致的數據結構定義。也可以作為一種異步的實現方式。

冗餘

消息隊列把數據持久化直到它明確被處理,通過這一方式規避了數據丟失的風險。許多消息隊列採用的「插入-獲取-刪除」範式中,在把一個消息從隊列中刪除之前,需要你的處理系統明確的指出該消息已經被處理完畢,從而確保你的數據被安全的保存直到你使用完畢。

擴展性

因為消息隊列解耦了你的處理過程,所以增大消息入隊和處理的頻率是很容易的,只要另外增加處理過程即可。

靈活性 & 峰值處理能力

在訪問量劇增的情況下,應用仍然需要繼續發揮作用,但是這樣的突發流量並不常見。如果為以能處理這類峰值訪問為標準來投入資源隨時待命無疑是巨大的浪費。使用消息隊列能夠使關鍵組件頂住突發的訪問壓力,而不會因為突發的超負荷的請求而完全崩潰

順序保證

在大多使用場景下,數據處理的順序都很重要。大部分消息隊列本來就是排序的,並且能保證數據會按照特定的順序來處理。(Kafka 保證一個 Partition 內的消息的有序性)

異步通信

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

4 kafka 架構

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

2)consumer:消息消費者,就是向 kafka broker 獲取消息的客戶端

3)topic:消息類別,也可以理解為一個隊列

4)consumer group(CG):這是 kafka 用來實現一個 topic 下的消息的 廣播語義 (發給所有的 consumer)和 單播語義 (發給任意一個 consumer)的手段。一個 topic 可以有多個 consumer group。topic 下的消息會複製給 consumer。**如果需要實現廣播,那麼只要每個 consumer 有一個獨立的 consumer group。要實現單播,只要所有的 consumer 在同一個 consumer group。**consumer group 還可以將 consumer 進行自由的分組,而不需要多次發送消息到不同的 topic。

5)broker:一台 kafka 伺服器就是一個 broker。一個集群由多個 broker 組成。一個broker 可以容納多個 topic。

6)partition:為了實現擴展性,一個非常大的 topic 可以分布到多個 broker(即伺服器)上,一個 topic 可以分為多個 partition,每個 partition 是一個有序的隊列。partition 中的每條消息都會被分配一個有序的 id(offset)。kafka 只保證按一個 partition 中的順序將消息發給 consumer,不保證一個 topic 的整體(多個partition間)的順序。

7)offset:kafka 的存儲文件都是按照 offset.kafka 來命名,用 offset 做名字的好處是方便查找。例如你想找位於 2049 的位置,只要找到 2048.kafk a的文件即可。當然t he first offset 就是00000000000.kafka。

5 分布式模型

Kafka 每個主題的多個分區日誌分布式地存儲在 Kafka 集群上,同時為了故障容錯,每個分區都會以副本的方式複製到多個消息代理節點上。其中一個節點會作為主副本(Leader),其他節點作為備份副本(Follower,也叫作從副本)。主副本會負責所有的客戶端讀寫操作,備份副本僅僅從主副本同步數據。當主副本出現故障時,備份副本中的一個副本會被選擇為新的主副本。 因為每個分區的副本中只有主副本接受讀寫,所以每個伺服器端都會作為某些分區的主副本,以及另外一些分區的備份副本,這樣 Kafka 集群的所有服務端整體上對客戶端是負載均衡的。

Kafka 的生產者和消費者相對於伺服器端而言都是客戶端。

Kafka 生產者客戶端發布消息到服務端的指定主題,會指定消息所屬的分區。生產者發布消息時根據消息是否有鍵,採用不同的分區策略。消息沒有鍵時,通過輪詢方式進行客戶端負載均衡;消息有鍵時,根據分區語義(例如 hash)確保相同鍵的消息總是發送到同一分區。

Kafka 的消費者通過訂閱主題來消費消息,並且每個消費者都會設置一個消費組名稱。因為生產者發布到主題的每一條消息都只會發送給消費者組的一個消費者。所以,如果要實現傳統消息系統的 「隊列」模型 ,可以讓每個消費者都擁有相同的消費組名稱,這樣消息就會負責均衡到所有的消費者;如果要實現 「發布-訂閱」模型 ,則每個消費者的消費者組名稱都不相同,這樣每條消息就會廣播給所有的消費者。

分區是消費者現場模型的最小並行單位。如下圖(圖1)所示,生產者發布消息到一台伺服器的3個分區時,只有一個消費者消費所有的3個分區。在下圖(圖2)中,3個分區分布在3台伺服器上,同時有3個消費者分別消費不同的分區。假設每個伺服器的吞吐量時300MB,在下圖(圖1)中分攤到每個分區只有100MB,而在下圖(圖2)中,集群整體的吞吐量有900MB。可以看到,增加伺服器節點會提升集群的性能,增加消費者數量會提升處理性能。

同一個消費組下多個消費者互相協調消費工作,Kafka 會將所有的分區平均地分配給所有的消費者實例,這樣每個消費者都可以分配到數量均等的分區。Kafka 的消費組管理協議會動態地維護消費組的成員列表,當一個新消費者加入消費者組,或者有消費者離開消費組,都會觸發再平衡操作。

Kafka 的消費者消費消息時,只保證在一個分區內的消息的完全有序性,並不保證同一個主題匯中多個分區的消息順序。而且,消費者讀取一個分區消息的順序和生產者寫入到這個分區的順序是一致的。比如,生產者寫入 「hello」 和 「Kafka」 兩條消息到分區 P1,則消費者讀取到的順序也一定是 「hello」 和 「Kafka」。如果業務上需要保證所有消息完全一致,只能通過設置一個分區完成,但這種做法的缺點是最多只能有一個消費者進行消費。一般來說,只需要保證每個分區的有序性,再對消息假設鍵來保證相同鍵的所有消息落入同一分區,就可以滿足絕大多數的應用。

end:如果你覺得本文對你有幫助的話,記得關注點贊轉發,你的支持就是我更新動力。

文章來源: https://twgreatdaily.com/zh-sg/DGeLRG4BMH2_cNUgzLp6.html