Kafka相關知識點

簡介

Kafka是一個分佈式、分區的、多副本的、多訂閱者,基於zookeeper協調的分佈式日誌系統(也可以當做消息隊列系統),常見可以用於web/nginx日誌、訪問日誌,消息服務等等。

根據官網的介紹,ApacheKafka®是一個分佈式流媒體平臺,它主要有3種功能:

  1:發佈和訂閱消息流。這個功能類似於消息隊列,這也是kafka歸類爲消息隊列框架的原因

  2:以容錯的方式保存消息流。kafka以文件的方式來存儲消息流

  3:在消息發佈的時候可以進行處理。

主要應用的場景有兩個:

      1:構建可在系統或應用程序之間可靠獲取數據的實時流數據管道。     消息隊列系統

      2:構建轉換或響應數據流的實時流應用程序。   日誌收集系統

Kafka術語介紹

broker

Kafka 集羣包含一個或多個kafka服務器,每個kafka服務器節點稱爲broker。

broker存儲topic的數據。如果某topic有N個partition,集羣有N個broker,那麼每個broker存儲應該該topic的一個partition。

如果某topic有N個partition,集羣有(N+M)個broker,那麼其中有N個broker存儲該topic的一個partition,剩下的M個broker不存儲該topic的partition數據。

如果某topic有N個partition,集羣中broker數目少於N個,那麼一個broker存儲該topic的一個或多個partition。在實際生產環境中,儘量避免這種情況的發生,這種情況容易導致Kafka集羣數據不均衡。

topic

每條發佈到Kafka集羣的消息都有一個類別,這個類別被稱爲Topic。物理上不同Topic的消息分開存儲,對於相同的topic,也可以根據需要分爲多個partition存儲,而一個partition物理上對應一個文件夾,而partition也會根據需要存儲在不同的broker上,因此一個Topic的消息可能會保存於一個或多個broker上,但用戶在生產或消費消息的時候只需要指定對應的topic。

partition

topic中的數據可以分爲一個或多個partition存儲。每個partition在物理存儲層面對應的是不同的文件夾,而這些文件夾中存放着多個log file(稱爲segment)。每個partition還可以根據配置生成多個副本,當然副本的數量自然也應該不大於kafka集羣中broker的數量。當然kafka會爲topic的每個partition在副本中選出一個leader,之後所有該partition的請求,實際操作的都是leader,然後再同步到其他的follower。當一個broker歇菜後,所有leader在該broker上的partition都會重新選舉,選出一個leader。(這裏不像分佈式文件存儲系統那樣會自動進行復制保持副本數)

leader

每個partition有多個副本,其中有且僅有一個作爲leader,leader是當前負責數據的讀寫的partition。

follower

follower跟隨leader,所有寫請求都通過leader路由,follower主動從leader拉取數據,follower與leader保持數據同步。如果leader失效,則從follower中選舉出一個新的leader。當follower與leader掛掉、卡住或者同步太慢,leader會把這個follower從“in sync replicas”(ISR)列表中刪除,重新創建一個lollower。

producer

生產者即數據的發佈者,該角色將消息發佈到Kafka的topic中。broker接收到生產者發送的消息後,broker將該消息追加到當前用於追加數據的segment文件中。生產者發送的消息,存儲到一個partition中,生產者也可以指定數據存儲的partition。

comsumer

消費者可以從broker中讀取數據。消費者可以消費多個topic中的數據。

comsumer group

每個Consumer屬於一個特定的Consumer Group(可爲每個Consumer指定group name,若不指定group name則屬於默認的group)。

 

kafka生產流程

kafka數據基本流向圖

數據流向

上圖中有兩個生產者producer用於產生消息,產生的消息在存入kafka集羣后,由集羣分別發佈給訂閱的3個消費者組,每個消費者組中分別有1個或多個消費者,在kafka集羣中有3個broker節點,每個節點中有topic_01和topic_02兩種主題的消息,topic_01主題中又分爲了兩個partition,每個partition都共有3個副本集,topic_02主題有一個partition,該partition都也有3個副本集,其中一個是leader,其餘兩個是follower用於保證了良好的容災。

Topic

kafka中主題是發佈記錄的類別或訂閱源名稱。可以簡單的將同一個topic的消息理解爲同一類消息。每個topic被分爲指定數量的partition(區)提高kafka的吞吐量。每個partition實際上在磁盤上對應一個文件夾,這個文件夾中存放着該partition的所有消息和索引文件。kafka在接收到生產者發送的消息之後,會根據均衡策略將消息存儲到不同的分區中。

每個partition在存儲層面是append log文件。任何發佈到此partition的消息都會被直接追加到log文件的尾部,每條消息在文件中的位置稱爲offset(偏移量),offset爲一個long型數字,它是唯一標記一條消息。

每個消費者保留的唯一元數據是該消費者在日誌中的偏移或位置。這種偏移由消費者控制:通常消費者在讀取記錄時會線性地提高其偏移量,但事實上,由於消費者控制位置,它可以按照自己喜歡的任何順序消費記錄。例如,消費者可以重置爲較舊的偏移量以重新處理過去的數據,或者跳到最近的記錄並從“現在”開始消費。

Kafka默認將offset保存在kafka(0.9之前是保存在zookeeper中)。具體的方法就是把offset提交,跟隨具體消息一期保存在log文件中。可以從下圖看出,具體log文件中存儲的數據是什麼樣的。

partition

kafka中的partition分佈在集羣服務器上,每個partition根據配置生成響應數量的副本(副本數量需要小於broker的數量),用於實現容錯。

topic具體partition都有對應的leader和follower,leader處理數據的讀寫,follower被動的同步數據,當leader掛掉後,其中的一個follower會成爲新的leader。在kafka的集羣中,partition的leader和follower會均衡的分佈到不同的broker中,這樣保證了集羣的負載平衡。

關於數據保存的策略

  • kafka提供基於時間的策略刪除消息數據,在kafka的配置文件中對應參數爲:log.retention.hours,例如,如果保留策略設置爲兩天,則在發佈記錄後的兩天內,它可供使用,之後將被丟棄以釋放空間。
  • kafka還提供基於partition的log文件大小刪除舊消息數據的策略,在kafka的配置文件中對應參數爲:log.segment.bytes,例如可以配置Partition文件超過1GB時刪除舊數據。

producer

生產者負責將消息發送給指定的topic,生產者也可以指定具體發送給topic的哪一個partition。

consumer

消費者訂閱topic是以消費者組訂閱的,同一個消費者組裏可能有多個消費者,但是同一個消費者組裏的不同消費者不能同時消費一個partition的消息,也就是說,一個partition裏的消息,只能被消費者組裏的一個消費者獲取,可以被多個消費者組訂閱。

消費者

當一個消費者組中新增了一個消費者實例時,該實例將從組中其他消費者接管一些分區,當一個消費者組中一個實例死亡時,該實例接管的分區會重新分配給該消費者組中的其他實例。

Reblance機制介紹:

Reblance本質上是一種協議,規定了一個Consumer Group下的所有的Consumer如何達成一致來分配訂閱Topic的每個Partition。比如某個group下有2個consumer,它訂閱了一個具有10個分區的topic。正常情況下,Kafka平均會爲每個consumer分配5個分區。

進行reblance的情況:

  • 有新的consumer加入
  • 舊的consumer掛了
  • coordinator掛了,集羣選舉出新的coordinator
  • topic的partition新加
  • consumer調用unsubscrible(),取消topic的訂閱

kafka消息傳送

kakfa消息傳送過程中可能存在的情況

  • At most once:最多一次,消息可能會丟失,但不會重複
  • At least once:最少一次,消息不會丟失,可能會重複
  • Exactly once:只且一次,消息不丟失不重複,只且消費一次(0.11中實現,僅限於下游也是kafka)

at most once: 消費者fetch消息,然後保存offset,然後處理消息;當client保存offset之後,但是在消息處理過程中出現了異常,導致部分消息未能繼續處理.那麼此後"未處理"的消息將不能被fetch到,這就是"at most once".

at least once: 消費者fetch消息,然後處理消息,然後保存offset.如果消息處理成功之後,但是在保存offset階段發生異常導致保存操作未能執行成功,這就導致接下來再次fetch時可能獲得上次已經處理過的消息,這就是"at least once"。這篇博文介紹了常見的重複消費的情況。其實在保存offset階段,如果發生rebalance,導致已經消費消息但是offset保存失敗,就會導致重複消費的情況。

exactly once: kafka中並沒有嚴格的去實現(基於2階段提交,事務),我們認爲這種策略在kafka中是沒有必要的.

通常情況下"at-least-once"是我們首選.(相比at most once而言,重複接收數據總比丟失數據要好).

kafka消息傳送過程中的生產者

生產者配置中"acks"指定了必須有多少個分區副本接收到了消息,生產者纔會認爲消息是發送成功的

通過配置acks不同的值來設置生產者ACK具體採用哪一種機制。生產者ACK共有下面三種機制:

acks=0:消息發送完畢即offset增加,生產者繼續發送可以繼續發送消息。這意味着生產者producer不等待來自broker同步完成的確認繼續發送下一條(批)消息。此選項提供最低的延遲但最弱的耐久性保證(當服務器發生故障時某些數據會丟失,如leader已死,但producer並不知情,發出去的信息broker就收不到)。對應At most once。

acks=1:集羣的leader收到了消息,生產者將會受到發送成功的一個響應,然後纔可以發送下一條消息。如果消息無撞到達leader節點(比如leader節點崩憤,新的首領還沒有被選舉出來),生產者會收到一個錯誤響應,爲了避免數據丟失,生產者會重發消息。不過,如果Leader剛剛接收到消息,Follower還沒來得及同步過去,結果Leader所在的broker宕機了,此時也會導致這條消息丟失。

acks=-1(all):所有參與複製的節點全部收到消息的時候,生產者纔會收到來自服務器的一個響應,這種模式最安全,但是吞吐量受限制,它可以保證不止一個服務器收到消息,就算某臺服務器奔潰,那麼整個集羣還是會正產運轉。對應At least once。

三種機制,性能依次遞減 (producer吞吐量降低),數據健壯性則依次遞增。

在acks的基礎上吞吐量還取決於使用的是同步發送還是異步發送。當消息發送成功或失敗後,同步發送是通過調用Future 對象的get()方法,讓發送客戶端等待服務器的響應,這樣的做法顯然會增加延遲問題(阻塞)(在網絡上傳輸一個來回的延遲)。異步發送是客戶端使用回調函數,延遲(阻塞)問題就可以得到緩解,不過吞吐量還是會受發送中消息數量的限制(比如,生產者在收到服務器響應之前可以發送多少個消息)。對應At least once。

高可用性配置

要保證數據寫入到Kafka是安全的,高可用的,需要如下的配置:

  • topic的配置:offsets.topic.replication.factor>=3,即副本數至少是3個;
  • broker的配置:leader的選舉條件unclean.leader.election.enable=true(默認爲false),此參數標識當ISR中沒有副本時,是否可以選舉OSR( Out-of-sync Replicas)中的副本(不推薦,會造成數據丟失)。
  • producer的配置:acks=all,並且生產者發送消息必須同步發送,即需要調用send()方法返回的Future對象的get()方法

kafka高可用設計解析

爲何需要給partition設置副本

  在Kafka在0.8以前的版本中,是沒有Replication的,一旦某一個Broker宕機,則其上所有的Partition數據都不可被消費,這與Kafka數據持久性及Delivery Guarantee的設計目標相悖。同時Producer都不能再將數據存於這些Partition中。

        在沒有Replication的情況下,一旦某機器宕機或者某個Broker停止工作則會造成整個系統的可用性降低。隨着集羣規模的增加,整個集羣中出現該類異常的機率大大增加,因此對於生產系統而言Replication機制的引入非常重要。

爲什麼Partition副本需要leader

  引入Replication之後,同一個Partition可能會有多個Replica,而這時需要在這些Replication之間選出一個Leader,Producer和Consumer只與這個Leader交互,其它Replica作爲Follower從Leader中複製數據。

  因爲需要保證同一個Partition的多個Replica之間的數據一致性(其中一個宕機後其它Replica必須要能繼續服務並且即不能造成數據重複也不能造成數據丟失)。如果沒有一個Leader,所有Replica都可同時讀/寫數據,那就需要保證多個Replica之間互相(N×N條通路)同步數據,數據的一致性和有序性非常難保證,大大增加了Replication實現的複雜性,同時也增加了出現異常的機率。而引入Leader後,只有Leader負責數據讀寫,Follower只從Leader順序Fetch數據(N條通路),系統更加簡單且高效。

如何將partition均勻的分佈到kafka的集羣中

爲了更好的做負載均衡,Kafka儘量將所有的Partition均勻分配到整個集羣上。一個典型的部署方式是一個Topic的Partition數量大於Broker的數量。同時爲了提高Kafka的容錯能力,也需要將同一個Partition的Replica儘量分散到不同的機器。實際上,如果所有的Replica都在同一個Broker上,那一旦該Broker宕機,該Partition的所有Replica都無法工作,也就達不到HA的效果。同時,如果某個Broker宕機了,需要保證它上面的負載可以被均勻的分配到其它倖存的所有Broker上。

Kafka分配Replica的算法如下:

1.將所有Broker(假設共n個Broker)和待分配的Partition排序

2.將第i個Partition分配到第(i mod n)個Broker上

3.將第i個Partition的第j個Replica分配到第((i + j) mode n)個Broker上

HW與leader epoch(0.11.0.0版本後採用leader epoch)

這篇文章介紹得很清楚https://www.cnblogs.com/warehouse/p/9545429.html

kafka副本同步機制

版本0.9及以後的Kafka只使用一個參數來確定滯後副本(lagging replica),而不再使用replica.lag.max.messages參數。這是因爲什麼原因呢?

  在詳細解釋此事之前我們先明確一些公共的術語以方便後續的討論:

  • ISR:in-sync replicas。與leader副本保持同步狀態的副本集合(leader副本本身也在ISR中)。
  • OSR:Out-of-sync Replicas, 與Leader 滯後過多的副本,如何判斷滯後,請參考之前的ISR.
  • AR: Assigned Replicas,分區中所有的副本都稱爲 AR,即AR=ISR+OSR
  • High Watermark:副本高水位值,簡稱HW,它表示該分區最新一條已提交消息(committed message)的位移
  • LEO:log end offset。從名字上來看似乎是日誌結束位移,但其實是下一條消息的位移,即追加寫下一條消息的位移

  值得一提的,HW表示的是最新一條已提交消息的位移。注意這裏是已提交的,說明這條消息已經完全備份過了(fully replicated),而LEO可能會比HW值大——因爲對於分區的leader副本而言,它的日誌隨時會被追加寫入新消息,而這些新消息很可能還沒有被完全複製到其他follower副本上,所以LEO值可能會比HW值大。兩者的關係可參考下圖:

消費者只能消費到HW線以下的消息;而未完全備份的消息不能被消費者消費。

  明白了這些術語之後,還有個問題需要研究下: follower部分與leader副本不同步,這是什麼意思?不同步(out of sync)意味着follower副本無法追上leader副本的LEO,而這又是什麼意思呢?我們舉個簡單的例子來說明。設想我們有一個topic,它只有一個分區,備份因子是3。假設這三個副本分別保存在broker1,broker2和broker3上。leader副本在broker1上,其他兩個broker上的副本都是follower副本,且當前所有的副本都在ISR中。現在我們設置replica.lag.max.messages等於4——表示只要follower副本落後leader副本的消息數小於4,該follower副本就不會被踢出ISR。如果此時有個producer程序每次給這個topic發送3條消息,那麼初始狀態如下:

很顯然,目前2個follower副本與leader副本是同步的,即它們都能追上leader副本的LEO。假設此時producer生產了1條新消息給leader副本,而同時broker3上的follower副本經歷了一次Full GC,那麼現在的日誌狀態如下圖:

從上圖可以發現,leader副本的HW值和LEO值已然變得不一樣了。不過更重要的是,最新生產的這條消息是不會被視爲“已提交”的,除非broker3被踢出ISR或者broker3上的follower副本追上了leader的LEO。由於replica.lag.max.messages=4,而broker3上的follower副本也只是落後leader副本1條消息,所以此時broker3上的副本並不滿足條件因而也不會被踢出ISR。對於broker3上的副本而言,事情變得相當簡單——只需追上leader的LEO即可。如果我們假設broker3因爲Full GC停頓了100ms之後追上了leader的進度,那麼此時的日誌狀態應該如下圖所示:

 此時一切都很完美了,leader的HW值與LEO值相同;2個follower副本都與leader副本是同步的。

   那麼有什麼可能的原因會使得follower副本與leader副本不同步呢?歸納起來有三種原因:

  • 速度跟不上——follower副本在一段時間內都沒法追上leader副本的消息寫入速度,比如follower副本所在broker的網絡IO開銷過大導致備份消息的速度慢於從leader處獲取消息的速度
  • 進程卡住了——follower副本在一段時間內根本就沒有向leader副本發起FetchRequest請求(該請求就是獲取消息數據),比如太過頻繁的GC或其他失敗導致
  • 新創建的——如果用戶增加了備份因子,很顯然新follower副本在啓動過程初始肯定是全力追趕leader副本,因而與其是不同步的

  replica.lag.max.messags參數就是用於檢測第一種情況的。當然Kafka還提供了一個參數 replica.lag.time.max.ms來檢測另外兩種情況。比如如果設置 replica.lag.time.max.ms=500ms,只要follower副本每隔500ms都能發送FetchRequest請求給leader,那麼該副本就不會被標記成dead從而被踢出ISR。

  由於本文重點關注replica.lag.max.messages參數,那麼我們來說一下Kafka檢測第一種情況會碰到的問題。回到之前提到的那個例子,如果producer一次性發送消息的速率是2條/秒,即一個batch都有2條消息,那麼顯然設置replica.lag.max.messages=4是個相當安全且合適的數值。爲什麼? 因爲在leader副本接收到producer發送過來的消息之後而follower副本開始備份這些消息之前,follower副本落後leader的消息數不會超過3條消息。但如果follower副本落後leader的消息數超過了3條,那麼你肯定希望leader把這個特別慢的follower副本踢出ISR以防止增加producer消息生產的延時。從這個簡單的例子上來看,這個參數似乎工作得很好,爲什麼要移除它呢?根本原因在於如果要正確設置這個參數的值,需要用戶結合具體使用場景自己去評估——基於這個原因,新版本Kafka把這個參數移除了。

  好了,我來詳細解釋一下這個根本原因。首先,對於一個參數的設置,有一點是很重要的:用戶應該對他們知道的參數進行設置,而不是對他們需要進行猜測的參數進行設置。對於該參數來說,我們只能去猜它應該設置成哪些值,而不是根據我們的需要對其進行設置。爲什麼?舉個例子,假設在剛纔那個topic的環境中producer程序突然發起了一波消息生產的瞬時高峯流量增加,比如producer現在一次性發送4條消息過來了,也就是說與replica.lag.max.messages值相等了。此時,這兩個follower副本都會被認爲是與leader副本不同步了,從而被踢出ISR,具體日誌狀態如下圖所示:

   從上圖看,這兩個follower副本與leader不再同步,但其實他們都是存活狀態(alive)的且沒有任何性能問題。那麼在下次FetchRequest時它們就能追上leader的LEO,並重新被加入ISR——於是就出現了這樣的情況:它們不斷地被踢出ISR然後重新加回ISR,造成了與leader不同步、再同步、又不同步、再次同步的情況發生。想想就知道這是多大的開銷!問題的關鍵就在replica.lag.max.messages這個參數上。用戶通過猜測設置該值,猜測producer的速度,猜測leader副本的入站流量。

  可能有用戶會說該參數默認值是4000,應該足夠使用了吧。但有一點需要注意的是,這個參數是全局的!即所有topic都受到這個參數的影響。假設集羣中有兩個topic: t1和t2。假設它們的流量差異非常巨大,t1的消息生產者一次性生產5000條消息,直接就突破了4000這個默認值;而另一個topic,t2,它的消息生產者一次性生產10條消息,那麼Kafka就需要相當長的時間才能辨別出t2各個分區中那些滯後的副本。很顯然這種流量差異巨大的topic很容易地在同一個集羣上部署,那麼這種情況下replica.lag.max.messages參數應該設置什麼值呢? 顯然沒有合適的值,對吧?

  綜上所述,新版本的Kafka去除了這個參數,改爲只使用一個參數就能夠同時檢測由於slow以及由於進程卡殼而導致的滯後(lagging)——即follower副本落後leader副本的時間間隔。這個唯一的參數就是replica.lag.time.max.ms,默認是10秒。對於第2,3種不同步原因而言,該參數沒有什麼具體的變化。但是對於第一種情況,檢測機制有了一些微調——如果一個follower副本落後leader的時間持續性地超過了這個閾值,那麼這個副本就要被標記爲dead從而被踢出ISR。這樣即使出現剛剛提到的producer瞬時峯值流量,只要follower沒有持續性地落後,它就不會反覆地在ISR中移進移出。

kafka節點控制器選舉

  1. 先獲取 zk 的 /cotroller 節點的信息,獲取 controller 的 broker id,如果該節點不存在(比如集羣剛創建時),那麼獲取的 controller id 爲-1;
  2. 如果 controller id 不爲-1,即 controller 已經存在,直接結束流程;
  3. 如果 controller id 爲-1,證明 controller 還不存在,這時候當前 broker 開始在 zk 註冊 controller;
  4. 如果註冊成功,那麼當前 broker 就成爲了 controller,這時候開始調用 onBecomingLeader() 方法,正式初始化 controller(注意: controller 節點是臨時節點 ,如果當前 controller 與 zk 的 session 斷開,那麼 controller 的臨時節點會消失,會觸發 controller 的重新選舉);
  5. 如果註冊失敗(剛好 controller 被其他 broker 創建了、拋出異常等),那麼直接返回。

在這裏 controller 算是成功被選舉出來了,controller 選舉過程實際上就是各個 broker 搶佔式註冊該節點,註冊成功的便爲 Controller。

kafka分區leader選舉

Kafka通過leaderSelector完成leader的選舉。

可能觸發爲partition選舉leader的場景有: 新創建topic,broker啓動,broker停止,controller選舉,客戶端觸發,reblance等等 場景。在不同的場景下選舉方法不盡相同。Kafka提供了幾種leader選舉方式,說明:

OfflinePartitionLeaderElectionStrategy

觸發場景:
    * 當創建分區(創建主題或增加分區都有創建分區的動作)或分區上線(比如分區中原先的leader副本下線,此時分區需要選舉一個新的leader上線來對外提供服務)的時候都需要執行leader的選舉動作。
選舉有兩種情況:
    1.AR列表中找到第一個存活的副本,且這個副本在目前的ISR列表中,unclean.leader.election.enable=false。
    2.AR列表中找到第一個存活的副本,這個副本可以不在的ISR列表中而在OSR列表中,unclean.leader.election.enable=true。

ControlledShutdownPartitionLeaderElectionStrategy,當某節點被優雅的關閉時 (執行 ControlledShutdown) ,該節點的副本都會下線,於此對應的分區需要執行 Leader 選舉。

觸發場景:
    * kafka的broker進程退出,發送消息給controller,controller觸發
選舉:
    * 在ISR列表中的選出存活的replica,還要確保這個副本不處於正在被關閉的節點上。否則拋出異常

PreferredReplicaPartitionLeaderElectionStrategy

觸發場景:
    * znode節點/admin/preferred_replica_election寫入相關數據
    * partition-rebalance-thread線程進行觸發reblance時
    * 新產生controller
選舉 :
    1) AR中取出一個作爲leader,如果與原有leader一樣,拋出異常
    2) 新leader的replica的broker存活且replica在ISR中,選出,否則拋出異常

ReassignPartitionLeaderElectionStrategy

觸發場景:
    * znode節點LeaderAndIsr發生變化
    * Broker啓動時
    * zknode節點/admin/reassign_partitions變動
    * 新產生controller時
選舉:
    * 新設置的AR中,存在broker存活的replica且replica在ISR中則選出爲leader,否則拋出異常

在所有的leader選舉策略中,如果符合條件的replica有多個,如Seq[int],則使用的是Seq.head,取的是seq的第一個。

消費者組中的選舉

類似broker中選了一個controller出來,消費也要從broker中選一個coordinator,用於分配partition。

組協調器GroupCoordinator需要爲消費組內的消費者選舉出一個消費組的coordinator,這個選舉的算法也很簡單,分兩種情況分析:

  1. 如果消費組內還沒有leader,那麼第一個加入消費組的消費者即爲消費組的leader。
  2. 如果某一時刻leader消費者由於某些原因退出了消費組,那麼會重新選舉一個新的leader,這個重新選舉leader的過程又更“隨意”了,在GroupCoordinator中消費者的信息是以HashMap的形式存儲的,其中key爲消費者的member_id,而value是消費者相關的元數據信息。leaderId表示leader消費者的member_id,它的取值爲HashMap中的第一個鍵值對的key,這種選舉的方式基本上和隨機無異。總體上來說,消費組的leader選舉過程是很隨意的。

關於kafka的各種問題

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章