Kafka 是一個優秀的分散式訊息中間件,許多系統中都會使用到 Kafka 來做訊息通訊。對分散式訊息系統的了解和使用幾乎成為一個後台開發人員必備的技能。今天碼哥字節
就從常見的 Kafka 面試題入手,和大家聊聊 Kafka 的那些事兒。
分散式訊息是一種通訊機制,和RPC、HTTP、RMI 等不一樣,訊息中間件採用分散式中間代理的方式進行通訊。如圖所示,採用了訊息中間件之後,上游業務系統發送訊息,先儲存在訊息中間件,然後由訊息中間件將訊息分發到對應的業務模組應用(分散式生產者 - 消費者模式)。這種非同步的方式,減少了服務之間的耦合程度。
定義訊息中間件:
在系統架構中引用額外的元件,必然提高系統的架構複雜度和維運的難度,那麼在系統中使用分散式訊息中間件有什麼優點呢?訊息中間件在系統中扮演的角色又是什麼呢?
##緩衝############非同步通訊#############面試時,面試官常常關心面試者對開源元件的選用能力,這既可以考驗面試者知識的廣度,也可以考驗面試者對某一類系統的知識的認識深度,也可以看出面試者對系統整體掌握和系統架構設計的能力。開源分散式訊息系統很多,不同的訊息系統的特性也不一樣,選擇怎樣的訊息系統,不僅需要對各訊息系統有一定的了解,也需要對自身系統需求有清楚的認知。 #########以下是常見的幾種分散式訊息系統的對比:######
是否支援事務?
###分割區數是否可以減少? ###############Kafka 架構中的一般概念:#######Kafka Topic Partitions Layout
Kafka 將Topic 進行分區,分區可以並發讀寫。
Kafka Consumer Offset
##簡單地說出 Kafka 的架構?
Producer、Consumer、Consumer Group、Topic、Partition
Kafka 是推模式還是拉模式,推拉的差別是什麼?
Kafka Producer 向 Broker 發送訊息使用 Push 模式,Consumer 消費採用的 Pull 模式。拉取模式,讓 consumer 自己管理 offset,可以提供讀取效能
Kafka 如何廣播訊息?
Consumer group
Kafka 的訊息是否是有順序的?
Topic 層級無序,Partition 有序
Kafka 是否支援讀寫分離?
不支持,只有 Leader 對外提供讀寫服務
#Kafka 如何保證資料高可用?
副本,ack,HW
#Kafka 中 zookeeper 的作用?
叢集管理,元資料管理
是否支援交易?
0.11 後支援事務,可以實現」exactly once「
分割區數是否可以減少?
不可以,會遺失資料
#Kafka 的命令列工具在Kafka 套件的/bin
#目錄下,主要包括服務和叢集管理腳本,配置腳本,資訊檢視腳本,Topic 腳本,客戶端腳本等。
Kafka producer 的正常生產邏輯包含以下步驟:
Producer 發送訊息的過程如下圖所示,需要經過攔截器
,序列化器
和分區器
,最終由累加器
批次發送至Broker。
Kafka Producer 需要以下必要參數:
#常見參數:
batch.num.messages
預設值:200,每次批次訊息的數量,只對asyc起作用。
request.required.acks
預設值:0,0 表示 producer 毋須等待 leader 的確認,1 代表需要 leader 確認寫入它的本地 log 並立即確認,-1 代表所有的備份都完成後確認。只對 async 模式起作用,這個參數的調整是資料不遺失和發送效率的 tradeoff,如果對資料遺失不敏感而在乎效率的場景可以考慮設定為 0,這樣可以大大提高 producer 發送資料的效率。
request.timeout.ms
#預設值:10000,確認逾時時間。
partitioner.class
預設值:kafka.producer.DefaultPartitioner,必須實作kafka.producer.Partitioner,根據Key 提供一個分區策略。 有時候我們需要相同類型的消息必須順序處理,這樣我們就必須自訂分配策略,從而將相同類型的資料分配到同一個分區中。
producer.type
預設值:sync,指定訊息傳送是同步還是非同步。非同步 asyc 成批發送用 kafka.producer.AyncProducer, 同步 sync 用 kafka.producer.SyncProducer。同步和非同步發送也會影響訊息生產的效率。
compression.topic
#預設值:none,訊息壓縮,預設不壓縮。其餘壓縮方式還有,"gzip"、"snappy"和"lz4"。訊息的壓縮可以大幅減少網路傳輸量、降低網路 IO,從而提高整體效能。
compressed.topics
預設值:null,在設定了壓縮的情況下,可以指定特定的 topic 壓縮,未指定則全部壓縮。
message.send.max.retries
預設值:3,訊息傳送最大嘗試次數。
retry.backoff.ms
#預設值:300,每次嘗試增加的額外的間隔時間。
topic.metadata.refresh.interval.ms
預設值:600000,定期的取得元資料的時間。當分割區遺失,leader 不可用時 producer 也會主動取得元數據,如果為 0,則每次發送完訊息就會取得元數據,不建議。如果為負值,則只有在失敗的情況下取得元資料。
queue.buffering.max.ms
預設值:5000,在producer queue 的快取的資料最大時間,僅僅for asyc。
queue.buffering.max.message
預設值:10000,producer 快取的訊息的最大數量,僅僅for asyc。
queue.enqueue.timeout.ms
預設值:-1,0 當 queue 滿時丟掉,負值是 queue 滿時 block, 正值是 queue 滿時 block 對應的時間,僅僅 for asyc。
Kafka 有消費群組的概念,每個消費者只能消費所分配到的分區的消息,每一個分區只能被一個消費組中的一個消費者所消費,所以同一個消費組中消費者的數量如果超過了分區的數量,將會出現有些消費者分配不到消費的分區。消費群組與消費者關係如下圖所示:
Kafka Consumer Client 消費訊息通常包含以下步驟:
host:port
格式。 key.serializer
對應,key 的反序列化方式。 value.serializer
對應,value 的反序列化方式。 false
,則需要在程式中手動提交位移。對於精確到一次的語義,最好手動提交位移max.poll.records
條資料需要在 session.timeout.ms 這個時間內處理完 。預設值為 500#rebalance 本質上是一種協議,規定了一個consumer group 下的所有consumer 如何達成協議來分配訂閱topic 的每個分區。例如某個 group 下有 20 個 consumer,它訂閱了一個有 100 個分割區的 topic。正常情況下,Kafka 平均會為每個 consumer 指派 5 個分割區。這個分配的過程就叫做 rebalance。
什麼時候 rebalance?
這也是常被提及的問題。 rebalance 的觸發條件有三種:
如何進行群組內分割區分配?
Kafka 預設提供了兩種指派策略:Range 和 Round-Robin。當然 Kafka 採用了可插拔式的分配策略,你可以建立自己的分配器來實現不同的分配策略。
/bin
目錄,管理 kafka 叢集、管理 topic、生產和消費 kafka在分散式資料系統中,通常使用分區來提高系統的處理能力,透過副本來確保資料的高可用性。多分區意味著並發處理的能力,這多個副本中,只有一個是 leader,而其他的都是 follower 副本。僅有 leader 副本可以對外提供服務。多個 follower 副本通常存放在和 leader 副本不同的 broker 中。透過這樣的機制實現了高可用,當某台機器掛掉後,其他 follower 副本也能迅速」轉正“,開始對外提供服務。
為什麼 follower 副本不提供讀取服務?
這個問題本質上是對效能和一致性的取捨。試想一下,如果 follower 副本也對外提供服務那會怎麼樣呢?首先,性能是肯定會有所提升的。但同時,會出現一系列問題。類似資料庫事務中的幻讀,髒讀。例如你現在寫入一條數據到 kafka 主題 a,消費者 b 從主題 a 消費數據,卻發現消費不到,因為消費者 b 去讀取的那個分區副本中,最新消息還沒寫入。而這時候,另一個消費者 c 卻可以消費到最新那條數據,因為它消費了 leader 副本。 Kafka 透過 WH 和 Offset 的管理來決定 Consumer 可以消費哪些數據,已經目前寫入的數據。
只有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 之間的資料同步。
一方面,由於不同Partition 可位於不同機器,因此可以充分利用叢集優勢,實現機器間的並行處理。另一方面,由於Partition 在物理上對應一個資料夾,即使多個Partition 位於同一個節點,也可透過配置讓同一節點上的不同Partition 置於不同的disk drive 上,從而實現磁碟間的並行處理,充分發揮多磁碟的優勢。
Kafka 每一個partition 目錄下的檔案被平均切割成大小相等(預設一個檔案是500 兆,可以手動去設定)的數據文件, 每一個資料檔都稱為一個段(segment file), 每個 segment 都採用 append 的方式追加資料。
Kafka 的交付語意?
透過副本來保證資料的高可用,producer ack、重試、自動Leader 選舉,Consumer 自平衡
、
at most once和exactly once
。 kafka 透過 ack 的配置來實現前兩種。
AR:Assigned Replicas。 AR 是主題建立後,分區建立時被指派的副本集合,副本個 數由副本因子決定。 ISR:In-Sync Replicas。 Kafka 中特別重要的概念,指涉的是 AR 中那些與 Leader 保 持同步的副本集合。在 AR 中的副本可能不在 ISR 中,但 Leader 副本天然就包含在 ISR 中。關於 ISR,還有一個常見的面試題目是如何判斷副本是否應該屬於 ISR。目前的判斷 依據是:Follower 副本的 LEO 落後 Leader LEO 的時間,是否超過了 Broker 端參數 replica.lag.time.max.ms 值。如果超過了,副本就會被從 ISR 移除。
Leader 和 Flower 是什麼?
Kafka 中的 HW 代表什麼?
高水位值 (High watermark)。這是控制消費者可讀取訊息範圍的重要欄位。一 個一般消費者只能「看見」Leader 副本上介於 Log Start Offset 和 HW(不含)之間的 所有訊息。水位以上的訊息是對消費者不可見的。
Kafka 為保證優越的效能做了哪些處理?
partition 並發、順序讀寫磁碟、page cache 壓縮、高效能序列化(二進位)、記憶體對映無鎖定offset 管理、Java NIO 模型
#本文並沒有深入Kafka 的實現細節和源碼分析,但Kafka 確實是一個優秀的開源系統,很多優雅的架構設計和源碼設計都值得我們學習,十分建議感興趣的同學更加深入的去了解這個開源系統,對於自身架構設計能力,編碼能力,效能最佳化都會有很大的幫助。
以上是從面試角度一文學完 Kafka的詳細內容。更多資訊請關注PHP中文網其他相關文章!