百度做網(wǎng)站搜索靠前百度電話
分區(qū)機(jī)制
Kafka 的分區(qū)機(jī)制是其實(shí)現(xiàn)高吞吐和可擴(kuò)展性的重要特性之一。
Kafka 中的數(shù)據(jù)具有三層結(jié)構(gòu),即主題(topic)-> 分區(qū)(partition)-> 消息(message)。一個(gè) Kafka 主題可以包含多個(gè)分區(qū),而每個(gè)分區(qū)又可以包含多條消息。
Topic和Partition是kafka中比較重要的概念。
- 主題:Topic是Kafka中承載消息的邏輯容器??梢岳斫鉃橐粋€(gè)消息隊(duì)列。生產(chǎn)者將消息發(fā)送到特定的Topic,消費(fèi)者從Topic中讀取消息。Topic可以被認(rèn)為是邏輯上的消息流。在實(shí)際使用中多用來區(qū)分具體的業(yè)務(wù)。
- 分區(qū):Partition。是Topic的物理分區(qū)。一個(gè)Topic可以被分成多個(gè)Partition,每個(gè)Partition是一個(gè)有序且持久化存儲(chǔ)的日志文件。每個(gè)Partition都存儲(chǔ)了一部分消息,并且有一個(gè)唯一的標(biāo)識(shí)符(稱為Partition ID)。
好處:
- 提升吞吐量:通過將一個(gè)Topic分成多個(gè)Partition,可以實(shí)現(xiàn)消息息的并行處理。每個(gè)Partition可以由不同的消費(fèi)者組進(jìn)行獨(dú)立消費(fèi),這樣就可以提高整個(gè)系統(tǒng)的吞吐量。
- 負(fù)載均衡:Partition的數(shù)量通常比消費(fèi)者組的數(shù)量多,這樣可以使每個(gè)消費(fèi)者組中的消費(fèi)者均勻地消費(fèi)消息。當(dāng)有新的消費(fèi)者加入或離開消費(fèi)者組時(shí),可以通過重新分配Partition的方式進(jìn)行負(fù)載均衡。
- 擴(kuò)展性:通過增加Partition的數(shù)量,可以實(shí)現(xiàn)Kafka集群的廣展性。更多的Partition可以提供更高的并發(fā)處理能力和更大的存儲(chǔ)容量。
重平衡機(jī)制
Kafka的重平衡機(jī)制是指在消費(fèi)者組中新增或刪除消費(fèi)者時(shí),Kafka集群會(huì)重新分配主題分區(qū)給各個(gè)消費(fèi)者,以保證每個(gè)消費(fèi)者消費(fèi)的分區(qū)數(shù)量盡可能均衡。
重平衡機(jī)制的目的是實(shí)現(xiàn)消費(fèi)者的負(fù)載均衡和高可用性,以確保每個(gè)消費(fèi)者都能夠按照預(yù)期的方式消費(fèi)到消息。
重平衡的3個(gè)觸發(fā)條件:
- 消費(fèi)者組成員數(shù)量發(fā)生變化。
- 消費(fèi)者組成員訂閱主題數(shù)量發(fā)生變化。
- 訂閱主題的分區(qū)數(shù)發(fā)生變化。
平衡機(jī)制步驟:
- 暫停消費(fèi):在重平衡開始之前,Kafka會(huì)暫停所有消費(fèi)者的拉取操作,以確保不會(huì)出現(xiàn)重平衡期間的消息丟失或重復(fù)消費(fèi)。
- 計(jì)算分區(qū)分配方案:kafka集群會(huì)根據(jù)當(dāng)前消費(fèi)者組的消費(fèi)者數(shù)量和主題分區(qū)數(shù)量,計(jì)算出每個(gè)消費(fèi)者應(yīng)該分配的分區(qū)列表,以實(shí)現(xiàn)分區(qū)的負(fù)載均衡。
- 通知消費(fèi)者:一旦分區(qū)分配方案確定,Kafka集群會(huì)將分配方案發(fā)送給每個(gè)消費(fèi)者,告訴它們需要消費(fèi)的分區(qū)列表,并請(qǐng)求它們重新加入消費(fèi)者組。
- 重新分配分區(qū):在消費(fèi)者重新加入消費(fèi)者組后,Kafka集群會(huì)將分區(qū)分配方案應(yīng)用到實(shí)際的分區(qū)分配中,重新分配主題分區(qū)給各個(gè)消費(fèi)者。
- 恢復(fù)消費(fèi):最后,Kafka會(huì)恢復(fù)所有消費(fèi)者的拉取操作,允許它們消費(fèi)分配給自己的分區(qū)。
Kafka的重平衡機(jī)制能夠有效地實(shí)現(xiàn)消費(fèi)者的負(fù)載均衡和高可用性,提高消息的處理能力和可靠性。但是,由于重平衡會(huì)帶來一定的性能開銷和不確定性,例如:消息亂序、重復(fù)消費(fèi)等問題,因此在設(shè)計(jì)應(yīng)用時(shí)需要考慮到重平衡的影響,并采取一些措施來降低重平衡的頻率和影響。
在重平衡過程中,所有Consumer實(shí)例都會(huì)停止消費(fèi)。等待重平衡完成。但是目前并沒有什么好的辦法來解決重平衡帶來的STW,只能盡量避免它的發(fā)生。
Consumer實(shí)例五種狀態(tài)
- Empty:組內(nèi)沒有任何成員,但是消費(fèi)者可能存在已提交的位移數(shù)據(jù),而且這些位移尚未過期。
- Dead:同樣是組內(nèi)沒有任何成員,但是組的元數(shù)據(jù)信息已經(jīng)被協(xié)調(diào)者端移除,協(xié)調(diào)者保存著當(dāng)前向他注冊(cè)過的所有組信息。
- Preparing Rebalance:費(fèi)者組準(zhǔn)備開啟重平衡,此時(shí)所有成員都需要重新加入消肖費(fèi)者組
- Completing Rebalance:消費(fèi)者組下所有成員已經(jīng)加入,各個(gè)成員中等待分配方案
- Stable:消費(fèi)者組的穩(wěn)定狀態(tài),該狀態(tài)表明重平衡已經(jīng)完成,組內(nèi)成員能夠正常消費(fèi)數(shù)據(jù)
Leader選舉機(jī)制
Partition Leader 選舉
Kafka中的每個(gè)Partition都有一個(gè)Leader,負(fù)責(zé)處理該P(yáng)arttition的讀寫請(qǐng)求。在正常情況下。Leader和ISR集合中的所有副本保持同步,Leader接收到的消息也會(huì)被ISF集合中的副本所接收。當(dāng)leader副本宕機(jī)或者無法正常工作時(shí),需要選舉新的leader副本來接管分區(qū)的工作。
Leader選舉的過程如下:
- 每個(gè)參與選舉的副本會(huì)嘗試向ZooKeeper上寫入一個(gè)臨時(shí)節(jié)點(diǎn),表示它們正在參與Leader選舉
- 所有寫入成功的副本會(huì)在ZooKeeper上創(chuàng)建一個(gè)序列號(hào)節(jié)點(diǎn),并將自己的節(jié)點(diǎn)序列號(hào)寫入該節(jié)點(diǎn)
- 節(jié)點(diǎn)序列號(hào)最小的副本會(huì)被選為新的Leader,并將自己的節(jié)點(diǎn)名稱寫入ZooKeeper上的/broker/…/leader節(jié)點(diǎn)中。
Controller選舉
Kafka集群中只能有一個(gè)Controller節(jié)點(diǎn),用于管理分區(qū)的副本分配、leader選舉等任務(wù)。當(dāng)一個(gè)Broker變成Controller后,會(huì)在Zookeeper的/controller節(jié)點(diǎn)中記錄下來。然后其他的Broker會(huì)實(shí)時(shí)監(jiān)聽這個(gè)節(jié)點(diǎn),主要就是避免當(dāng)這個(gè)controller宕機(jī)的話,就需要進(jìn)行重新選舉。
Controller選舉的過程如下:
- 所有可用的Broker向ZooKeeper注冊(cè)自己的ID。并監(jiān)聽Zookeeper中/controller節(jié)點(diǎn)的變化。
- 當(dāng)Controller節(jié)點(diǎn)出現(xiàn)故障時(shí),ZooKeeper會(huì)刪除/controller節(jié)點(diǎn),這時(shí)所有的Broker都會(huì)監(jiān)聽到該事件,并開始爭(zhēng)奪Controller的位置。為了避免出現(xiàn)多個(gè)Broker同時(shí)競(jìng)選Controller的情況,Kafka設(shè)計(jì)了一種基于ZooKeeper的Master-Slave機(jī)制,其中一個(gè)Broker成為Master,其它Broker成為為Slave。Master負(fù)責(zé)選舉Controller,并將選舉結(jié)果寫入ZooKeeper中,而Slave則監(jiān)聽/controller節(jié)點(diǎn)的變化,一旦發(fā)現(xiàn)Master發(fā)生故障,則開始爭(zhēng)奪Master的位置。
- 當(dāng)一個(gè)Broker發(fā)現(xiàn)Controller失效時(shí),它會(huì)向ZooKeeper寫入自自己的ID,并嘗試競(jìng)選Controller的位置。如果他創(chuàng)建臨時(shí)節(jié)點(diǎn)成功,則該Broker成為新的Controller,并將選舉結(jié)果寫入ZooKeeper中。
- 其它的Broker會(huì)監(jiān)聽到ZooKeeper中/controller節(jié)點(diǎn)的變化,一旦發(fā)現(xiàn)選舉結(jié)果發(fā)生變化,則更新自己的元數(shù)據(jù)信息,然后與新的Controller建立連接,進(jìn)行后續(xù)的操作。
高水位HW機(jī)制
高水位(HW,HighWatermark)是Kafka中的一個(gè)重要的概念,主要是用于管理消費(fèi)者的進(jìn)度和保證數(shù)據(jù)的可靠性的。
高水位標(biāo)識(shí)了一個(gè)特定的消息偏移量(offset),即一個(gè)分區(qū)中已提交(這里的已提交指的是ISR中的所有副本都記錄了這條消息)消息的最高偏移量(offset),消費(fèi)者只能拉取到這個(gè)offset之前的消息。消費(fèi)者可以通過跟蹤高水位來確定自己消費(fèi)的位置。
在Kafka中,HW主要有兩個(gè)作用:
- 消費(fèi)進(jìn)度管理:消費(fèi)者可以通過記錄上一次消費(fèi)的偏移量,然后將其與分區(qū)的高水位進(jìn)行比較,來確定自己的消費(fèi)進(jìn)度。消費(fèi)者可以在和高水位對(duì)比之后繼續(xù)消費(fèi)新的消息,確保不會(huì)錯(cuò)過任何已提交的消息。這樣,消費(fèi)者可以按照自己的節(jié)奏進(jìn)行消費(fèi),不受其他消費(fèi)者的響。
- 數(shù)據(jù)的可靠性:高水位還用于確保數(shù)據(jù)的可靠性。在Kafka中,只有消息被寫入主副本(Leader Replica)并被所有的同步副本(In-Sync Replicas,ISR)確認(rèn)后,才被認(rèn)為是是已提交的消息。高水位表示已經(jīng)被提交的消息的邊界。只有高水位之前的消息才能被認(rèn)為是已經(jīng)被確認(rèn)的,其他的消息可能會(huì)因?yàn)楦北竟收匣蚱渌蚨鴣G失。當(dāng)消費(fèi)者消費(fèi)消息,可以使用高水位作為參考點(diǎn),只消費(fèi)高水位之前的消息,以確保消費(fèi)的是已經(jīng)被確認(rèn)的消息,從而保證數(shù)據(jù)的可靠性。
還有一個(gè)概念,叫做LEO,即LogEnd Offset,,他是日志最后消息的偏移量。它標(biāo)識(shí)當(dāng)前日志文件中下一條待寫入消息的offset。
它有以下特點(diǎn)和作用:
- 用于表示副本寫入下一條消息的位置。
- 每個(gè)副本(包括 leader 副本和 follower 副本)都有自己的 LEO。
- LEO 的值會(huì)隨著消息的寫入而增加,每當(dāng)有新消息寫入底層日志成功時(shí),相應(yīng)副本的 LEO 就會(huì)加 1。
- LEO 主要用于跟蹤副本的同步進(jìn)度。
需要注意的是,在 0.11.0.0 版本之前,HW 的更新可能存在一些問題,例如在特定情況下可能導(dǎo)致消息丟失。0.11.0.0 及之后的版本使用 leader epoch,與 HW 值結(jié)合,從而更好地保證了數(shù)據(jù)的一致性和順序性。
- 每個(gè)分區(qū)都有一個(gè)初始的LeaderEpoch,通常為0。
- 當(dāng)Leader副本發(fā)生故障或需要進(jìn)行切換時(shí),Kafka會(huì)觸發(fā)副本切換過程。
- 副本切換過程中,Kafka會(huì)從ISR(In-Sync Replicas,同步副本)中選擇一個(gè)新的Follower副本作為新的Leader副本。
- 新的Leader副本會(huì)增加自己的Leader Epoch,使其大于之前的Leader Epoch。這表示進(jìn)入了一個(gè)新的任期。
- 新的Leader副本會(huì)驗(yàn)證舊Leader副本的狀態(tài)以確保數(shù)據(jù)的一致性。它會(huì)檢查舊Leader副本的Leader Epoch和高水位。
- 如果舊Leader副本的Leader Epoch小于等于新Leader副本的Leadder Epoch,并且舊Leader副本的高水位小于等于新Leader副本的高水位,則驗(yàn)證通過。
- 一旦驗(yàn)證通過,新的Leader副本會(huì)開始從ISR中的一部分副本中尋找最大的LEO副本進(jìn)行復(fù)制數(shù)據(jù),以確保新Leader上的數(shù)據(jù)與舊Leader-致。
- 一旦新的Leader副本復(fù)制了舊Leader副本的所有數(shù)據(jù),并達(dá)到了與舊Leader副本相同的高水位,副本切換過程就完成了。
通過使用Leader Epoch、高水位、LEO的驗(yàn)證,Kafka可以避免新的Leader副本接受舊Leader副本之后的消息,從而避免數(shù)據(jù)回滾和丟失。Leader Epoch 為 Kafka 提供了一種更可靠和一致的副本管理機(jī)制,確保了在 Leader 副本切換等情況下數(shù)據(jù)的完整性和正確性。