Roblox 如何將其 Kafka 平台擴展至每日處理超過 18 兆則訊息
高效系統的端到端優化

過去兩年來,我們每年將內部訊息佇列平台的規模擴展超過 2.5 倍,目前每日處理量已超過 18 兆則訊息。 目前我們每秒處理超過 3 億則訊息,同時維持 99.995% 的可用性。這個基於 Apache Kafka 建置的訊息佇列平台,已成為我們在公司內部傳輸數據的關鍵環節。它支援的作業負載包括分析事件、內容審核流程、配對系統等眾多應用。這些數字固然令人振奮,但更重要的故事在於我們是如何達成這項成就的。
端到端優化的影響
關於大規模系統,一個常見的誤解是:容量問題主要取決於硬體。根據我們的經驗,若將可擴展性視為一個端到端的工程問題來處理,往往能帶來最具影響力的改進。
Roblox 各團隊已基於訊息佇列建置了各式各樣的平台,包括 AI 訓練管線、串流處理抽象層以及遙測系統。透過與這些平台的負責團隊合作,我們得以協助確保遵循最佳實踐,例如啟用批次處理與壓縮功能。這使得系統能高效運作,同時無需讓終端使用者參與詳細的配置設定。

與使用該平台的各團隊就業務優先順序、衡量標準及成功準則達成共識至關重要,這有助於推動跨團隊協作。關鍵指標在系統各層級之間有所差異:雖然我們可能會優化 Kafka 伺服器,以在較少機器的情況下高效處理大量資料,但終端使用者可能希望將端到端延遲優化至毫秒級,或是將批次工作完成資料寫入所需的總時間優化至最低。
並非所有流量都相同
我們學到的一項關鍵教訓是:大規模平台若不將所有流量一視同仁,其可靠性會更高。某些工作負載在流量激增時需要極低的延遲和強大的保護,例如我們的配對系統,其運作時的端到端延遲必須控制在 10 毫秒以內。 另一些工作負載雖然流量極大,但對延遲的容忍度較高,例如我們的分析事件導入管道,即使端到端延遲達數秒仍能順暢運行。若將這兩類流量以相同方式處理,流量最大的那類可能會擠占對業務更關鍵的流量,特別是在負載高峰期間。
為解決此問題,我們會根據使用案例的需求將流量分組,以確保每個案例都能獲得妥善支援。在 Kafka 中,端到端延遲與吞吐量之間的權衡,是建立新使用案例時的主要考量之一。這項原則貫穿從生產者(producer)到伺服器再到消費者(consumer)的整個資料路徑:每個環節都有可調整的設定,用以針對吞吐量或延遲進行優化。 雖然可針對個別用例調整客戶端設定,但伺服器端的設定靈活性較低,因為為每個不同的用例維護專屬叢集並不可行。
我們將這種針對各群集所服務的用例進行優化的方法,從系統堆疊一路延伸至硬體層。
硬體依然至關重要
我們最初是在配備 RAID10 硬碟的機器上運行 Kafka。隨著流量增長,機器的磁碟 I/O 容量成為限制每台伺服器 Kafka 吞吐量的主要瓶頸。為解決此問題,我們進行了兩項優化:盡可能將中繼器轉換為使用 SSD,從而將瓶頸從磁碟 I/O 容量轉移至網路吞吐量或磁碟空間(因為我們採購的 SSD 磁碟空間較小)。 此舉使磁碟 I/O 吞吐量提升了 10 倍。我們同時開始將剩餘的 HDD 陣列從 RAID10 轉換為 RAID0。由於 RAID0 每次寫入僅需對單一磁碟進行寫入(而非兩顆),這使得磁碟 I/O 容量大致翻了一倍。
其取捨在於:由於每個訊息副本僅寫入每台仲介伺服器的一顆硬碟(而非兩顆),因此從 RAID10 轉換至 RAID0 可能會伴隨可靠性風險。為維持可靠性,我們針對重要用例增加了確認(acks)次數並強化資料複製機制,包括複製至多個區域。
要充分發揮每台機器的儲存與吞吐量能力,還需要額外的工作。我們優化了記憶體分配與頁面快取管理設定,使 Kafka 能將訊息緩存,並從記憶體中處理讀取或近期資料的請求;僅在必要時(例如讀取歷史資料時)才會觸發磁碟讀寫並消耗寶貴的 IOPS。
我們還執行了效能基準測試,以了解硬體限制,並確定需要設定哪些軟體層級的限制。實際上,這意味著需設定 Kafka 經紀人的讀寫流量限制,這些限制會根據叢集所运行的硬體而有所不同。我們的 SSD 伺服器每台經紀人可處理更高的吞吐量,而 HDD 伺服器則更適合需要長期保留歷史資料的使用情境。
建構可靠性
佇列平台是 Roblox 基礎架構的關鍵組件,維持其可靠性至關重要。上線前的測試以及持續進行的故障情境測試(有時稱為「實戰演練」),對於驗證我們的基礎架構能否抵禦單一主機故障、機架故障、網路問題等各種故障模式,發揮了關鍵作用。 我們可靠性團隊的內部混沌測試平台,不僅實現了模擬各種故障情境的能力,更簡化了相關流程。這些測試有助於識別系統的改進空間或退化現象,並透過定期驗證警示機制,確保運維人員熟悉處理各類問題(即使是罕見問題)的步驟,從而建立卓越的運維能力。
我們還設計並實作了故障轉移流程,能迅速為依賴性用例恢復佇列功能。即使單一叢集發生全面故障,我們也能將客戶端切換至具備充足容量的正常叢集。為確保擁有足夠的閒置容量,我們維持一個備用 Kafka 叢集。這有助於在活躍叢集之間切換流量時,消除「噪音鄰居」問題的風險。
下圖展示執行故障轉移的高階步驟。首先,運維人員確定故障轉移的範圍;接著,透過自動化批量操作在備用叢集中建立主題與存取控制清單(ACL);最後,運維人員更新控制平面服務的配置,客戶端會透過輪詢這些配置來判斷是否需要重新連線。下圖所示為通用的即時應用情境。 針對其他使用案例與情境,我們還提供額外的策略與工具,包括使用 Mirror Maker 2 進行主題鏡像、資料回填工具等。

Roblox 對安全性有嚴格的要求,這也是可靠性不可或缺的一部分。我們已實作標準的安全功能,例如傳輸中加密(透過 mTLS)、靜態資料加密(透過加密磁碟)、資料保留期限要求,以及透過 Kafka 主體和存取控制清單(ACL)進行的身份驗證與授權。此外,我們還會自動輪替使用者的憑證,以進一步提升安全性。
除此之外,我們在控制平面上建置了自訂處理機制,以利快速進行作業系統修補程式更新及機架清空作業。在作業系統修補期間,我們會將資料保留在磁碟上,以便完成修補的機器在重新加入 Kafka 叢集後能迅速恢復正常運作。透過這種方式,即使系統規模持續擴大,我們仍能在 30 天內完成整個機隊的修補作業。 透過 Cruise Control 等工具,我們以「機架感知」的方式進行資料複製,因此可將整個機架離線進行維護與網路修補,而不會影響資料的可用性。
未來的方向
我們佇列平台的下一階段目標,在於讓平台對開發者而言更加簡便,同時持續提升彈性與隔離性。我們正投入資源開發新的抽象層,包括生產者與消費者代理,以及完全託管的連接器。這些系統將進一步使應用程式團隊擺脫基礎設施複雜性的束縛,並讓我們的平台在規模化部署時更易於採用與管理。 舉例來說,消費者代理將實現「競爭型消費者」模式,使平台能支援更廣泛的應用場景,並將處理器的擴展與 Kafka 分區的擴展解耦。這對於處理大量突發通知等用例極具價值——此類用例無需順序性,且可透過暫時無限制地增加處理器數量來提升效能,而無需綁定特定的端到端傳遞目標。
Kafka 的擴展不僅僅是增加叢集的數量和規模,更在於建立工程規範、抽象層與營運模式,使 Roblox 能持續致力於每天以樂觀與文明的態度,將十億人連結在一起。
致謝:感謝 Danny Yuan 和 George Li 對 Roblox 佇列平台所作出的重大貢獻。


