1. 程式人生 > >【譯】Apache Kafka支持單集群20萬分區

【譯】Apache Kafka支持單集群20萬分區

kafka Kafka集群 做的 過程 ilo 6.5 概念 1.0 表現

  之前網上關於確定Kafka分區數的博客多多少少都源自於饒軍大神的文章,如今他帶來了這方面的第二篇文章,特此翻譯一下,記錄一下其中的要點。

  原貼地址: https://www.confluent.io/blog/apache-kafka-supports-200k-partitions-per-cluster


  Kafka中topic可以設置多個分區,而分區是最小的並行度單位。通常而言,分區數越多吞吐量也越高。但是依然有很多因素制約了一個Kafka集群所能支持的最大分區數。我現在高興地宣布Kafka 1.1.0版本在這方面取得了重大的改進。目前生產環境中單Kafka集群支持的分區上限得到了極大的提升。

  為了便於理解這個改進是如何實現的,我們重溫一下分區leader和controller的基本概念。首先,每個分區都可以配置多個副本用於實現高可用性以及持久性。其中的一個副本被指定為leader而所有client只與leader進行交互;其次,cluster中的某個broker被指定為controller來管理整個集群。若broker掛掉,controller負責為該broker上所有分區選舉leader。

  默認情況下關閉Kafka broker執行的是一個受控關閉操作(下稱controlled shutdown)。Controlled shutdown對client的影響是最小的。一個典型的controlled shutdown分為以下幾步:1. 發送SIGTERM信號給待關閉的broker;2. Broker發送請求給controller表明自己要正常關閉;3. Controller變更該broker上所有分區的leader並將這部分數據保存回Zookeeper;4. Controller發送新的leader信息給其他broker;5. Controller發送響應給關閉中的broker表明操作成功,於是broker成功關閉。此時,client端不受任何影響因為新leader已經轉移到其他broker上。下面的兩張圖描述了這個過程,註意到圖中(4)和(5)步是可以並行執行的:

技術分享圖片 技術分享圖片

上圖中步驟(1)發起broker關閉;步驟(2)發送controlled shutdown請求給controller;步驟(3)中controller寫入新leader到Zookeeper;步驟(4)controller發送新leader信息到其他broker;步驟(5)controller發送成功信息給關閉中的broker

  在Kafka 1.1.0之前,一旦發起controlled shutdown,controller每次只能為一個分區選舉leader。對於每個分區而言,controller順序執行:選擇新leader、同步寫leader信息回Zookeeper以及同步leader信息給其他broker等操作。這種設計是低效率的:首先,同步寫入Zookeeper就有很高的延時,從而整體拖慢controller shudown時間;其次,每次處理一個分區的做法導致需要給其他broker發送很多次請求,即使這些請求本身攜帶的數據量是很小的,從而最終導致對新leader的處理時間被極大地拉長。

  Kafka 1.1.0為controlled shutdown引入了多個方面的性能提升。第一個提升就是使用異步API來替代了之前的同步寫入Zookeeper。在controlled shutdown過程中,Kafka不再是每次寫入一個leader信息,等待其完成然後再寫入下一個。相反地,controller使用異步API一次性地提交多個分區的leader到Zookeeper上,然後統一等待其執行完畢。這就等於在Kafka與Zookeeper之間構建了一種管道式請求處理流程,從而減少了整體的延時。第二個提升則是將於新leader的交互操作批量化。與其每次為一個分區發送RPC請求,controller使用單個RPC請求一次性地攜帶所有受影響分區的leader信息。

  同時,Kafka對於controller failover的時間也做了優化。當controller掛掉後,Kafka集群自動檢測controller失敗並選擇其他broker作為新的controller。在開啟controller工作之前,新選出的controller必須要從Zookeeper中加載所有分區的狀態信息到內存中。如果controller直接崩潰的話,分區不可用的時間窗口將等同於Zookeeper會話超時時間加上controller狀態加載時間,所以降低加載時間能夠有效地幫助我們改善Kafka可用性。在1.1.0之前,加載操作使用的也是同步Zookeeper API。在1.1.0中被替換成了異步API。

  社區對controlled shutdown時間和加載時間都做了測試。每個測試都使用了5節點Zookeeper的集群。在測試controlled shutdown時,社區搭建了一個5節點broker的Kafka集群並為該集群創建了25000個單分區的topic,每個topic都是雙副本,故每個broker上平均有10000個分區。之後測試controlled shutdown,測試結果如下:

技術分享圖片

  提升的很大一部分來自於修復了打日誌(logging)的開銷:之前在每個分區leader變更時都會記錄集群中所有分區的數據——這實際上是沒必要的。通過修復了這個logging的bug,controller shutdown從6.5分鐘被壓縮到30秒,而采用異步API更進一步地將其拉低到3秒。這些提升都極大地縮短了Kafka集群重啟恢復的時間。

  在第二項測試中,社區同樣搭建了一個5節點集群,只不過這次創建了2000個配置有50分區的topic,單副本——故總數是1000000個分區。當測試controller狀態加載時間時發現比1.0.0有了100%的提升(1.0.0耗時28秒,1.1.0耗時14秒)。

  有了這些提升,Kafka單集群能夠支持多少分區呢?確切的數字自然依賴於諸如可容忍的不可用窗口時間、Zookeeper延時、broker存儲類型等因素。根據經驗法則我們評估單臺broker能夠支撐的分區數可達4000個,而單集群能夠支撐200000個分區。當然後者主要受限於集群對controller崩潰這種不常見情形的容忍度,另外其他影響分區數的因素也要考慮進來。

  1.1.0所做的改進僅僅是提升Kafka高擴展性的一小步。事實上社區在1.1.0版本還嘗試了更多的分區並改進了它們的延時表現。後面可能會在另一篇文章中給出具體的說明。在未來,Kafka社區計劃實現單集群支撐百萬級分區的構想,所以,敬請期待~~

【譯】Apache Kafka支持單集群20萬分區