您當前的位置:首頁 > 書法

《面試八股文》之kafka21卷

作者:由 moon聊技術 發表于 書法時間:2021-07-09

微信公眾號:

moon聊技術

關注選擇“

星標

”, 重磅乾貨,第一 時間送達!

[如果你覺得文章對你有幫助,歡迎

關注,在看,點贊,轉發

《面試八股文》之kafka21卷

大家好,我是moon,最新一篇面試八股文系列 kafka 篇也出爐了,大家還不捲起來嗎?

其他《面試八股文》系列文章

1。什麼是訊息中介軟體?

2。kafka 是什麼?有什麼作用?

3。kafka 的架構是怎麼樣的?

4。Kafka Replicas是怎麼管理的?

5。如何確定當前能讀到哪一條訊息?

6。生產者傳送訊息有哪些模式?

7。傳送訊息的分割槽策略有哪些?

8。Kafka 支援讀寫分離嗎?為什麼?

9。那 Kafka 是怎麼去實現負載均衡的?

10。Kafka 的負責均衡會有什麼問題呢?

11。Kafka 的可靠性是怎麼保證的?

12。Kafka 的訊息消費方式有哪些?

13。分割槽再分配是做什麼的?解決了什麼問題?

14。副本 leader 是怎麼選舉的?

15。分割槽數越多越好嗎?吞吐量就會越高嗎?

16。如何增強消費者的消費能力?

17。消費者與 topic 的分割槽分配策略有哪些?

18。kafka 控制器是什麼?有什麼作用

19。kafka 控制器是怎麼進行選舉的?

20。kafka 為什麼這麼快?

21。什麼情況下 kafka 會丟失訊息?

1.什麼是訊息中介軟體?

訊息中介軟體是基於佇列與訊息傳遞技術,在網路環境中為應用系統提供

同步或非同步、可靠的

訊息傳輸的支撐性軟體系統。

訊息中介軟體利用

高效可靠

的訊息傳遞機制進行平臺無關的資料交流,並基於資料通訊來進行分散式系統的整合。透過提供訊息傳遞和訊息排隊模型,它可以在分散式環境下擴充套件程序間的通訊。

2.kafka 是什麼?有什麼作用?

Kafka 是一個分散式的流式處理平臺,它以高吞吐、可持久化、可水平擴充套件、支援流資料處理等多種特性而被廣泛使用

《面試八股文》之kafka21卷

主要功能體現於三點:

訊息系統

:kafka與傳統的訊息中介軟體都具備

系統解耦、冗餘儲存、流量削峰、緩衝、非同步通訊、擴充套件性、可恢復性

等功能。與此同時,kafka還提供了大多數訊息系統難以實現的訊息順序性保障及回溯性消費的功能。

儲存系統

:kafka把

訊息持久化到磁碟

,相比於其他基於記憶體儲存的系統而言,有效的降低了訊息丟失的風險。這得益於其訊息持久化和多副本機制。也可以將kafka作為長期的儲存系統來使用,只需要把對應的資料保留策略設定為“永久”或啟用主題日誌壓縮功能。

流式處理平臺

:kafka為流行的流式處理框架提供了可靠的資料來源,還提供了一個完整的流式處理框架,比如視窗、連線、變換和聚合等各類操作。

3.kafka 的架構是怎麼樣的?

《面試八股文》之kafka21卷

一個典型的 kafka 體系架構包括若干

Producer

、若干

Consumer

、以及一個

Zookeeper

叢集(在2。8。0版本中移,除了 Zookeeper,透過

KRaft

進行自己的叢集管理)

Producer 將訊息傳送到 Broker,Broker 負責將受到的訊息儲存到磁碟中,而 Consumer 負責從 Broker 訂閱並消費訊息。

Kafka 基本概念:

Producer

:生產者,負責將訊息傳送到 Broker

Consumer

:消費者,從 Broker 接收訊息

Consumer Group

:消費者組,由

多個 Consumer 組成

。消費者組內每個消費者負責消費不同分割槽的資料,

一個分割槽只能由一個組內消費者消費

;消費者組之間互不影響。所有的消費者都屬於某個消費者組,即消費者組是邏輯上的一個訂閱者。

Broker

:可以看做一個獨立的

Kafka 服務節點或 Kafka 服務例項

。如果一臺伺服器上只部署了一個 Kafka 例項,那麼我們也可以將 Broker 看做一臺 Kafka 伺服器。

Topic

:一個邏輯上的概念,包含很多 Partition,

同一個 Topic 下的 Partiton 的訊息內容是不相同的

Partition

:為了實現擴充套件性,一個非常大的 topic

可以分佈到多個 broker 上,一個 topic 可以分為多個 partition

,每個 partition 是一個有序的佇列。

Replica

:副本,

同一分割槽的不同副本儲存的是相同的訊息

,為保證叢集中的某個節點發生故障時,該節點上的 partition 資料不丟失,且 kafka 仍然能夠繼續工作,kafka 提供了副本機制,一個 topic 的每個分割槽都有若干個副本,一個 leader 和若干個 follower。

Leader

:每個分割槽的多個副本中的“主副本”,

生產者以及消費者只與 Leader 互動

Follower

:每個分割槽的多個副本中的“從副本”,

負責實時從 Leader 中同步資料,保持和 Leader 資料的同步

。Leader 發生故障時,從 Follower 副本中重新選舉新的 Leader 副本對外提供服務。

4.Kafka Replicas是怎麼管理的?

《面試八股文》之kafka21卷

AR:分割槽中的

所有 Replica 統稱為 AR

ISR:所有與 Leader 副本

保持一定程度同步

的Replica(包括 Leader 副本在內)組成 ISR

OSR:與 Leader 副本

同步滯後過多的

Replica 組成了 OSR

Leader 負責維護和跟蹤 ISR 集合中所有 Follower 副本的滯後狀態,當 Follower 副本落後過多時,就會將其放入 OSR 集合,當 Follower 副本追上了 Leader 的進度時,就會將其放入 ISR 集合。

預設情況下,

只有 ISR 中的副本才有資格晉升為 Leader

5.如何確定當前能讀到哪一條訊息?

分割槽相當於一個日誌檔案,我們先簡單介紹幾個概念

《面試八股文》之kafka21卷

如上圖是一個分割槽日誌檔案

標識

共有7條訊息

,offset (訊息偏移量)分別是0~6

0 代表這個日誌檔案的

開始

HW(High Watermark) 為4,0~3 代表這個日誌檔案

可以消費的區間

,消費者只能消費到這四條訊息

LEO 代表即將要寫入訊息的偏移量 offset

分割槽 ISR 集合中的每個副本都會維護自己的 LEO,而 ISR 集合中最小的LEO 即為分割槽的 HW

《面試八股文》之kafka21卷

如上圖: 三個分割槽副本都是 ISR集合當中的,最小的 LEO 為 3,就代表分割槽的 HW 為3,所以當前分割槽只能消費到 0~2 之間的三條資料,如下圖

《面試八股文》之kafka21卷

6.生產者傳送訊息有哪些模式?

總共有三種模式

1。

發後即忘

(fire-and-forget)

它只管往 Kafka 裡面傳送訊息,但是

不關心訊息是否正確到達

,這種方式的效率最高,但是可靠性也最差,比如當發生某些不可充實異常的時候會造成訊息的丟失

2。

同步

(sync)

producer。send()返回一個Future物件,呼叫get()方法變回進行同步等待,就知道訊息是否傳送成功,

傳送一條訊息需要等上個訊息傳送成功後才可以繼續傳送

3。

非同步

(async)

Kafka支援 producer。send() 傳入一個回撥函式,訊息不管成功或者失敗都會呼叫這個回撥函式,這樣就算是非同步傳送,我們也知道訊息的傳送情況,然後再回調函式中選擇記錄日誌還是重試都取決於呼叫方

7.傳送訊息的分割槽策略有哪些?

《面試八股文》之kafka21卷

1。輪詢:

依次

將訊息傳送該topic下的所有分割槽,如果在建立訊息的時候 key 為 null,Kafka 預設採用這種策略。

2。key 指定分割槽:在建立訊息是 key 不為空,並且使用預設分割槽器,Kafka 會將 key 進行 hash,然後

根據hash值對映到指定的分割槽上

。這樣的好處是 key 相同的訊息會在一個分割槽下,Kafka 並不能保證全域性有序,但是在每個分割槽下的訊息是有序的,按照順序儲存,按照順序消費。在保證同一個 key 的訊息是有序的,這樣基本能滿足訊息的順序性的需求。但是

如果 partation 數量發生變化,那就很難保證 key 與分割槽之間的對映關係了

3。自定義策略:實現 Partitioner 介面就能自定義分割槽策略。

4。指定 Partiton 傳送

8.Kafka 支援讀寫分離嗎?為什麼?

Kafka 是

不支援讀寫分離

的,那麼讀寫分離的好處是什麼?主要就是讓一個節點去承擔另一個節點的負載壓力,也就是能做到一定程度的負載均衡,而且 Kafka 不透過讀寫分離也可以一定程度上去實現負載均衡。

但是對於 Kafka 的架構來說,讀寫分離有兩個很大的

缺點

《面試八股文》之kafka21卷

1。資料不一致的問題:讀寫分離必然涉及到資料的同步,只要是

不同節點之間的資料同步

,必然

會有資料不一致的問題

存在。

2。延時問題:由於 Kafka 獨特的資料處理方式,導致如果將資料從一個節點同步到另一個節點必然會經過

主節點磁碟和從節點磁碟

,對一些延時性要求較高的應用來說,並不太適用

9.那 Kafka 是怎麼去實現負載均衡的?

Kafka 的負責均衡主要是

透過分割槽來實現

的,我們知道 Kafka 是

主寫主讀

的架構,如下圖:

《面試八股文》之kafka21卷

共三個 broker ,裡面各有三個副本,總共有三個 partation, 深色的是 leader,淺色的是 follower,上下灰色分別代表生產者和消費者,虛線代表 follower 從 leader 拉取訊息。

我們從這張圖就可以很明顯的看出來,

每個 broker 都有消費者拉取訊息,每個 broker 也都有生產者傳送訊息,每個 broker 上的讀寫負載都是一樣的

,這也說明了 kafka 獨特的架構方式可以透過主寫主讀來實現負載均衡。

10.Kafka 的負責均衡會有什麼問題呢?

kafka的負載均衡在絕對理想的狀況下可以實現,但是會有某些情況出現一定程度上的負載不均衡

《面試八股文》之kafka21卷

1。

broker 端分配不均

:當建立 topic 的時候可能會出現某些 broker 分配到的分割槽數多,而有些 broker 分配的分割槽少,這就導致了 leader 多副本不均。

2。

生產者寫入訊息不均

:生產者可能只對某些 broker 中的 leader 副本進行大量的寫入操作,而對其他的 leader 副本不聞不問。

3。

消費者消費不均

:消費者可能只對某些 broker 中的 leader 副本進行大量的拉取操作,而對其他的 leader 副本不聞不問。

4。

leader 副本切換不均

:當主從副本切換或者分割槽副本進行了重分配後,可能會導致各個 broker 中的 leader 副本分配不均勻。

11.Kafka 的可靠性是怎麼保證的?

《面試八股文》之kafka21卷

1.acks

這個引數用來指定分割槽中有多少個副本收到這條訊息,生產者才認為這條訊息是寫入成功的,這個引數有三個值:

1。acks = 1,預設為1。生產者傳送訊息,

只要 leader 副本成功寫入訊息,就代表成功

。這種方案的問題在於,當返回成功後,如果 leader 副本和 follower 副本還

沒有來得及同步

,leader 就崩潰了,那麼在選舉後新的 leader 就沒有這條

訊息,也就丟失了

2。acks = 0。生產者傳送訊息後直接算寫入成功,不需要等待響應。這個方案的問題很明顯,

只要服務端寫訊息時出現任何問題,都會導致訊息丟失

3。acks = -1 或 acks = all。生產者傳送訊息後,需要等待 ISR 中的所有副本都成功寫入訊息後才能收到服務端的響應。毫無疑問這種方案的

可靠性是最高

的,但是如果 ISR 中只有leader 副本,那麼就和 acks = 1 毫無差別了。

2.訊息傳送的方式

第6問中我們提到了生產者傳送訊息有三種方式,發完即忘,同步和非同步。我們可以

透過同步或者非同步

獲取響應結果,

失敗做重試

來保證訊息的可靠性。

3.手動提交位移

預設情況下,當消費者消費到訊息後,就會自動提交位移。但是如果消費者消費出錯,沒有進入真正的業務處理,那麼就可能會導致這條訊息消費失敗,從而丟失。我們可以開啟手動提交位移,等待業務正常處理完成後,再提交offset。

4.透過副本 LEO 來確定分割槽 HW

可參考第五問

12.Kafka 的訊息消費方式有哪些?

一般訊息消費有兩種模式,推和拉。Kafka的消費是屬於

拉模式

的,而此模式的訊息消費方式有

兩種,點對點和釋出訂閱

《面試八股文》之kafka21卷

1。

點對點

:如果所有消費者屬於同一個消費組,那麼所有的訊息都會被均勻的投遞給每一個消費者,

每條訊息只會被其中一個消費者消費

《面試八股文》之kafka21卷

2。

釋出訂閱

:如果所有消費者屬於不同的消費組,那麼所有的訊息都會被投遞給每一個消費者,

每個消費者都會收到該訊息

13.分割槽再分配是做什麼的?解決了什麼問題?

分割槽再分配主要是用來

維護 kafka 叢集的負載均衡

既然是分割槽再分配,那麼 kafka 分割槽有什麼問題呢?

《面試八股文》之kafka21卷

問題1:當叢集中的一個節點下線了

如果該節點的分割槽是單副本的,那麼分割槽將會變得不可用

如果是多副本的,就會進行 leader 選舉,在其他機器上選舉出新的 leader

kafka 並不會將這些失效的分割槽遷移到其他可用的 broker 上

,這樣就會影響叢集的負載均衡,甚至也會影響服務的可靠性和可用性

《面試八股文》之kafka21卷

問題2:當叢集新增 broker 時,只有新的主題分割槽會分配在該 broker 上,而老的主題分割槽不會分配在該 broker 上,就造成了

老節點和新節點之間的負載不均衡

為了解決該問題就出現了分割槽再分配,它可以在叢集擴容,broker 失效的場景下進行分割槽遷移。

分割槽再分配的原理就是通化控制器給分割槽新增新的副本,然後透過網路把舊的副本資料複製到新的副本上,在複製完成後,將舊副本清除。

當然,為了不影響叢集正常的效能,在此複製期間還會有一些列保證效能的操作,比如

複製限流

14.副本 leader 是怎麼選舉的?

當分割槽 leader 節點崩潰時,其中一個 follower 節點會成為新的 leader 節點,這樣會

導致叢集的負載不均衡,從而影響服務的健壯性和穩定性

如下:

Topic: test Partation:0 Leader:1 Replicas:1,2,0 Isr:1,2,0

Topic: test Partation:1 Leader:2 Replicas:2,0,1 Isr:2,0,1

Topic: test Partation:2 Leader:0 Replicas:0,1,2 Isr:0,1,2

我們可以看到

0 分割槽有 1 個 leader

1 分割槽有 2 個 leader

2 分割槽有 0 個 leader

如果此時中間的

節點重啟

Topic: test Partation:0 Leader:1 Replicas:1,2,0 Isr:1,0,2

Topic: test Partation:1 Leader:0 Replicas:2,0,1 Isr:0,1,2

Topic: test Partation:2 Leader:0 Replicas:0,1,2 Isr:0,1,2

我們又可以看到:

0 分割槽有 1 個 leader

1 分割槽有 0 個 leader

2 分割槽有 0 個 leader

我們會發現,原本 1 分割槽有兩個 ledaer,經過重啟後 leader 都消失了,如此就

負載不均衡

了。

為了解決這種問題,就引入了優先副本的概念

優先副本就是說在 AR 集合中的第一個副本。比如分割槽 2 的 AR 為 0,1,2,那麼分割槽 2 的優先副本就為0。理想情況下優先副本就是 leader 副本。優先副本選舉就是促使優先副本成為 leader 副本,從而維護叢集的負載均衡。

15.分割槽數越多越好嗎?吞吐量就會越高嗎?

一般類似於這種問題的答案,都是持否定態度的。

但是可以說,

在一定條件下,分割槽數的數量是和吞吐量成正比的,分割槽數和效能也是成正比的

那麼為什麼說超過了一定限度,就會對效能造成影響呢?原因如下:

《面試八股文》之kafka21卷

1.客戶端/伺服器端需要使用的記憶體就越多

服務端在很多元件中都維護了分割槽級別的快取,分割槽數越大,

快取成本

也就越大。

消費端的消費執行緒數是和分割槽數掛鉤的,分割槽數越大消費執行緒數也就越多,

執行緒的開銷成本

也就越大

生產者傳送訊息有快取的概念,會為每個分割槽快取訊息,當積累到一定程度或者時間時會將訊息傳送到分割槽,

分割槽越多,這部分的快取

也就越大

2.檔案控制代碼的開銷

每個 partition 都會對應磁碟檔案系統的一個目錄

。在 Kafka 的資料日誌檔案目錄中,每個日誌資料段都會分配兩個檔案,一個索引檔案和一個數據檔案。

每個 broker 會為每個日誌段檔案開啟一個 index 檔案控制代碼和一個數據檔案控制代碼

。因此,隨著 partition 的增多,所需要保持開啟狀態的檔案控制代碼數也就越多,最終可能超過底層作業系統配置的檔案控制代碼數量限制。

3.越多的分割槽可能增加端對端的延遲

Kafka 會將分割槽 HW 之前的訊息暴露給消費者。

分割槽越多則副本之間的同步數量就越多

,在預設情況下,每個 broker 從其他 broker 節點進行資料副本複製時,該 broker 節點只會為此工作分配一個執行緒,該執行緒需要完成該 broker 所有 partition 資料的複製。

4.降低高可用性

在第 13 問我們提到了分割槽再分配,會將資料複製到另一份副本當中,

分割槽數量越多,那麼恢復時間也就越長

,而如果發生宕機的 broker 恰好是 controller 節點時:在這種情況下,新 leader 節點的選舉過程在 controller 節點恢復到新的 broker 之前不會啟動。controller 節點的錯誤恢復將會自動地進行,但是新的 controller 節點需要從 zookeeper 中讀取每一個 partition 的元資料資訊用於初始化資料。例如,假設一個Kafka 叢集存在 10000個partition,從 zookeeper 中恢復元資料時每個 partition 大約花費 2 ms,則 controller 的恢復將會增加約 20 秒的不可用時間視窗。

16.如何增強消費者的消費能力?

1。可以考慮增加 topic 的分割槽數,並且同時提升消費組的消費者數量,消費者數=分割槽數。

2。如果是消費者消費不及時,可以採用多執行緒的方式進行消費,並且最佳化業務方法流程,同樣的分割槽數,為什麼人家併發那麼高,你的就不行??

17.消費者與 topic 的分割槽分配策略有哪些?

《面試八股文》之kafka21卷

1.RangeAssignor 分配策略

該分配策略是按照

消費者總數和分割槽總數進行整除運算

來獲得一個跨度,然後分割槽按照跨度來進行平均分配,儘可能保證分割槽均勻的分配給所有的消費者。

對於每個 topic,該策略會講消費者組內所有訂閱這個主題的消費者

按照名稱的字典順序排序

,然後為每個消費者劃分固定過的區域,

如果不夠平均分配,那麼字典排序考前的就會多分配一個分割槽

比如 2 個消費者屬於一個消費者組,有 2 個 topic t1,t2,每個 topic 都有 3 個分割槽,p1,p2,p3,那麼分配的情況如下:

消費者A:t0-p0,t0-p1,t1-p0,t1-p1,

消費者B:t0-p2,t1-p2

這樣就會出現非配不均勻的情況

2.RoundRobinAssignor 分配策略

該分配策略是

按將消費者組內所有消費者及消費者訂閱的所有主題的分割槽按照字典排序,然後透過輪詢的方式分配給每個消費者

比如有 3 個消費者 A,B,C,訂閱了 3 個 topic ,t0,t1,t2,每個 topic 各有 3 個分割槽 p0,p1,p2。 如果 A 訂閱了 t0,B 訂閱了 t0 和 t1,C 訂閱了 t0,t1,t2,那麼分配的情況如下:

消費者A:t0-p0

消費者B:t1-p0

消費者C:t1-p1,t2-p0,t2-p1,t2-p2

這樣也會出現分配不均勻的情況,按照訂閱情況來講完全可以吧 t1p1 分配給消費者B

3.StickyAssignor分配策略

這種分配策略有兩個目的

1。分割槽的分配要儘可能的均勻

2。分割槽的分配儘可能的與上次分配的保持相同。

當兩者發生衝突時,第一個目標優先於第二個目標。

假設消費組內有3個消費者:

C0、C1、C2

它們都訂閱了4個主題:

t0、t1、t2、t3

並且每個主題有2個分割槽,也就是說整個消費組訂閱了,

t0p0、t0p1、t1p0、t1p1、t2p0、t2p1、t3p0、t3p1

這8個分割槽

最終的分配結果如下:

消費者C0:t0p0、t1p1、t3p0

消費者C1:t0p1、t2p0、t3p1

消費者C2:t1p0、t2p1

這樣初看上去似乎與採用RoundRobinAssignor策略所分配的結果相同

此時假設消費者C1脫離了消費組,那麼消費組就會執行再平衡操作,進而消費分割槽會重新分配。如果採用RoundRobinAssignor策略,那麼此時的分配結果如下:

消費者C0:t0p0、t1p0、t2p0、t3p0

消費者C2:t0p1、t1p1、t2p1、t3p1

如分配結果所示,RoundRobinAssignor策略會按照消費者C0和C2進行重新輪詢分配。而如果此時使用的是StickyAssignor策略,那麼分配結果為:

消費者C0:t0p0、t1p1、t3p0、t2p0

消費者C2:t1p0、t2p1、t0p1、t3p1

可以看到分配結果中保留了上一次分配中對於消費者C0和C2的所有分配結果,並將原來消費者C1的“負擔”分配給了剩餘的兩個消費者C0和C2,最終C0和C2的分配還保持了均衡。

如果發生分割槽重分配,那麼對於同一個分割槽而言有可能之前的消費者和新指派的消費者不是同一個,對於之前消費者進行到一半的處理還要在新指派的消費者中再次復現一遍,這顯然很浪費系統資源。StickyAssignor策略如同其名稱中的“sticky”一樣,讓分配策略具備一定的“粘性”,儘可能地讓前後兩次分配相同,進而減少系統資源的損耗以及其它異常情況的發生

到目前為止所分析的都是消費者的訂閱資訊都是相同的情況,我們來看一下訂閱資訊不同的情況下的處理。

舉例: 同樣消費組內有3個消費者:

C0、C1、C2

叢集中有3個主題

t0、t1、t2

這3個主題分別有

1、2、3

個分割槽

也就是說叢集中有

t0p0、t1p0、t1p1、t2p0、t2p1、t2p2

這6個分割槽

消費者

C0訂閱了主題t0,消費者C1訂閱了主題t0和t1,消費者C2訂閱了主題t0、t1和t2

如果此時採用RoundRobinAssignor策略:

消費者C0:t0p0

消費者C1:t1p0

消費者C2:t1p1、t2p0、t2p1、t2p2

如果此時採用的是StickyAssignor策略:

消費者C0:t0p0

消費者C1:t1p0、t1p1

消費者C2:t2p0、t2p1、t2p2

此時消費者C0脫離了消費組,那麼RoundRobinAssignor策略的分配結果為:

消費者C1:t0p0、t1p1

消費者C2:t1p0、t2p0、t2p1、t2p2

StickyAssignor策略,那麼分配結果為:

消費者C1:t1p0、t1p1、t0p0

消費者C2:t2p0、t2p1、t2p2

可以看到StickyAssignor策略保留了消費者C1和C2中原有的5個分割槽的分配:

t1p0、t1p1、t2p0、t2p1、t2p2。

從結果上看StickyAssignor策略比另外兩者分配策略而言顯得更加的優異,這個策略的程式碼實現也是異常複雜。

4.自定義分割槽分配策略

可以透過實現 org。apache。kafka。clients。consumer。internals。PartitionAssignor 介面來實現

18.kafka 控制器是什麼?有什麼作用

在 Kafka 叢集中會有一個或多個 broker,其中有一個 broker 會被選舉為控制器,

它負責管理整個叢集中所有分割槽和副本的狀態

,kafka 叢集中

只能有一個控制器

當某個分割槽的 leader 副本出現故障時,由控制器負責

為該分割槽選舉新的 leader 副本

當檢測到某個分割槽的ISR集合發生變化時,由控制器負責

通知所有 broker 更新其元資料資訊

當為某個 topic 增加分割槽數量時,由控制器

負責分割槽的重新分配

19.kafka 控制器是怎麼進行選舉的?

kafka 中的控制器選舉工作

依賴於 Zookeeper

,成功競選成為控制器的 broker 會在Zookeeper中建立/controller臨時節點。

每個 broker 啟動的時候會去嘗試讀取/controller 節點的 brokerid的值

如果

讀取到的

brokerid 的值不為-1

,表示已經有其他broker 節點成功競選為控制器,所以當前 broker

就會放棄競選

如果Zookeeper中

不存在

/controller 節點,

或者

這個節點的資料

異常

,那麼

就會嘗試去建立

/controller 節點,

建立成功的那個 broker 就會成為控制器

每個 broker 都會在記憶體中儲存當前控制器的 brokerid 值,這個值可以標識為 activeControllerId。

Zookeeper 中還有一個與控制器有關的/controller_epoch 節點,這個節點是

持久節點

,節點中存放的是一個整型的 controller_epoch 值。controller_epoch 值用於

記錄控制器發生變更的次數

controller_epoch 的

初始值為1

,即叢集中的第一個控制器的紀元為1,當控制器發生變更時,

每選出一個新的控制器就將該欄位值加1

每個和控制器互動的請求都會攜帶 controller_epoch 這個欄位,

如果請求的 controller_epoch 值

小於

記憶體中的 controller_epoch值

認為這個請求是向已經過期的控制器傳送的請求,那麼這個請求會

被認定為無效的請求

如果請求的 controller_epoch 值

大於

記憶體中的 controller_epoch值,那麼說明

已經有新的控制器當選

20.kafka 為什麼這麼快?

《面試八股文》之kafka21卷

1.順序讀寫

磁碟分為順序讀寫與隨機讀寫,基於磁碟的隨機讀寫確實很慢,但磁碟的順序讀寫效能卻很高,kafka 這裡採用的就是順序讀寫。

2.Page Cache

為了最佳化讀寫效能,Kafka 利用了操作

系統本身的 Page Cache

,就是利用作業系統自身的記憶體而不是JVM空間記憶體。

3.零複製

Kafka使用了零複製技術,也就是

直接將資料從核心空間的讀緩衝區直接複製到核心空間的 socket 緩衝區

,然後再寫入到 NIC 緩衝區,避免了在核心空間和使用者空間之間穿梭。

4.分割槽分段+索引

Kafka 的 message 是按 topic分 類儲存的,topic 中的資料又是按照一個一個的 partition 即分割槽儲存到不同 broker 節點。每個 partition 對應了作業系統上的一個資料夾,partition 實際上又是按照segment分段儲存的。

透過這種分割槽分段的設計,Kafka 的 message 訊息實際上是分散式儲存在一個一個小的 segment 中的,每次檔案操作也是直接操作的 segment。為了進一步的查詢最佳化,Kafka 又預設為分段後的資料檔案建立了索引檔案,就是檔案系統上的。index檔案。這種分割槽分段+索引的設計,不僅提升了資料讀取的效率,同時也提高了資料操作的並行度。

5.批次讀寫

Kafka

資料讀寫也是批次的而不是單條的

,這樣可以避免在網路上頻繁傳輸單個訊息帶來的延遲和頻寬開銷。假設網路頻寬為10MB/S,一次性傳輸10MB的訊息比傳輸1KB的訊息10000萬次顯然要快得多。

6.批次壓縮

Kafka 把所有的訊息都變成一個

批次的檔案

,並且進行合理的

批次壓縮

,減少網路 IO 損耗,透過 mmap 提高 I/O 速度,寫入資料的時候由於單個Partion是末尾新增所以速度最優;讀取資料的時候配合 sendfile 進行直接讀取。

21.什麼情況下 kafka 會丟失訊息?

Kafka 有三次訊息傳遞的過程: 生產者發訊息給 Broker,Broker 同步訊息和持久化訊息,Broker 將訊息傳遞給消費者。

《面試八股文》之kafka21卷

這其中每一步都有可能丟失訊息。

1。生產者傳送資料: 在第 11 問中的 acks中有說到

當 acks 為 0,

只要服務端寫訊息時出現任何問題,都會導致訊息丟失

當 acks 配置為 1 時,生產者傳送訊息,只要 leader 副本成功寫入訊息,就代表成功。這種方案的問題在於,當返回成功後,

如果 leader 副本和 follower 副本還沒有來得及同步,leader 就崩潰了,那麼在選舉後新的 leader 就沒有這條訊息,也就丟失了

2。Broker 儲存資料:kafka 透過 Page Cache 將資料寫入磁碟。

Page Cache 就是當往磁碟檔案寫入的時候,系統會先將資料流寫入快取中,但是

什麼時候將快取的資料寫入檔案中是由作業系統自行決定

。所以

如果此時機器突然掛了,也是會丟失訊息的

3。消費者消費資料:在開啟

自動提交 offset

時,只要消費者消費到訊息,那麼就會自動提交偏移量,

如果業務還沒有來得及處理,那麼訊息就會丟失

<面試八股文>系列至今

「已經幫助眾多讀者拿到了大廠offer」

!!

更多<面試八股文>系列請

「關注公眾號:moon聊技術」

獲取

「在這裡,送大家一份自己整理的面試資料,絕不是在網上那種打包下載的,而是自己需要學到某個方向知識的時候,需要看了,去網上挨個找的,最後彙總而成。這部分我是會不斷把它完善的,當成自己的小電子書庫,不多,但貴在精。」

《面試八股文》之kafka21卷

當然,

「除了面試資料」

之外,moon還特地準備了市面上大

「約200本電子書」

,一起打包送給你,

「歡迎成為moon的朋友,一起玩技術、聊人生、看生活、搞理想」

《面試八股文》之kafka21卷

「關注公眾號:moon聊技術,立刻白嫖!」

標簽: 分割槽  副本  消費者  Kafka  訊息