<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    如何為Kafka集群確定合適的分區數以及分區數過多帶來的弊端

    VSole2022-08-04 16:43:21

    理論上說,如果一個topic分區越多,理論上整個集群所能達到的吞吐量就越大。

    但是,實際生產中Kafka topic的分區數真的配置越多越好嗎?很顯然不是!

    分區數過多會有以下弊端:

    一、客戶端/服務器端需要使用的內存就越多

    Kafka0.8.2之后,在客戶端producer有個參數batch.size,默認是16KB。它會為每個分區緩存消息,在數據積累到一定大小或者足夠的時間時,積累的消息將會從緩存中移除并發往broker節點。這個功能是為了提高性能而設計,但是隨著分區數增多,這部分緩存所需的內存占用也會更多。

    與此同時,consumer端在消費消息時的內存占用、以及為達到更高的吞吐性能開啟的consumer線程數也會隨著分區數增加而增加。比如有10000個分區,同時consumer線程數要匹配分區數(大部分情況下是最佳的消費吞吐量配置)的話,那么在consumer client就要創建10000個線程,那么在consumer client就要創建10000個線程,也需要創建大約10000個Socket去獲取分區數據。線程的開銷成本很顯然是不容小覷的!

    此外,服務器端的開銷也不小,如果閱讀Kafka源碼的話可以發現,服務器端的很多組件都在內存中維護了分區級別的緩存,比如controller,FetcherManager等,因此分區數越多,這種緩存的成本就越大。

    二、文件句柄的開銷

    在Kafka的broker中,每個partition都會對應磁盤文件系統的一個目錄。在Kafka的數據日志文件目錄中,每個日志數據段都會分配兩個文件,一個索引文件和一個數據文件。當前版本的kafka,每個broker會為每個日志段文件打開一個index文件句柄和一個數據文件句柄。因此,隨著partition的增多,所需要保持打開狀態的文件句柄數也就越多,最終可能超過底層操作系統配置的文件句柄數量限制。

    三、越多的分區可能增加端對端的延遲

    Kafka端對端延遲定義為producer端發布消息到consumer端接收消息所需要的時間,即consumer接收消息的時間減去producer發布消息的時間。

    Kafka只有在消息提交之后,才會將消息暴露給消費者。例如,消息在所有in-sync副本列表同步復制完成之后才暴露。因此,in-sync副本復制所花時間將是kafka端對端延遲的最主要部分。在默認情況下,每個broker從其他broker節點進行數據副本復制時,該broker節點只會為此工作分配一個線程,該線程需要完成該broker所有partition數據的復制。

    注意,上述問題可以通過增大kafka集群來進行緩解。例如,將1000個分區leader放到一個broker節點和放到10個broker節點,他們之間的延遲是存在差異的。在10個broker節點的集群中,每個broker節點平均需要處理100個分區的數據復制。此時,端對端的延遲將會從原來的數十毫秒變為僅僅需要幾毫秒。

    根據經驗,如果你十分關心消息延遲問題,限制每個broker節點的partition數量是一個很好的主意:對于b個broker節點和復制因子為r的kafka集群,整個kafka集群的partition數量最好不超過100*b*r個,即單個partition的leader數量不超過100。

    四、降低高可用性

    Kafka通過多副本復制技術,實現Kafka集群的高可用和穩定性。每個partition都會有多個數據副本,每個副本分別存在于不同的broker。所有的數據副本中,有一個數據副本為leader,其他的數據副本為follower。

    在Kafka集群內部,所有的數據副本皆采用自動化的方式進行管理,并且確保所有的數據副本的數據皆保持同步狀態。不論是producer端還是consumer端發往partition的請求,都通過leader數據副本所在的broker進行處理。當broker發生故障時,對于leader數據副本在該broker的所有partition將會變得暫時不可用。Kafka將會自動在其它數據副本中選擇出一個leader,用于接收客戶端的請求。這個過程由Kafka controller節點broker自動完成,主要是從Zookeeper讀取和修改受影響partition的一些元數據信息。

    在通常情況下,當一個broker有計劃地停止服務時,那么controller會在服務停止之前,將該broker上的所有leader一個個地移走。由于單個leader的移動時間大約只需要花費幾毫秒,因此從客戶層面看,有計劃的服務停機只會導致系統在很小時間窗口中不可用。(注:在有計劃地停機時,系統每一個時間窗口只會轉移一個leader,其他leader皆處于可用狀態。)

    然而,當broker非計劃地停止服務時(例如,kill -9方式),系統的不可用時間窗口將會與受影響的partition數量有關。假如,一個2節點的kafka集群中存在2000個partition,每個partition擁有2個數據副本。當其中一個broker非計劃地宕機,所有1000個partition同時變得不可用。假設每一個partition恢復時間是5ms,那么1000個partition的恢復時間將會花費5秒鐘。因此,在這種情況下,用戶將會觀察到系統存在5秒鐘的不可用時間窗口。

    而如果發生宕機的broker恰好是controller節點時:在這種情況下,新leader節點的選舉過程在controller節點恢復到新的broker之前不會啟動。controller節點的錯誤恢復將會自動地進行,但是新的controller節點需要從zookeeper中讀取每一個partition的元數據信息用于初始化數據。例如,假設一個Kafka集群存在10000個partition,從zookeeper中恢復元數據時每個partition大約花費2ms,則controller的恢復將會增加約20秒的不可用時間窗口。

    總而言之,通常情況下Kafka集群中越多的partition會帶來越高的吞吐量。但是,如果Kafka集群中partition總量過大或者單個broker節點partition過多,都可能會對系統的可用性和消息延遲帶來潛在的負面影響,需要引起我們的重視。

    那么如何確定合理的分區數量呢?

    在partition級別上達到均衡負載是實現吞吐量的關鍵,合適的partition數量可以達到高度并行讀寫和負載均衡的目的,需要根據每個分區的生產者和消費者的目標吞吐量進行估計。

    可以遵循一定的步驟來確定分區數:根據某個topic日常"接收"的數據量等經驗確定分區的初始值,然后測試這個topic的producer吞吐量和consumer吞吐量。假設它們的值分別是Tp和Tc,單位可以是MB/s。然后假設總的目標吞吐量是Tt,那么numPartitions = Tt / max(Tp, Tc)

    說明:Tp表示producer的吞吐量。測試producer通常是很容易的,因為它的邏輯非常簡單,就是直接發送消息到Kafka就好了。Tc表示consumer的吞吐量。測試Tc通常與應用消費消息后進行什么處理的關系更大,相對復雜一些。

    kafka吞吐量
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    Kafka只有在消息提交之后,才會將消息暴露給消費者。不論是producer端還是consumer端發往partition的請求,都通過leader數據副本所在的broker進行處理。這個過程由Kafka controller節點broker自動完成,主要是從Zookeeper讀取和修改受影響partition的一些元數據信息
    Kafka消息積壓的典型場景:1.實時/消費任務掛掉比如,我們寫的實時應用因為某種原因掛掉了,并且這個任務沒有被監控程序監控發現通知相關負責人,負責人又沒有寫自動拉起任務的腳本進行重啟。此外,Kafka分區數是Kafka并行度調優的最小單元,如果Kafka分區數設置的太少,會影響Kafka consumer消費的吞吐量
    在企業實時處理架構中,通常將spark streaming和kafka集成作為整個大數據處理架構的核心環節之一。
    添加消息的任務我們稱為producer,而取出并使用消息的任務,我們稱之為consumer。kafka應運而生,它是專門設計用來做消息中間件的系統。這兩點也是kafka要解決的核心問題。為此,kafka提出了partition的概念。由于消息不會被刪除,因此可以等消費者明確告知kafka這條消息消費成功以后,再去更新游標。對于同一個topic,不同的消費組有各自的游標。
    Filebeat監視您指定的日志文件或位置,收集日志事件,并將它們轉發到Elasticsearch或 Logstash進行索引。使用Kibana,可以通過各種圖表進行高級數據分析及展示。
    如果是在消費端丟失數據,那么多次消費結果完全一模一樣的幾率很低。這時已經fetch的數據還沒有處理完成但已經被commit掉,因此沒有機會再次被處理,數據丟失。網絡負載很高或者磁盤很忙寫入失敗的情況下,沒有自動重試重發消息。
    Kafka consumer為了及時消費消息,會以Consumer Group(消費組)的形式,啟動多個consumer消費消息。不同的消費組在消費消息時彼此互不影響,同一個消費組的consumer協調在一起消費訂閱的topic所有分區消息。
    隨機讀寫會導致尋址時間延長,從而影響磁盤的讀寫速度。而Kafka在將數據持久化到磁盤時,采用只追加的順序寫,有效降低了尋址時間,提高效率。當讀操作發生時,先從PageCache中查找,如果發生缺頁才進行磁盤調度,最終返回需要的數據。對應到Kafka生產和消費消息中:producer把消息發到broker后,數據并不是直接落入磁盤的,而是先進入PageCache。
    Apache Kafka是一個開源的分布式事件流平臺,被數千家公司用于高性能數據管道、流分析、數據集成和任務關鍵型應用程序。
    分布式流平臺Kafka
    2022-08-02 10:13:27
    無論消息是否被消費,Kafka集群都會持久的保存所有發布的消息,直到過期。Kafka中采用分區的設計主要有兩個目的:第一,當日志大小超過了單臺服務器的限制,允許日志進行擴展。在Kafka中實現消費的方式是將日志中的分區劃分到每一個消費者實例上,以便在任何時間,每個實例都是分區唯一的消費者。
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类