Kafka 是很是流行的分佈式流式處理和大數據消息隊列解決方案,在技術行業已經獲得了普遍採用,在 Dropbox 也不例外。Kafka 在 Dropbox 的不少分佈式系統數據結構中發揮着重要的做用:數據分析、機器學習、監控、搜索和流式處理,等等。在 Dropbox,Kafka 集羣由 Jetstream 團隊負責管理,他們的主要職責是提供高質量的 Kafka 服務。他們的一個主要目標是瞭解 Kafka 在 Dropbox 基礎設施中的吞吐量極限,這對於針對不一樣用例作出適當的配置決策來講相當重要。最近,他們建立了一個自動化測試平臺來實現這一目標。這篇文章將分享他們所使用的方法和一些有趣的發現。算法
測試平臺
上圖描繪了本文所使用的測試平臺的設置。咱們在 Spark 中使用 Kafka 客戶端,這樣就能夠以任意規模生成和消費流量。咱們搭建了三個不一樣大小的 Kafka 集羣,要調整集羣大小,只須要將流量重定向到不一樣的集羣。咱們建立了一個 Kafka 主題,用於生成測試流量。爲簡單起見,咱們將流量均勻地分佈在 Kafka broker 之間。爲實現這一目標,咱們建立了測試主題,分區數量是 broker 數量的 10 倍,這樣每一個 broker 都是 10 個分區的首領。由於寫入單個分區是串行的,因此若是每一個 broker 的分區太少會致使寫入競爭,從而限制了吞吐量。根據咱們的實驗,10 是一個恰到好處的數字,能夠避免寫入競爭形成吞吐量瓶頸。編程
因爲基礎設施的分佈式特性,客戶端遍及在美國的不一樣地區。由於測試流量遠低於 Dropbox 網絡主幹的限制,因此咱們能夠安全地假設跨區域流量的限制也適用於本地流量。數組
是什麼影響了工做負載?
有一系列因素會影響 Kafka 集羣的工做負載:生產者數量、消費者羣組數量、初始消費者偏移量、每秒消息數量、每條消息的大小,以及所涉及的主題和分區的數量,等等。咱們能夠自由地設置參數,所以,頗有必要找到主導的影響因素,以便將測試複雜性下降到實用水平。安全
咱們研究了不一樣的參數組合,最後得出結論,咱們須要考慮的主要因素是每秒產生的消息數(mps)和每一個消息的字節大小(bpm)。網絡
流量模型
咱們採起了正式的方法來了解 Kafka 的吞吐量極限。特定的 Kafka 集羣都有一個相關聯的流量空間,這個多維空間中的每個點都對應一個 Kafka 流量模式,能夠經過參數向量來表示:<mps、bpm、生產者數量、消費者羣組數量、主題數量……>。全部不會致使 Kafka 過載的流量模式都造成了一個封閉的子空間,其表面就是 Kafka 集羣的吞吐量極限。數據結構
對於初始測試,咱們選擇將 mps 和 bpm 做爲吞吐量極限的基礎,所以流量空間就降到二維平面。這一系列可接受的流量造成了一個封閉的區域,找到 Kafka 的吞吐量極限至關於繪製出該區域的邊界。機器學習
自動化測試
爲了以合理的精度繪製出邊界,咱們須要用不一樣的設置進行數百次實驗,經過手動操做的方式是不切實際的。所以,咱們設計了一種算法,無需人工干預便可運行全部的實驗。分佈式
過載指示器
咱們須要找到一系列可以以編程方式判斷 Kafka 健康情況的指標。咱們研究了大量的候選指標,最後鎖定如下這些:ide
IO 線程空閒低於 20%:這意味着 Kafka 用於處理客戶端請求的工做線程池太忙而沒法處理更多工做負載。性能
同步副本集變化超過 50%:這意味着在 50%的時間內至少有一個 broker 沒法及時複製首領的數據。
Jetstream 團隊還使用這些指標來監控 Kafka 運行情況,當集羣承受過大壓力時,這些指標會首當其衝發出信號。
找到邊界
爲了找到一個邊界點,咱們讓 bpm 維度固定,並嘗試經過更改 mps 值來讓 Kafka 過載。當咱們有一個安全的 mps 值和另外一個致使集羣接近過載的 mps 值時,邊界就找到了。咱們將安全的值視爲邊界點,而後經過重複這個過程來找到整條邊界線,以下所示:
值得注意的是,咱們調整了具備相同生產速率的生產者(用 np 表示),而不是直接調整 mps。主要是由於批處理方式致使單個生產者的生產速率不易控制。相反,改變生產者的數量能夠線性地縮放流量。根據咱們早期的研究,單獨增長生產者數量不會給 Kafka 帶來明顯的負載差別。
咱們經過二分查找來尋找單邊界點。二分查找從一個很是大的 np[0,max] 窗口開始,其中 max 是一個確定會致使過載的值。在每次迭代中,選擇中間值來生成流量。若是 Kafka 在使用這個值時發生過載,那麼這個值將成爲新的上限,不然就成爲新的下限。當窗口足夠窄時,中止該過程。咱們將對應於當前下限的 mps 值視爲邊界。
結果
咱們在上圖中繪製了不一樣大小的 Kafka 的邊界。基於這個結果,咱們能夠得出結論,Dropbox 基礎設施能夠承受的最大吞吐量爲每一個 broker 60MB/s。
值得注意的是,這只是一個保守的極限,由於咱們測試用的消息大小徹底是隨機的,主要是爲了最小化 Kafka 內部消息壓縮機制所帶來的影響。在生產環境中,Kafka 消息一般遵循某種模式,由於它們一般由類似的過程生成,這爲壓縮優化提供了很大的空間。咱們測試了一個極端狀況,消息所有由相同的字符組成,這個時候咱們能夠看到更高的吞吐量極限。
此外,當有 5 個消費者羣組訂閱測試主題時,這個吞吐量限制仍然有效。換句話說,當讀取吞吐量是當前 5 倍時,仍然能夠實現這樣的寫入吞吐量。當消費者羣組增長到 5 個以上時,隨着網絡成爲瓶頸,寫入吞吐量開始降低。由於 Dropbox 生產環境中的讀寫流量比遠低於 5,因此咱們獲得的極限適用於全部生產集羣。
這個結果爲未來的 Kafka 配置提供了指導基礎。假設咱們容許最多 20%的 broker 離線,那麼單個 broker 的最大安全吞吐量應爲 60MB/s * 0.8 ~= 50MB/s。有了這個,咱們能夠根據將來用例的估算吞吐量來肯定集羣大小。
對將來工做的影響
這個平臺和自動化測試套件將成爲 Jetstream 團隊的一筆寶貴的財富。當咱們切換到新硬件、更改網絡配置或升級 Kafka 版本時,能夠從新運行這些測試並得到新的吞吐量極限。咱們能夠應用相同的方法來探索其餘影響 Kafka 性能的因素。最後,這個平臺能夠做爲 Jetstream 的測試平臺,以便模擬新的流量模式或在隔離環境中重現問題。
總結在這篇文章中,咱們提出了一種系統方法來了解 Kafka 的吞吐量極限。值得注意的是,咱們是基於 Dropbox 的基礎設施獲得的這些結果,所以,因爲硬件、軟件棧和網絡條件的不一樣,咱們獲得的數字可能不適用於其餘 Kafka 實例。咱們但願這裏介紹的技術可以幫助讀者去了解他們本身的 Kafka 系統。