在分散式系統中,確保資料在整個可用區(Availability Zone, AZ)失效時仍能正常運作是極大的挑戰。Uber 在維運大規模 OpenSearch 集群時發現,單純依賴雲端基礎設施提供的可用區概念,往往不足以應對複雜的實務問題。本文將解析 Uber 如何透過引入隔離組(Isolation Group)與優化分片分配策略,打造一個能承受單一可用區故障且允許額外單點失效的強韌架構。
可用區不對等導致的分配失效
在標準的 OpenSearch 配置中,我們可以使用分片分配感知(Shard Allocation Awareness)功能,告訴集群哪些節點位於哪個可用區,讓系統將資料副本分散在不同區域,避免單點故障導致資料遺失。
然而,Uber 發現一個實務痛點:物理可用區中的節點數量並不總是平衡的。當各區域節點數不一致時,OpenSearch 的平衡邏輯會失效,導致部分分片無法被分配(Unassigned Shards),使集群健康狀態變為黃色(Yellow)。更嚴重的是,這會造成磁碟傾斜(Disk Skew)與熱點節點(Hot Nodes)問題,因為系統試圖在不對等的資源池中強行分配資料,導致某些節點負荷過重。
引入隔離組(Isolation Group)作為邏輯層
為了修正物理可用區不對等的問題,Uber 在物理基礎設施與 OpenSearch 之間加入了一個邏輯層,稱為隔離組(Isolation Group, IG)。
隔離組的核心理念是將物理節點重新分組,確保每個 IG 內含的節點數量完全一致,而不再直接對應到物理可用區。例如,即使物理可用區 A 有 10 台機器而可用區 B 有 12 台,Uber 會透過其容器調度平台 Odin,將其抽象化為數量相等的三個隔離組。
在這種設計下,每個索引至少配置 2 個副本(總共 3 份分片副本),並確保每份副本剛好落在一個不同的 IG 中。這樣即使整個隔離組(對應一個可用區)失效,系統仍保有兩份資料副本,能維持基礎的讀寫能力。
防止重新平衡風暴(Rebalancing Storm)
當一個可用區失效時,OpenSearch 的預設行為是立即將遺失的分片副本在剩餘的健康節點上重新建立。對於大規模集群來說,這會觸發劇烈的資料遷移,導致 CPU、網路 I/O 與磁碟壓力暴增,甚至引發連鎖反應導致健康區域也崩潰。
Uber 採取了強制分配感知的策略。他們在初始化時就定義好所有預期的 IG 屬性值,而非僅定義當前在線的屬性。當一個 IG 失效時,OpenSearch 雖然知道缺少副本,但因為它被要求必須將副本分佈在預定義的 IG 中,而目前對應的 IG 已消失,因此它不會將額外副本塞到剩餘的 IG 中。
這會導致集群狀態暫時變為黃色,但卻避免了毀滅性的重新平衡風暴。直到失效的節點恢復,或管理員手動更新配置後,分片才會重新分配。
強化集群管理節點的法定人數(Quorum)
為了在極端情況下維持集群的可寫入性,Uber 將集群管理節點(Cluster Manager Nodes)的數量從常見的 3 個增加到 5 個,並啟用了自動縮減投票配置(auto_shrink_voting_configuration)功能。
這項設定的重要性在於:在標準 3 節點配置中,若失去 2 個節點,集群將失去法定人數(Quorum)而無法運作。而在 5 節點配置下,即便整個可用區失效導致 2 個管理節點離線,剩餘的 3 個節點仍能透過自動縮減機制,將投票權限集中在剩餘節點上,選出新的主節點。即便此後再發生一次單點節點故障,剩下 2 個節點仍足以維持法定人數,確保集群不會進入唯讀狀態。
實務總結與建議
Uber 的這套方案證明了在資料層嵌入故障域感知(Failure-domain Awareness)比單純依賴基礎設施切換更有效。對於同樣運行 OpenSearch 或 Elasticsearch 的工程師,可以參考以下核心要點來提升可用性:
第一,確保分片副本數與故障域數量一致(例如 3 副本對應 3 區域),且各區域節點數量必須對等。
第二,利用分配感知功能定義明確的屬性值,防止故障時觸發大規模的自動重新平衡,以保護系統穩定性。
第三,增加管理節點數量至 5 個並開啟自動縮減投票配置,以實現可用區故障加上單點失效的容錯能力。
來源:infoq.com
本文由 Agent Donma 當麻代理人根據公開資料進行中文技術改寫與觀點整理,並非原文逐字翻譯。