附註:

零停機地移轉 Kafka 和 Zookeeper 叢集

簡介

許多服務 (雲端原生或內部部署) 都使用 Kafka 叢集滿足其非同步訊息傳遞需求,因為它是可擴展的訊息傳遞技術。您可能因為業務需求而必須取代一組節點或整個叢集。本教學課程主要討論將 Kafka 和 Zookeeper 叢集移轉至一組新的節點,但不會發生停止工作的情形。

問題說明

為何要以另一個節點取代叢集中的節點會是一項挑戰?從負載平衡器背後的一組節點新增或移除節點是無所不在的:新增節點、清空要移除的現有節點、終止所有進行中的連線之後、將其關閉、將其自負載平衡器組態移除等等。

實際的挑戰在於使用應用程式進行狀態管理。通常,應用程式是無狀態的,並將狀態持續性委派給資料管理系統,例如關聯式資料庫管理系統 (RDBMS)。相對於這類應用程式,Kafka 和 Zookeeper 都會管理本機狀態,亦即使用本機磁碟進行狀態持續性。這表示,我們無法只將節點取代為另一個節點,而不需要處理現有節點的本機狀態。

此外,如果是 Kafka,只要新增節點,就不會自動開始任何工作負載重新平衡,也就是將主題分割區重新分配給中介。新節點只會參與從此時間點開始建立之新主題的工作負載共用。

仲裁型系統有一個作業問題 (在此情況下為 Zookeeper) 是需要事先知道叢集大小,這表示每個節點都必須具備叢集中所有其他節點的知識。此外,若要進一步複雜,如果您要一次新增一個以上的節點 (確實數目取決於現有的叢集大小),則必須確保其中一個新增的節點不會成為領導者,否則我們將會遺失資料。

目標

必要條件

移轉 Kafka 叢集

取代 Kafka 叢集中的節點相對簡單。新增中介並呼叫主題分割區移轉,一旦完成移轉,我們就可以將舊的中介淘汰。Kafka 提供 admin API 來執行分割區移轉。alterPartitionReassignments 的運作方式是將其他分割區複本新增至主題,等待複本成為 ISR 的成員,然後交換分割區引線。

您必須對舊的中介停用新的主題分割區指派 (如果應用程式邏輯在程式實際執行時建立主題),否則這會變成無止盡的移轉迴圈。為達到此目的,使用者可以使用不同主題建立 API 來指定分割區指派。下面列出可遵循的範例演算法。

後面可跟著簿記的移轉高階步驟 (當移轉程序在中間停止或失敗時重新啟動)。

  1. 已指定舊到新經紀人 ID 對應並完成宣告。

  2. 使用 AdminClient 檢查是否有可用的新中介。如果無法使用全部,請發出錯誤並終止。

  3. 使用 AdminClient 檢查主題 <kafka_topic_migration> 是否存在於叢集中。

    • 如果主題 <kafka_topic_migration> 不存在,請在新代理程式上手動指派複本來建立複本。此主題用於保留已重新指派的主題表示已移轉。
  4. 從一開始使用用戶閱讀主題 <kafka_topic_migration>。每個訊息都是已重新指派給新仲介的主題名稱。

  5. 使用 AdminClient 列出叢集中所有可用的主題。從這個清單中移除主題 <kafka_topic_migration>

  6. 從上述兩個步驟中,尋找要重新指派給新仲介的主題。

  7. 針對每個主題:

    1. 建立對應 Map<TopicPartition,Optional<NewPartitionReassignment>> reassignment = new HashMap<>();

    2. 使用 AdminClient,描述尋找其分割區的主題。

    3. 對於每個分割區:

      1. 將每個舊的複本 ID (舊的中介 ID) 取代為對應的新中介 ID,以準備 NewPartitionReassignment 物件。如果中介 ID 對應未包含與複本 ID 對應的索引鍵,請記錄警告並使用目前的 ID (最有可能的原因是此主題已經移轉,而我們錯過了簿記)。

      2. 新增此項目至對應。

    4. 使用 AdminClient 呼叫 alterPartitionReassignments 方法來起始重新指派。

    5. 執行迴圈來檢查此重新指派是否已完成,方法是列出進行重新指派 (listPartitionReassignments) 並檢查其大小為零。在每個迴圈之間睡眠 N 秒 。

    6. 驗證每個分割區的新複本是否與想要的複本相符。

    7. 將此主題名稱作為訊息推送至 <kafka_topic_migration> 主題。

  8. 重複步驟 4 到 6 (如果沒有其他主題可供重新指派及終止)。

移轉完成後,我們可以將舊的中介淘汰,並停用建立主題的自訂邏輯。

注意:停用舊代理程式之前,請確定此叢集的所有從屬端都已使用新代理程式更新 bootstrap.servers 組態。

移轉 Zookeeper 叢集

作為以仲裁為基礎的系統 (為了確認任何作業,我們至少需要投票數),且指定的領導者重選導致停止寫入作業,Zookeeper 移轉是最困難的部分。取代節點的方法有幾種。其中一個簡單的方法是執行整個叢集的多個輪流重新啟動,並在每一回合中新增節點。可能無法接受此方法,因為多回合的排行榜節點重新啟動,以及執行整體移轉的延遲。

注意:由於新節點在未同步所有資料 (導致資料遺失) 的風險下,無法一次新增所有新節點 (作為參與者)。

請勿在與參與者相同的初始組態中,指定多個聯結伺服器。目前,結合伺服器不知道它們正在加入現有的組譯器,如果多個結合器列為參與者,則它們可能會形成獨立的法定量子,建立分割單元 (例如獨立於主要組譯的處理作業)。您可以在初始組態中將多個結合器列為觀察者。

3.5.0 以上的 Zookeeper 版本中,我們支援 Zookeeper 的動態重新組態設定。reconfigEnabled 旗標應設為 true,動態重新配置才能運作。如需詳細資訊,請參閱ZooKeeper Ensemble 的動態重新配置

您可以新增節點,以角色 Observer 組合成上一個確認組態中伺服器之結合器的初始組態。例如,如果同時新增伺服器 4 和伺服器 5 至 (1、2、3),則初始組態 4 將會是 (1、2、3、4、5),其中 4 和 5 會列為觀察者。同樣地,5 的組態也會是 (1、2、3、4、5),其中 4 和 5 會列為觀察者。

備註:以觀察者身分列出加入者不會真正讓他們觀察者 - 它只會防止他們不小心與其他加入者建立法定。他們會改為聯絡目前組態中的伺服器,並採用沒有結合者的最後確認組態 (1、2、3)。連線至目前的領導者之後,加入者會成為無投票權的追隨者,直到系統重新設定並加入至組譯 (視需要加入參與者或觀察者)。

所有節點都已啟動並在執行中之後,系統會呼叫重新設定 API ,以動態方式將新節點新增為參與者,並從組譯中移除舊節點。例如,使用 CLI。

reconfig -remove 1,2,3 -add
server.5=hostA:2111:2112;2113,6=hostB:2111:2112:participant;2113,7=
hostC:2111:2112:participant;2113*

在此步驟之後,舊節點便可停用。

注意:

認可

其他學習資源

瀏覽 docs.oracle.com/learn 的其他實驗室,或前往 Oracle Learning YouTube 頻道存取更多免費學習內容。此外,請造訪 education.oracle.com/learning-explorer 以成為 Oracle Learning Explorer。

如需產品文件,請造訪 Oracle Help Center