作者丨Prince Mahajan
編譯丨諾亞
出品 | 51CTO技術棧(微信號:blog51cto)
如何通過云原生設計提升Apache Kafka引擎的性能、可用性和成本效率?本文作者圍繞這一中心議題,介紹了一項名為Kora的事件流處理平臺的重新設計過程及關鍵技術創新。文章首先指出成功云原生平臺的必備特性,包括多租戶支持、易于擴展、數據驅動管理、跨客戶安全隔離以及支持快速創新。Kora的設計旨在滿足這些需求,同時保持與現有Kafka協議的兼容性,并在多云環境下提供一致體驗。
當我們著手重建托管Apache Kafka服務核心的引擎時,我們知道必須滿足成功云原生平臺的幾個獨特要求。這些系統需要從底層開始就是多租戶的,能夠輕松擴展以服務于成千上萬的客戶,并且主要由數據驅動的軟件而非人工操作員來管理。它們還應確保在工程師可以持續快速創新的環境中,跨客戶具有強大的隔離性和安全性,即使工作負載不可預測。
去年,我們展示了Kafka引擎的重新設計。我們設計和實施的大部分內容也將適用于其他構建大規模分布式云系統的團隊,如數據庫或存儲系統。我們希望與更廣泛的社區分享我們的經驗,希望這些經驗能對從事其他項目的人有所幫助。
1.Kafka引擎重新設計的關鍵考慮因素
我們的高層級目標可能與你自己基于云的系統的目標相似:提高性能和彈性,增加對我們自己和客戶的成本效率,并在多個公有云上提供一致的體驗。我們還有一個額外的要求,即與當前版本的Kafka協議保持100%兼容。
我們重新設計的Kafka引擎名為Kora,是一個事件流處理平臺,在AWS、Google Cloud和Azure的70多個區域運行著數萬個集群。你可能不會立即達到這樣的規模,但下面描述的許多技術仍然適用。
以下是我們在新的Kora設計中實施的五個關鍵創新。如果你想深入了解其中任何一個,我們在這個主題上發表了一篇白皮書,該白皮書在2023年的國際超大數據庫會議(VLDB)上獲得了最佳行業論文獎。
2.使用邏輯“單元”實現可擴展性和隔離性
要構建高可用性和水平可擴展的系統,你需要一個使用可擴展和可組合構建塊構建的架構。具體來說,一個可擴展系統所做的工作應隨著系統規模的增加而線性增長。原始的Kafka架構沒有滿足這個標準,因為許多負載方面的增長與系統規模的增加是非線性的。
例如,隨著集群規模的增加,連接數呈二次方增長,因為所有客戶端通常都需要與所有代理通信。類似地,由于每個代理通常在所有其他代理上都有跟隨者,復制開銷也呈二次方增長。最終結果是,添加代理會導致開銷的不成比例增加,相對于它們帶來的額外計算/存儲能力。
第二個挑戰是確保租戶之間的隔離。特別是,一個表現不佳的租戶可能會對集群中每個其他租戶的性能和可用性產生負面影響。即使有有效的限制和節流,可能總會有一些負載模式是有問題的。即使客戶端表現良好,節點的存儲也可能會被降級。在集群中的隨機分布,這將影響所有租戶和潛在的所有應用程序。
我們使用一種稱為單元的邏輯構建塊解決了這些挑戰。我們將集群劃分為一組跨越可用性區域的單元。租戶被隔離到單個單元中,這意味著該租戶擁有的每個分區的副本都被分配到該單元中的代理上。這也意味著復制被限制在該單元內的代理之間。向單元中添加代理在單元級別上帶來了與以前相同的問題,但現在我們有了一個選項,即在不增加開銷的情況下在集群中創建新的單元。此外,這為我們提供了一種處理嘈雜租戶的方法。我們可以將租戶的分區移動到隔離單元中。
為了衡量這個解決方案的有效性,我們設置了一個包含24個代理和六個代理單元的實驗性集群(有關完整配置的詳細信息,請參見我們的白皮書)。當我們運行基準測試時,集群負載——我們為衡量Kafka集群負載而設計的一個自定義指標——在使用單元時為53%,而不使用單元時為73%。
3.通過分層架構優化不同存儲類型使用
通過將架構分層以優化不同存儲類型的使用,我們在提高性能和可靠性的同時降低了成本。這源于我們分離計算和存儲的方式,主要是兩方面:使用對象存儲保存冷數據,以及使用塊存儲代替實例存儲保存更頻繁訪問的數據。
這種分層架構使我們能夠增強彈性——當只需要重新分配熱數據時,分區的重新分配變得容易得多。使用EBS卷而不是實例存儲也提高了持久性,因為存儲卷的生命周期與相關虛擬機的生命周期解耦。
最重要的是,分層允許我們顯著改善成本和性能。成本降低是因為對象存儲是存儲冷數據更經濟實惠和可靠的選擇。而性能提高是因為一旦數據被分層,我們可以將熱數據置于高性能存儲卷中,如果沒有分層,這將是成本高昂的。
4.使用抽象統一多云體驗
對于計劃在多個云上運營的任何服務來說,提供統一且一致的跨云客戶體驗至關重要,但這在幾個方面都是具有挑戰性的。云服務復雜,即使它們遵循標準,不同云和實例之間仍存在差異。實例類型、實例可用性和甚至對于類似云服務的計費模式都可能以微妙但重要的方式有所不同。例如,Azure塊存儲不允許獨立配置磁盤吞吐量/IOPS,因此需要配置大容量磁盤來擴展IOPS。相比之下,AWS和GCP允許你獨立調整這些變量。
許多SaaS提供商回避這種復雜性,讓客戶自己擔心實現一致性能所需的配置細節。顯然,這并不理想,因此在Kora中,我們開發了抽象化的方法來消除這些差異。
我們引入了三種抽象,使客戶能夠遠離實現細節,專注于更高層次的應用程序屬性。這些抽象可以幫助大幅簡化服務并限制客戶需要自行回答的問題。
5.自動化緩解循環對抗性能退化
故障處理對于可靠性至關重要。即便是在云端,由于云提供商中斷、軟件錯誤、磁盤損壞、配置錯誤或其他原因,故障也是不可避免的。這些可能是完全或部分故障,但無論哪種情況,都必須迅速解決,以免影響性能或系統訪問。
不幸的是,如果你正在大規模運營云平臺,手動檢測和處理這些故障是不可能的。它會占用過多的操作員時間,并且意味著可能無法快速解決問題以維持服務水平協議。
為了解決這個問題,我們構建了一個解決方案來處理所有此類基礎設施退化的案例。具體來說,我們構建了一個反饋循環,包括一個退化檢測組件,該組件從集群收集指標并使用它們來決定是否有任何組件發生故障以及是否需要采取行動。這使我們能夠在不需任何手動操作員介入的情況下,每周自動處理數百次退化。
實現多種反饋循環跟蹤代理性能并在必要時采取行動。當發現問題時,會標記為特定的代理健康狀態,并針對每個狀態采用相應的緩解策略。這三個反饋循環分別解決了本地磁盤問題、外部連接問題和代理退化問題。
- 監控:一種從外部角度跟蹤每個代理性能的方法。我們經常進行探測以跟蹤。
- 聚合:在某些情況下,我們聚合指標以確保相對于其他代理,退化是可察覺的
- React:特定于 Kafka 的機制,用于將代理排除在復制協議之外或將領導權從復制協議中移走。
確實,我們的自動化緩解每月在所有三大云提供商中檢測并自動緩解數千次部分退化,節省了寶貴的操作員時間,同時確保對客戶的影響最小。
6.平衡有狀態服務以實現性能和效率
在任何有狀態服務中跨服務器平衡負載是一個難題,直接影響到客戶體驗的服務質量。負載分布不均會導致客戶受到最繁忙服務器提供的延遲和吞吐量限制。有狀態服務通常有一組鍵,你需要平衡這些鍵的分布,以便總體負載均勻分布在服務器上,從而客戶能夠從系統中獲得最大性能和最低成本。
例如,Kafka運行的狀態性代理負責平衡分區及其副本到各個代理的分配。根據客戶活動,這些分區上的負載可能會以難以預測的方式激增或下降。這需要一套指標和啟發式方法來確定如何放置分區以最大化效率和利用率。我們通過一個平衡服務來實現這一點,該服務跟蹤來自多個代理的一套指標,并持續在后臺工作以重新分配分區。
重新平衡分配需要謹慎進行。過于積極的重新平衡會因這些重新分配產生的額外工作而破壞性能并增加成本。而過慢的重新平衡則會讓系統在修復不平衡之前明顯退化。我們必須實驗了很多啟發式方法,以收斂到一個適合各種工作負載的適當反應水平。
有效平衡的影響可能是巨大的。我們的一位客戶在為他們啟用重新平衡后,負載大約減少了25%。類似地,另一位客戶由于重新平衡,延遲大幅減少。
7.精心設計的云原生服務的優勢
如果你正在為你的組織構建云原生基礎設施,無論是使用新代碼還是使用像Kafka這樣的現有開源軟件,我們希望本文中描述的技術能幫助你實現性能、可用性和成本效率的目標。
為了測試Kora的性能,我們在相同的硬件上進行了小規模實驗,比較了Kora和我們的全云平臺與開源Kafka。我們發現Kora提供了更大的彈性,擴展速度提高了30倍;相比我們自管理客戶或其他云服務的故障率,可用性提高了10倍以上;并且延遲明顯低于自管理的Kafka。雖然Kafka仍然是運行開源數據流系統的最佳選擇,但對于尋求云原生體驗的人來說,Kora是一個很好的選擇。
參考鏈接:https://www.infoworld.com/article/3715426/5-tips-for-building-highly-scalable-cloud-native-apps.html