溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

怎樣進(jìn)行Kafka的工作原理

發(fā)布時間:2021-12-03 10:51:23 來源:億速云 閱讀:111 作者:柒染 欄目:互聯(lián)網(wǎng)科技

今天就跟大家聊聊有關(guān)怎樣進(jìn)行Kafka的工作原理,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

為什么需要消息隊列

回到正題,如果沒有小芳便利店,那快遞小哥和我的交互圖就應(yīng):

怎樣進(jìn)行Kafka的工作原理

會出現(xiàn)什么情況呢?

  • 為了這個女朋友,我請假回去拿(老板不批)。

  • 小哥一直在你樓下等(小哥還有其他的快遞要送)。

  • 周末再送(顯然等不及)。

  • 這個女朋友我不要了(絕對不可能)!

小芳便利店出現(xiàn)后,交互圖如下:

怎樣進(jìn)行Kafka的工作原理

在上面例子中,“快遞小哥”和“買女朋友的我”就是需要交互的兩個系統(tǒng),小芳便利店就是我們本文要講的消息中間件。

總結(jié)下來小芳便利店(消息中間件)出現(xiàn)后有如下好處:

解耦

快遞小哥手上有很多快遞需要送,他每次都需要先電話一一確認(rèn)收貨人是否有空、哪個時間段有空,然后再確定好送貨的方案。這樣完全依賴收貨人了!如果快遞一多,快遞小哥估計得忙瘋了……

如果有了便利店,快遞小哥只需要將同一個小區(qū)的快遞放在同一個便利店,然后通知收貨人來取貨就可以了,這時候快遞小哥和收貨人就實現(xiàn)了解耦!

異步

快遞小哥打電話給我后需要一直在你樓下等著,直到我拿走你的快遞他才能去送其他人的。

快遞小哥將快遞放在小芳便利店后,又可以干其他的活兒去了,不需要等待你到來而一直處于等待狀態(tài),提高了工作的效率。

削峰

假設(shè)雙十一我買了不同店里的各種商品,而恰巧這些店發(fā)貨的快遞都不一樣,有中通、圓通、申通、各種通等……更巧的是他們都同時到貨了!

中通的小哥打來電話叫我去北門取快遞、圓通小哥叫我去南門、申通小哥叫我去東門。我一時手忙腳亂……

我們能看到在系統(tǒng)需要交互的場景中,使用消息隊列中間件真的是好處多多,基于這種思路,就有了豐巢、菜鳥驛站等比小芳便利店更專業(yè)的“中間件”了。

***,上面的故事純屬虛構(gòu)……

消息隊列通信的模式

通過上面的例子我們引出了消息中間件,并且介紹了消息隊列出現(xiàn)后的好處,這里就需要介紹消息隊列通信的兩種模式了:

點對點模式

怎樣進(jìn)行Kafka的工作原理

如上圖所示,點對點模式通常是基于拉取或者輪詢的消息傳送模型,這個模型的特點是發(fā)送到隊列的消息被一個且只有一個消費者進(jìn)行處理。

生產(chǎn)者將消息放入消息隊列后,由消費者主動的去拉取消息進(jìn)行消費。點對點模型的優(yōu)點是消費者拉取消息的頻率可以由自己控制。

但是消息隊列是否有消息需要消費,在消費者端無法感知,所以在消費者端需要額外的線程去監(jiān)控。

發(fā)布訂閱模式

怎樣進(jìn)行Kafka的工作原理

如上圖所示,發(fā)布訂閱模式是一個基于消息送的消息傳送模型,該模型可以有多種不同的訂閱者。

生產(chǎn)者將消息放入消息隊列后,隊列會將消息推送給訂閱過該類消息的消費者(類似微信公眾號)。

由于是消費者被動接收推送,所以無需感知消息隊列是否有待消費的消息!但是 Consumer1、Consumer2、Consumer3  由于機(jī)器性能不一樣,所以處理消息的能力也會不一樣,但消息隊列卻無法感知消費者消費的速度!

所以推送的速度成了發(fā)布訂閱模式的一個問題!假設(shè)三個消費者處理速度分別是 8M/s、5M/s、2M/s,如果隊列推送的速度為 5M/s,則  Consumer3 無法承受!

如果隊列推送的速度為 2M/s,則 Consumer1、Consumer2 會出現(xiàn)資源的極大浪費!

Kafka

上面簡單的介紹了為什么需要消息隊列以及消息隊列通信的兩種模式,接下來就到了我們本文的主角 Kafka 閃亮登場的時候了!

Kafka  是一種高吞吐量的分布式發(fā)布訂閱消息系統(tǒng),它可以處理消費者規(guī)模的網(wǎng)站中的所有動作流數(shù)據(jù),具有高性能、持久化、多副本備份、橫向擴(kuò)展能力………

基礎(chǔ)架構(gòu)及術(shù)語

話不多說,先看圖,通過這張圖我們來捋一捋相關(guān)的概念及之間的關(guān)系:

怎樣進(jìn)行Kafka的工作原理

如果看到這張圖你很懵逼,木有關(guān)系!我們先來分析相關(guān)概念:

  • Producer:Producer 即生產(chǎn)者,消息的產(chǎn)生者,是消息的入口。

  • Kafka Cluster:

Broker:Broker 是 Kafka 實例,每個服務(wù)器上有一個或多個 Kafka 的實例,我們姑且認(rèn)為每個 Broker 對應(yīng)一臺服務(wù)器。

每個 Kafka 集群內(nèi)的 Broker 都有一個不重復(fù)的編號,如圖中的 Broker-0、Broker-1 等……

Topic:消息的主題,可以理解為消息的分類,Kafka 的數(shù)據(jù)就保存在 Topic。在每個 Broker 上都可以創(chuàng)建多個 Topic。

Partition:Topic 的分區(qū),每個 Topic 可以有多個分區(qū),分區(qū)的作用是做負(fù)載,提高 Kafka 的吞吐量。

同一個 Topic 在不同的分區(qū)的數(shù)據(jù)是不重復(fù)的,Partition 的表現(xiàn)形式就是一個一個的文件夾!

Replication:每一個分區(qū)都有多個副本,副本的作用是做備胎。當(dāng)主分區(qū)(Leader)故障的時候會選擇一個備胎(Follower)上位,成為  Leader。

在 Kafka 中默認(rèn)副本的***數(shù)量是 10 個,且副本的數(shù)量不能大于 Broker 的數(shù)量,F(xiàn)ollower 和 Leader  絕對是在不同的機(jī)器,同一機(jī)器對同一個分區(qū)也只可能存放一個副本(包括自己)。

  • Message:每一條發(fā)送的消息主體。

  • Consumer:消費者,即消息的消費方,是消息的出口。

  • Consumer Group:我們可以將多個消費組組成一個消費者組,在 Kafka 的設(shè)計中同一個分區(qū)的數(shù)據(jù)只能被消費者組中的某一個消費者消費。

同一個消費者組的消費者可以消費同一個 Topic 的不同分區(qū)的數(shù)據(jù),這也是為了提高 Kafka 的吞吐量!

  • Zookeeper:Kafka 集群依賴 Zookeeper 來保存集群的的元信息,來保證系統(tǒng)的可用性。

工作流程分析

上面介紹了 Kafka 的基礎(chǔ)架構(gòu)及基本概念,不知道大家看完有沒有對 Kafka 有個大致印象,如果還比較懵也沒關(guān)系!

我們接下來再結(jié)合上面的結(jié)構(gòu)圖分析 Kafka 的工作流程,***再回來整個梳理一遍我相信你會更有收獲!

發(fā)送數(shù)據(jù)

我們看上面的架構(gòu)圖中,Producer 就是生產(chǎn)者,是數(shù)據(jù)的入口。注意看圖中的紅色箭頭,Producer 在寫入數(shù)據(jù)的時候永遠(yuǎn)在找  Leader,不會直接將數(shù)據(jù)寫入 Follower!

那 Leader 怎么找呢?寫入的流程又是什么樣的呢?我們看下圖:

怎樣進(jìn)行Kafka的工作原理

發(fā)送的流程就在圖中已經(jīng)說明了,就不單獨在文字列出來了!需要注意的一點是,消息寫入 Leader 后,F(xiàn)ollower 是主動的去 Leader  進(jìn)行同步的!

Producer 采用 Push 模式將數(shù)據(jù)發(fā)布到 Broker,每條消息追加到分區(qū)中,順序?qū)懭氪疟P,所以保證同一分區(qū)內(nèi)的數(shù)據(jù)是有序的!

寫入示意圖如下:

怎樣進(jìn)行Kafka的工作原理

上面說到數(shù)據(jù)會寫入到不同的分區(qū),那 Kafka 為什么要做分區(qū)呢?相信大家應(yīng)該也能猜到,分區(qū)的主要目的是:

  • 方便擴(kuò)展。因為一個 Topic 可以有多個 Partition,所以我們可以通過擴(kuò)展機(jī)器去輕松的應(yīng)對日益增長的數(shù)據(jù)量。

  • 提高并發(fā)。以 Partition 為讀寫單位,可以多個消費者同時消費數(shù)據(jù),提高了消息的處理效率。

熟悉負(fù)載均衡的朋友應(yīng)該知道,當(dāng)我們向某個服務(wù)器發(fā)送請求的時候,服務(wù)端可能會對請求做一個負(fù)載,將流量分發(fā)到不同的服務(wù)器。

那在 Kafka 中,如果某個 Topic 有多個 Partition,Producer 又怎么知道該將數(shù)據(jù)發(fā)往哪個 Partition 呢?

Kafka 中有幾個原則:

  • Partition 在寫入的時候可以指定需要寫入的 Partition,如果有指定,則寫入對應(yīng)的 Partition。

  • 如果沒有指定 Partition,但是設(shè)置了數(shù)據(jù)的 Key,則會根據(jù) Key 的值 Hash 出一個 Partition。

  • 如果既沒指定 Partition,又沒有設(shè)置 Key,則會輪詢選出一個 Partition。

保證消息不丟失是一個消息隊列中間件的基本保證,那 Producer 在向 Kafka 寫入消息的時候,怎么保證消息不丟失呢?

其實上面的寫入流程圖中有描述出來,那就是通過 ACK 應(yīng)答機(jī)制!在生產(chǎn)者向隊列寫入數(shù)據(jù)的時候可以設(shè)置參數(shù)來確定是否確認(rèn) Kafka  接收到數(shù)據(jù),這個參數(shù)可設(shè)置的值為 0、1、all:

  • 0 代表 Producer 往集群發(fā)送數(shù)據(jù)不需要等到集群的返回,不確保消息發(fā)送成功。安全性***但是效率***。

  • 1 代表 Producer 往集群發(fā)送數(shù)據(jù)只要 Leader 應(yīng)答就可以發(fā)送下一條,只確保 Leader 發(fā)送成功。

  • all 代表 Producer 往集群發(fā)送數(shù)據(jù)需要所有的 Follower 都完成從 Leader 的同步才會發(fā)送下一條,確保 Leader  發(fā)送成功和所有的副本都完成備份。安全性***,但是效率***。

***要注意的是,如果往不存在的 Topic 寫數(shù)據(jù),能不能寫入成功呢?Kafka 會自動創(chuàng)建 Topic,分區(qū)和副本的數(shù)量根據(jù)默認(rèn)配置都是 1。

保存數(shù)據(jù)

Producer 將數(shù)據(jù)寫入 Kafka 后,集群就需要對數(shù)據(jù)進(jìn)行保存了!Kafka  將數(shù)據(jù)保存在磁盤,可能在我們的一般的認(rèn)知里,寫入磁盤是比較耗時的操作,不適合這種高并發(fā)的組件。

Kafka 初始會單獨開辟一塊磁盤空間,順序?qū)懭霐?shù)據(jù)(效率比隨機(jī)寫入高)。

①Partition 結(jié)構(gòu)

前面說過了每個 Topic 都可以分為一個或多個 Partition,如果你覺得 Topic 比較抽象,那 Partition  就是比較具體的東西了!

Partition 在服務(wù)器上的表現(xiàn)形式就是一個一個的文件夾,每個 Partition 的文件夾下面會有多組 Segment 文件。

每組 Segment 文件又包含 .index 文件、.log 文件、.timeindex 文件(早期版本中沒有)三個文件。

Log 文件就是實際存儲 Message 的地方,而 Index 和 Timeindex 文件為索引文件,用于檢索消息。

怎樣進(jìn)行Kafka的工作原理

如上圖,這個 Partition 有三組 Segment 文件,每個 Log 文件的大小是一樣的,但是存儲的 Message 數(shù)量是不一定相等的(每條的  Message 大小不一致)。

文件的命名是以該 Segment 最小 Offset 來命名的,如 000.index 存儲 Offset 為 0~368795 的消息,Kafka  就是利用分段+索引的方式來解決查找效率的問題。

②Message 結(jié)構(gòu)

上面說到 Log 文件就實際是存儲 Message 的地方,我們在 Producer 往 Kafka 寫入的也是一條一條的 Message。

那存儲在 Log 中的 Message 是什么樣子的呢?消息主要包含消息體、消息大小、Offset、壓縮類型……等等!

我們重點需要知道的是下面三個:

  • Offset:Offset 是一個占 8byte 的有序 id 號,它可以唯一確定每條消息在 Parition 內(nèi)的位置!

  • 消息大?。合⒋笮≌加?4byte,用于描述消息的大小。

  • 消息體:消息體存放的是實際的消息數(shù)據(jù)(被壓縮過),占用的空間根據(jù)具體的消息而不一樣。

③存儲策略

無論消息是否被消費,Kafka 都會保存所有的消息。那對于舊數(shù)據(jù)有什么刪除策略呢?

  • 基于時間,默認(rèn)配置是 168 小時(7 天)。

  • 基于大小,默認(rèn)配置是 1073741824。

需要注意的是,Kafka 讀取特定消息的時間復(fù)雜度是 O(1),所以這里刪除過期的文件并不會提高 Kafka 的性能!

消費數(shù)據(jù)

消息存儲在 Log 文件后,消費者就可以進(jìn)行消費了。在講消息隊列通信的兩種模式的時候講到過點對點模式和發(fā)布訂閱模式。

Kafka 采用的是點對點的模式,消費者主動的去 Kafka 集群拉取消息,與 Producer 相同的是,消費者在拉取消息的時候也是找 Leader  去拉取。

多個消費者可以組成一個消費者組(Consumer Group),每個消費者組都有一個組 id!

同一個消費組者的消費者可以消費同一 Topic 下不同分區(qū)的數(shù)據(jù),但是不會組內(nèi)多個消費者消費同一分區(qū)的數(shù)據(jù)!

是不是有點繞?我們看下圖:

怎樣進(jìn)行Kafka的工作原理

圖示是消費者組內(nèi)的消費者小于 Partition 數(shù)量的情況,所以會出現(xiàn)某個消費者消費多個 Partition 數(shù)據(jù)的情況,消費的速度也就不及只處理一個  Partition 的消費者的處理速度!

如果是消費者組的消費者多于 Partition 的數(shù)量,那會不會出現(xiàn)多個消費者消費同一個 Partition 的數(shù)據(jù)呢?

上面已經(jīng)提到過不會出現(xiàn)這種情況!多出來的消費者不消費任何 Partition 的數(shù)據(jù)。

所以在實際的應(yīng)用中,建議消費者組的 Consumer 的數(shù)量與 Partition 的數(shù)量一致!

在保存數(shù)據(jù)的小節(jié)里面,我們聊到了 Partition 劃分為多組 Segment,每個 Segment 又包含  .log、.index、.timeindex 文件,存放的每條 Message 包含 Offset、消息大小、消息體……

我們多次提到 Segment 和 Offset,查找消息的時候是怎么利用 Segment+Offset 配合查找的呢?

假如現(xiàn)在需要查找一個 Offset 為 368801 的 Message 是什么樣的過程呢?我們先看看下面的圖:

怎樣進(jìn)行Kafka的工作原理

①先找到 Offset 的 368801message 所在的 Segment 文件(利用二分法查找),這里找到的就是在第二個 Segment  文件。

②打開找到的 Segment 中的 .index 文件(也就是 368796.index 文件,該文件起始偏移量為 368796+1。

我們要查找的 Offset 為 368801 的 Message 在該 Index 內(nèi)的偏移量為 368796+5=368801,所以這里要查找的相對  Offset 為 5)。

由于該文件采用的是稀疏索引的方式存儲著相對 Offset 及對應(yīng) Message 物理偏移量的關(guān)系,所以直接找相對 Offset 為 5  的索引找不到。

這里同樣利用二分法查找相對 Offset 小于或者等于指定的相對 Offset 的索引條目中***的那個相對 Offset,所以找到的是相對 Offset  為 4 的這個索引。

③根據(jù)找到的相對 Offset 為 4 的索引確定 Message 存儲的物理偏移位置為 256。

打開數(shù)據(jù)文件,從位置為 256 的那個地方開始順序掃描直到找到 Offset 為 368801 的那條 Message。

這套機(jī)制是建立在 Offset 為有序的基礎(chǔ)上,利用 Segment+有序 Offset+稀疏索引+二分查找+順序查找等多種手段來高效的查找數(shù)據(jù)!

至此,消費者就能拿到需要處理的數(shù)據(jù)進(jìn)行處理了。

看完上述內(nèi)容,你們對怎樣進(jìn)行Kafka的工作原理有進(jìn)一步的了解嗎?如果還想了解更多知識或者相關(guān)內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道,感謝大家的支持。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI