深入理解Kafka核心設計及原理(四):主題管理

香吧香發表於2022-04-09

轉載請註明出處:https://www.cnblogs.com/zjdxr-up/p/16124354.html

目錄:

  4.1建立主題

  4.2 優先副本的選舉

  4.3 分割槽重分配

  4.4 如何選擇合適的分割槽

  4.5分割槽數越多吞吐量也越高?

4.1建立主題

    如果 broker 端配置引數 auto .create.topics .enable 設定為 true (預設值就是 true) ,那麼當生產者向一個尚未建立的主題傳送訊息時,會自動建立一個分割槽數為 num . partitions(預設值為1 )、副本因子為 default.repl 工 cation.factor (預設值為1 )的主題。除此之外,當一個消費者開始從未知主題中讀取訊息時,或者當任意一個客戶端向未知主題傳送後設資料請求時,都會按照配置引數 num.partitions 和 default.replicatio口 .factor 的值來建立一個相應的主題。很多時候,這種自動建立主題的行為都是非預期的。除非有特殊應用需求,否則不建議將 auto.create.topics. enable 引數設定為 true,這個引數會增加主題的管理與維護的難度。

    通過命令建立主題

bin/kafka-topics.sh --zookeeper localhost:2181/kafka --create --topic topic-create --partitions 4 --replication-factor 2

    建立了一個分割槽數為 4 、 副本因子為 2 的主題;在執行完指令碼之後,Kafka 會在 log.dir 或 log.dirs 引數所配置的目錄下建立相應的主題分割槽,預設情況下這個目錄為/tmp/kafka-logs/

                                         

  生產者的分割槽分配是指為每條訊息指定其所要發往的分割槽,消費者中的分割槽分配是指為消費者指定其可以消費訊息的分割槽

#檢視指定主題
bin/kafka-topics.sh --zookeeper localhost:2181/kafka --describe --topic topic-create-zk

#檢視當前所有可用主題
bin/kafka-topics.sh --zookeeper localhost:2181/kafka -list

#刪除主題
bin/kafka-topics.sh --zookeeper localhost:2181/kafka --delete --topic topic-delete

#增加主題分割槽
bin/kafka-topics.sh --zookeeper localhost:2181/kafka --alter --topic topic-config --partitions 3

                 

4.2 優先副本的選舉

    隨著時間的更替, Kafka叢集的broker節點不可避免地會遇到當機或崩潰的問題, 當 分割槽的leader節點發生故障時, 其中 一個follower節點就會成為新的leader節點, 這樣就會導致叢集的負載不均衡, 從而影響整體的健壯性和穩定性。

    為了能夠有效地治理負載失衡的情況,Kafka引入了優先副本(preferred replica)的概念。所謂的優先副本 是指在 AR 集合列表中的第 一個副本 。 比如上面 主題 topic-partitions中 分割槽 0的AR集合列表(Replicas)為[1,2,0], 那麼分割槽0 的優先副本即為1。 理想情況下,優先副本就是該分割槽的leader副本, 所以也可以稱之為 preferred leader。Kafka要確保所有主題的優先副本在Kafka叢集中均勻分佈, 這樣就保證了所有分割槽的leader均衡 分佈。 如果leader 分佈過於集中, 就會造成叢集 負載不均衡。 所謂的優先副本的選舉 是指通過一定的方式促使優先副本 選舉為 leader副本, 以此來促進叢集的負載均衡, 這 一行為也可以稱為“ 分割槽平衡” 。

    在Kafka中可以提供分割槽自動平衡的功能, 與此對應的broker端引數是auto.leader.rebalance.enable,此引數的預設值為true, 即預設情況下此 功能是開啟的。如果開啟分割槽自動平衡的功能,則Kafka的控制器會啟動一個定時任務, 這個定時任務會輪詢所有的broker節點, 計算每個broker節點的分割槽不平衡率(broker中的不平衡率=非優先副本的leader個數/分割槽總數)是否超過leader.imbalance.per.broker.percentage引數配置的比值,預設值為10%,如果超過設定的比值則會自動執行優先副本的選舉動作以求分割槽平衡。執行週期由引數leader.imbalance.check.interval.seconds控制,預設值為300秒,即5分鐘。

    不過在生產環境中不建議將auto.leader.rebalance.enable 設定為預設的true,因為這 可能引起負面的效能問題, 也有可能引起客戶端 一 定時間的阻塞。 因為執行的時間無法自主掌控,如果在關鍵時期(比如電商大促波峰期)執行關鍵任務的關卡上執行優先副本的自動選舉操作, 勢必會有業務阻塞、 頻繁超時之類的風險。 前面也分析過, 分割槽及副本的均衡也不能完全確保叢集整體的均衡,並且叢集中一 定程度上的不均衡也是可以忍受的, 為防止出現關鍵時期“ 掉鏈子”的行為.

    Kafka中kafka-perferred-replica-election.sh指令碼提供了對分割槽leader副本進行重新平衡的功能。

bin/kafka-preferred-replica-election. sh --zookeeper localhost:2181/kafka

4.3 分割槽重分配

    當要對叢集中的一個節點進行有計劃的下線操作時, 為了保證分割槽及副本的合理分配, 我們也希望通過某種方式能夠將該節點上的分割槽副本遷移到其他的可用節點上。當叢集中新增broker節點時, 只有新建立的主題分割槽才有可能被分配到這個節點上, 而之前的主題分割槽並不會自動分配到新加入的節點中, 因為在它們被建立時還沒有這個新節點, 這樣新節點的負載和原先節點的負載之間嚴重不均衡。 為了解決上述問題,需要讓分割槽副本再次進行合理的分配,也就是所謂的分割槽重分配Kafka提供了kafka-reassign-partitions.sh指令碼來執行分割槽重分配的工作, 它可以在叢集擴容、broker節點失效的場景下對分割槽進行遷移。

    kafka-reassign-partitions.sh指令碼的使用分為3 個步驟:首先建立需要 一 個包含主題清單的JSON檔案, 其次根據主題清單和broker節點清單生成 一 份重分配方案,最後根據這份方案執行具體的重分配動作。

    分割槽重分配的基本原理是先通過控制器為每個分割槽新增新副本(增加副本因子 ) ,新的副本將從分割槽的leader副本那裡複製所有的資料。 根據分割槽的大小不同, 複製過程可能需要花一些時間, 因為資料是通過網路複製到新副本上的。在複製完成之後, 控制器將舊副本從副本清單裡移除(恢復為原先的副本因子數)。 注意在重分配的過程中要確保有足夠的空間。

    分割槽重分配本質在於資料複製,先增加新的副本,然後進行資料同步,最後刪除舊的副本來達到最終的目的。 資料複製會佔用額外的資源, 如果重分配的量太大必然會嚴重影響整體的效能, 尤其是處於業務高峰期的時候。 減小重分配的粒度, 以小批次的方式來操作是一種可行的解決思路。

    如果叢集中某個主題或某個分割槽的流量在某段時間內特別大, 那麼只靠減小粒度是不足以應對的, 這時就需要有一個限流的機制, 可以對副本間的複製流量加以限制來保證重分配期間整體服務不會受太大的影響 。副本間的複製限流有兩種實現方式:kafka- config.sh指令碼和kafka-reassign- partitions.sh指令碼 。

4.4 如何選擇合適的分割槽

    在 Kafka 中 ,效能與分割槽數有著必然的關係,在設定分割槽數時一般也需要考慮效能的因素。對不同的硬體而言,其對應的效能也會不太一樣。

    在實際生產環境中,我們需要了解一套硬體所對應的效能指標之後才能分配其合適的應用和負荷,所以效能測試工具必不可少。Kafka 本身提供的用於生產者效能測試的kafka-producer­-perftest.sh 和用於消費者效能測試的 kafka-consumer-perf-test. sh 。

    向一個只有1個分割槽和1個副本的主題 topic-1 中傳送 100 萬條訊息,並且每條訊息大小為 1024B ,生產者對應的 acks 引數為 l;

bin/kafka-producer-perf-test.sh --topic topic-1 --num-records 1000000 --record-size 1024 --throughput 一1 --producer-props bootstrap.servers=localhost:9092 acks=l

    簡單地消費主題topic-I中的100萬條訊息

bin/kafka-consumer-perf-test. sh --topic topic-1 --messages 1000000 --broker-list localhost:9092

4.5分割槽數越多吞吐量也越高?

    針對分割槽數越多吞吐量越高這個命題進行反證, 其實要證明一個觀點是錯誤的, 只需要舉個反例即可, 本節的內容亦是如此 。不過本節並沒有指明分割槽數越多吞吐量就越低這個觀點, 並且具體吞吐量的數值和走勢還會和磁碟、 檔案系統、1/0排程策略相關。分割槽數越多吞吐量 也就越高?網路上很多資料都認可這 一觀點 , 但實際上很多事情都會有一個臨界值, 當超過這個臨界值之後, 很多原本符合既定邏輯的走向又會變得不同。讀者需要對此有清晰的認知,懂得去偽求真, 實地測試驗證不失為一座通向真知的橋樑。

    一味地增加分割槽數並不能使吞吐量 一直得到提升, 並且分割槽數也並不能一直增加, 如果超過預設的配置值, 還會引起 Kafka程式的崩潰。

    當然分割槽數也不能一味地增加, 分割槽數會佔用檔案描述符(即一個檔案下可建立的子檔案數量預設為1024,超過預設值則會報 open too many files), 而一個程式所能支配的檔案描述符是有限的, 這也是通常所說的檔案控制程式碼的開銷。 雖然我們可以通過修改配置來增加可用檔案描述符的個數, 但凡事總有一個上限, 在選擇合適的分割槽數之前, 最好再考量一下當前Kaf ka程式中已經使用的檔案描述符的個數。

 

 

深入理解Kafka核心設計及原理(一):初始Kafka

深入理解Kafka核心設計及原理(二):生產者

深入理解Kafka核心設計及原理(三):消費者

 

 

相關文章