從面試角度一文學完 Kafka

Kafka 是一個優秀的分佈式消息中間件,許多系統中都會使用到 Kafka 來做消息通信。對分佈式消息系統的瞭解和使用幾乎成爲一個後臺開發人員必備的技能。今天碼哥字節就從常見的 Kafka 面試題入手,和大家聊聊 Kafka 的那些事兒。

思維導圖

講一講分佈式消息中間件

問題

消息隊列

分佈式消息是一種通信機制,和 RPC、HTTP、RMI 等不一樣,消息中間件採用分佈式中間代理的方式進行通信。如圖所示,採用了消息中間件之後,上游業務系統發送消息,先存儲在消息中間件,然後由消息中間件將消息分發到對應的業務模塊應用(分佈式生產者 - 消費者模式)。這種異步的方式,減少了服務之間的耦合程度。

架構

定義消息中間件:

在系統架構中引用額外的組件,必然提高系統的架構複雜度和運維的難度,那麼在系統中使用分佈式消息中間件有什麼優勢呢?消息中間件在系統中起的作用又是什麼呢?

面試時,面試官經常會關心面試者對開源組件的選型能力,這既可以考驗面試者知識的廣度,也可以考驗面試者對某類系統的知識的認識深度,而且也可以看出面試者對系統整體把握和系統架構設計的能力。開源分佈式消息系統有很多,不同的消息系統的特性也不一樣,選擇怎樣的消息系統,不僅需要對各消息系統有一定的瞭解,也需要對自身系統需求有清晰的認識。

下面是常見的幾種分佈式消息系統的對比:

選擇

答案關鍵字

Kafka 基本概念和架構

問題

Kafka 架構中的一般概念:

架構

Kafka Topic Partitions Layout

主題

Kafka 將 Topic 進行分區,分區可以併發讀寫。

Kafka Consumer Offset

consumer offset

zookeeper

zookeeper

答案關鍵字

Kafka 使用

問題

命令行工具

Kafka 的命令行工具在 Kafka 包的/bin目錄下,主要包括服務和集羣管理腳本,配置腳本,信息查看腳本,Topic 腳本,客戶端腳本等。

我們通常可以使用kafka-console-consumer.shkafka-console-producer.sh腳本來測試 Kafka 生產和消費,kafka-consumer-groups.sh可以查看和管理集羣中的 Topic,kafka-topics.sh通常用於查看 Kafka 的消費組情況。

Kafka Producer

Kafka producer 的正常生產邏輯包含以下幾個步驟:

  1. 配置生產者客戶端參數常見生產者實例。

  2. 構建待發送的消息。

  3. 發送消息。

  4. 關閉生產者實例。

Producer 發送消息的過程如下圖所示,需要經過攔截器序列化器分區器,最終由累加器批量發送至 Broker。

producer

Kafka Producer 需要以下必要參數:

常見參數:

Kafka Consumer

Kafka 有消費組的概念,每個消費者只能消費所分配到的分區的消息,每一個分區只能被一個消費組中的一個消費者所消費,所以同一個消費組中消費者的數量如果超過了分區的數量,將會出現有些消費者分配不到消費的分區。消費組與消費者關係如下圖所示:

consumer group

Kafka Consumer Client 消費消息通常包含以下步驟:

  1. 配置客戶端,創建消費者

  2. 訂閱主題

  3. 拉去消息並消費

  4. 提交消費位移

  5. 關閉消費者實例

過程

因爲 Kafka 的 Consumer 客戶端是線程不安全的,爲了保證線程安全,並提升消費性能,可以在 Consumer 端採用類似 Reactor 的線程模型來消費數據。

消費模型

Kafka consumer 參數

Kafka Rebalance

rebalance 本質上是一種協議,規定了一個 consumer group 下的所有 consumer 如何達成一致來分配訂閱 topic 的每個分區。比如某個 group 下有 20 個 consumer,它訂閱了一個具有 100 個分區的 topic。正常情況下,Kafka 平均會爲每個 consumer 分配 5 個分區。這個分配的過程就叫 rebalance。

什麼時候 rebalance?

這也是經常被提及的一個問題。rebalance 的觸發條件有三種:

如何進行組內分區分配?

Kafka 默認提供了兩種分配策略:Range 和 Round-Robin。當然 Kafka 採用了可插拔式的分配策略,你可以創建自己的分配器以實現不同的分配策略。

答案關鍵字

高可用和性能

問題

分區與副本

分區副本

在分佈式數據系統中,通常使用分區來提高系統的處理能力,通過副本來保證數據的高可用性。多分區意味着併發處理的能力,這多個副本中,只有一個是 leader,而其他的都是 follower 副本。僅有 leader 副本可以對外提供服務。多個 follower 副本通常存放在和 leader 副本不同的 broker 中。通過這樣的機制實現了高可用,當某臺機器掛掉後,其他 follower 副本也能迅速” 轉正 “,開始對外提供服務。

爲什麼 follower 副本不提供讀服務?

這個問題本質上是對性能和一致性的取捨。試想一下,如果 follower 副本也對外提供服務那會怎麼樣呢?首先,性能是肯定會有所提升的。但同時,會出現一系列問題。類似數據庫事務中的幻讀,髒讀。比如你現在寫入一條數據到 kafka 主題 a,消費者 b 從主題 a 消費數據,卻發現消費不到,因爲消費者 b 去讀取的那個分區副本中,最新消息還沒寫入。而這個時候,另一個消費者 c 卻可以消費到最新那條數據,因爲它消費了 leader 副本。Kafka 通過 WH 和 Offset 的管理來決定 Consumer 可以消費哪些數據,已經當前寫入的數據。

watermark

只有 Leader 可以對外提供讀服務,那如何選舉 Leader

kafka 會將與 leader 副本保持同步的副本放到 ISR 副本集合中。當然,leader 副本是一直存在於 ISR 副本集合中的,在某些特殊情況下,ISR 副本中甚至只有 leader 一個副本。當 leader 掛掉時,kakfa 通過 zookeeper 感知到這一情況,在 ISR 副本中選取新的副本成爲 leader,對外提供服務。但這樣還有一個問題,前面提到過,有可能 ISR 副本集合中,只有 leader,當 leader 副本掛掉後,ISR 集合就爲空,這時候怎麼辦呢?這時候如果設置 unclean.leader.election.enable 參數爲 true,那麼 kafka 會在非同步,也就是不在 ISR 副本集合中的副本中,選取出副本成爲 leader。

副本的存在就會出現副本同步問題

Kafka 在所有分配的副本 (AR) 中維護一個可用的副本列表 (ISR),Producer 向 Broker 發送消息時會根據ack配置來確定需要等待幾個副本已經同步了消息才相應成功,Broker 內部會ReplicaManager服務來管理 flower 與 leader 之間的數據同步。

sync

性能優化

Partition 併發

一方面,由於不同 Partition 可位於不同機器,因此可以充分利用集羣優勢,實現機器間的並行處理。另一方面,由於 Partition 在物理上對應一個文件夾,即使多個 Partition 位於同一個節點,也可通過配置讓同一節點上的不同 Partition 置於不同的 disk drive 上,從而實現磁盤間的並行處理,充分發揮多磁盤的優勢。

順序讀寫

Kafka 每一個 partition 目錄下的文件被平均切割成大小相等(默認一個文件是 500 兆,可以手動去設置)的數據文件, 每一個數據文件都被稱爲一個段(segment file), 每個 segment 都採用 append 的方式追加數據。

追加數據

答案關鍵字

本文並沒有深入 Kafka 的實現細節和源碼分析,但 Kafka 確實是一個 優秀的開源系統,很多優雅的架構設計和源碼設計都值得我們學習,十分建議感興趣的同學更加深入的去了解一下這個開源系統,對於自身架構設計能力,編碼能力,性能優化都會有很大的幫助。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/tK35gnCaKxlKn1_k4decyA