多年來,Facebook已從一種基本的Web服務器體系結構演變為一個復雜的體系結構,其中包含成千上萬的服務在后臺運行,擴展Facebook產品所需的各種后端服務并不是一件容易的事,而且發現我們的許多團隊正在構建具有重疊功能的自定義分片解決方案,為了解決此問題,我們將Shard Manager構建為通用平臺,以促進可靠分片應用程式的有效開發和操作,
使用分片擴展服務的概念并不新鮮,但是,據我們所知,我們是業界唯一在我們的規模上獲得廣泛采用的通用分片平臺,Shard Manager管理生產中成百上千個應用程式中成千上萬個服務器上托管的數千萬個分片,
多年來,Facebook已從一種基本的Web服務器體系結構演變為一個復雜的體系結構,其中包含成千上萬的服務在后臺運行,擴展Facebook產品所需的各種后端服務并不是一件容易的事,而且發現我們的許多團隊正在構建具有重疊功能的自定義分片解決方案,為了解決此問題,我們將Shard Manager構建為通用平臺,以促進可靠分片應用程式的有效開發和操作,
使用分片擴展服務的概念并不新鮮,但是,據我們所知,我們是業界唯一在我們的規模上獲得廣泛采用的通用分片平臺,Shard Manager管理生產中成百上千個應用程式中成千上萬個服務器上托管的數千萬個分片,

分片簡介
人們熟悉分片作為擴展服務以支持高吞吐量的一種方式,下圖說明了典型Web堆疊的縮放比例,Web層通常是無狀態的,并且易于擴展,由于任何服務器都可以處理任何請求,因此可以使用多種通信量路由策略,例如輪循或隨機,

另一方面,縮放資料庫部分由于其狀態是不平凡的,我們需要應用一種方案來確定性地跨服務器分布資料,像散列這樣的簡單散列方案hash(data_key) % num_servers 可以散布資料,但是當按比例添加服務器時,存在將資料混排的問題,一致性哈希通過僅將一小部分資料從現有服務器重新分配到新服務器來解決此問題,但是,此方案要求應用程式具有細粒度的鍵才能使統計負載平衡有效,由于其本質,一致性哈希支持基于約束的分配的能力(例如,應將歐洲聯盟用戶的資料存盤在歐洲資料中心以降低延遲),結果,只有某些型別的應用程式(例如分布式快取)才采用此方案,
一種替代方案是將資料顯式磁區為分配給服務器的分片,數十億用戶的資料存盤在許多資料庫實體中,每個實體都可以視為一個分片,為了提高容錯能力,每個資料庫分片可以具有多個副本(又名副本),每個副本都可以發揮不同的作用 (例如,主要或次要),具體取決于一致性要求,
明確分配給服務器的分片具有合并各種約束(例如,哈希解決方案無法支持的位置首選項)的能力,我們發現分片方法比散列方法更靈活,并且適合更廣泛的分布式應用程式的需求,
采用這種分片方法的應用程式通常需要某些分片管理功能才能可靠地大規模運行,最基本的功能是故障轉移功能,如果發生硬體或軟體故障,系統可以將客戶端流量從故障服務器轉移開,甚至可能需要在運行狀況良好的服務器上重建受影響的副本,在大型資料中心中,服務器始終計劃停機以執行硬體或軟體維護,分片管理系統需要通過主動將副本從服務器上移開以確保每個分片具有足夠的正常副本,以便在必要時將其洗掉,
另外,可能不均勻且不斷變化的分片負載需要負載平衡,這意味著必須動態調整每個服務器主機的分片集,以實作統一的資源利用率并提高整體資源效率和服務可靠性,最后,客戶端流量的波動需要分片擴展,系統在每個分片的基礎上動態調整復制因子,以確保其平均每個副本負載保持最佳狀態,
我們發現,Facebook的不同服務團隊已經在構建自己的自定義解決方案,以實作不同程度的完整性,常見的情況是,服務能夠處理故障轉移,但是負載平衡的形式非常有限,這導致次優的可靠性和較高的操作開銷,這就是為什么我們將Shard Manager設計為通用的分片管理平臺的原因,
使用分片管理器將分片作為平臺
多年來,已將數百個分片應用程式構建或遷移到Shard Manager上,具有歷史超增長的上十萬個服務器上總共有上千萬個分片副本,這些應用程式有助于各種面向用戶的產品(包括Facebook應用程式,Messenger,WhatsApp和Instagram)的平穩運行,
首先,與Shard Manager集成意味著簡單地實作一個由add_shard 和原語組成的小而直接的界面drop_shard ,其次,每個應用程式都可以通過基于意圖的規范來宣告其可靠性和效率要求,第三,使用通用約束優化求解器使Shard Manager能夠提供通用的負載平衡功能,并輕松添加對新平衡策略的支持,
最后但并非最不重要的一點是,通過完全集成到包括容量和容器管理在內的整個基礎架構生態系統中,Shard Manager不僅支持分片應用程式的高效開發,而且還支持分片應用程式的安全運行,因此提供了端到端解決方案,這是同類平臺所沒有的提供,與類似的平臺(例如基于Hex的Apache Helix)(包括基于Paxos的存盤系統用例)相比,Shard Manager支持更復雜的用例,
Shard Manager應用程式的型別
我們在Shard Manager上抽象了應用程式的通用性,并將它們分為三種型別:僅主,僅次和主次,
僅主Primary only:
主副本**:**每個分片都有一個副本,稱為主副本,這些型別的應用程式通常將狀態存盤在外部系統中,例如資料庫和資料倉庫,一個常見的范例是,每個分片代表一個作業程式,該作業程式使用諸如批處理之類的可選優化來獲取指定的資料,對其進行處理,有選擇地服務于客戶端請求并回寫結果,流處理是一個真實的示例,它處理來自輸入流的資料并將結果寫入輸出流,Shard Manager提供了至多一項主要保證,以幫助防止由于重復資料處理而導致的資料不一致,就像傳統的基于ZooKeeper鎖的方法一樣,
僅次Secondaries only:
節點**:**每個分片具有多個角色相同的副本,稱為輔助節點,來自多個副本的冗余提供了更好的容錯能力,此外,可以根據作業負載調整復制因子:熱分片可以具有更多副本來分散負載,通常,這些型別的應用程式是只讀的,沒有很強的一致性要求,他們從外部存盤系統中獲取資料,可選地處理資料,在本地快取結果,并根據本地資料提供查詢,一個真實的例子是機器學習推理系統,該系統從遠程存盤中下載經過訓練的模型并服務于推理請求,
主次
節點**:**每個分片具有主次節點兩個角色的多個副本,這些型別的應用程式通常是對資料一致性和持久性有嚴格要求的存盤系統,其中主副本接受寫請求并驅動所有副本之間的復制,而輔助副本提供冗余,并且可以選擇提供讀取以減少主副本上的負載,一個示例是ZippyDB,它是具有基于Paxos的復制的全域鍵值存盤,
我們發現以上三種型別可以在Facebook上對大多數分片應用程式建模,截至2020年8月的百分比分布如下所示,由于架構的簡單性和與傳統ZooKeeper基于鎖的解決方案的概念相似性,百分之六十七的應用程式是僅主的應用程式,但是,就服務器數量而言,僅主的應用程式僅占17%,這意味著僅主的應用程式平均比其他兩種型別的應用程式小,

使用Shard Manager構建應用程式
在應用程式所有者決定如何將其作業負載/資料切成分片以及哪種應用程式型別適合其需求之后,無論用例如何,在Shard Manager上構建分片應用程式都需要執行三個簡單的標準化步驟,
- 應用程式鏈接了Shard Manager庫,并通過插入其業務邏輯來實作分片狀態轉換介面,
- 應用程式所有者提供基于意圖的規范來配置約束,Shard Manager提供了四組主要的開箱即用功能:容錯,負載平衡,分片擴展和操作安全性,
- 應用程式客戶端使用公共路由庫來路由特定于分片的請求,
分片管理器的設計與實作
在Facebook,我們的整體基礎架構是采用分層方法構建的,各層次之間的關注點清晰分開,這使我們能夠獨立,穩健地發展和擴展每一層,下圖顯示了基礎架構的層次結構,每一層分配并定義相鄰上層操作的范圍,

- 主機管理:資源配額系統管理所有物理服務器,并為組織和團隊分配容量,
- 容器管理:Twine從資源配額系統獲取容量,并將其分配給以容器為單位的各個應用程式,
- 分片管理:分片管理器在Twine提供的容器內為分片應用程式分配分片,
- 分片應用程式:在每個分片中,應用程式分配并運行關聯的作業負載,
- 產品:這些是面向用戶的產品,例如移動應用程式,由分片的后端應用程式提供支持,
除了每一層在相鄰較低層上的向下功能依賴關系之外,整個基礎結構堆疊都經過代碼簽名,并通過向上傳播的信號和事件協同作業,特別是對于Shard Manager層,TaskControl是我們實作協作調度的機制,
架構
Shard Manager的體系結構如下:

- 應用程式所有者向Shard Manager Scheduler提供了一個規范,其中包含管理應用程式所需的所有資訊,
- Shard Manager Scheduler是協調分片過渡和移動的中央服務,它收集應用程式狀態;監視狀態更改,例如服務器連接,服務器故障和負載更改;調整分片分配;并通過對應用程式服務器的RPC呼叫來驅動分片狀態轉換,Shard Manager Scheduler在內部被分片以橫向擴展,
- 應用程式 鏈接Shard Manager庫,該庫通過連接到ZooKeeper來提供服務器成員身份和活動檢查的透明度,應用程式實作分片狀態轉換介面,并由分片管理器調度程式指示狀態轉換,應用程式可以測量和公開由Shard Manager Scheduler收集的動態負載資訊,
- 分片管理器調度程式將分片分配的公共視圖發布到高度可用且可擴展的服務發現系統,該系統將資訊傳播到應用程式客戶端以路由請求,
- 應用程式客戶端鏈接一個通用路由庫,該路由庫在每個分片的基礎上封裝了服務器端點的發現,端點發現后,客戶端請求將直接發送到應用程式服務器,因此,分片管理器調度程式不在請求服務的關鍵路徑上,
總結
Shard Manager提供了用于構建分片應用程式的通用平臺,用戶只需要實作分片狀態轉換介面,并通過基于意圖的規范來表達分片約束,該平臺與Facebook生態系統的其余部分完全集成,這使整體基礎結構隱藏了基礎架構的復雜性,并使我們的工程師能夠專注于其應用程式和產品的核心業務邏輯,
Shard Manager從九年前開始發展,但是旅程還遠未完成,我們將繼續努力提供一流的解決方案,以在Facebook上構建分片服務,
盡管我們取得了成功,但我們仍在多個方面擴展Shard Manager的規模和功能,以下是我們計劃在未來幾年應對的各種挑戰:
- 通過在內部將應用程式劃分為較小的獨立磁區,每個應用程式可支持數千萬個分片,以滿足不斷增長的大型應用程式的需求,
- 通過提供更高的模塊化和可插入性以供用戶自定義,同時使Shard Manager保持簡單,從而支持更復雜的應用程式,
- 簡化了當前抽象過于繁瑣的小型,簡單應用程式的長尾使用體驗,
通過展示構建通用分片解決方案的可行性,我們希望我們可以促進進一步的討論,并幫助圍繞技術領域中這一前沿問題共同推動該領域的發展,
banq注:資料庫分片其實是業務資料切分,DDD有界背景關系提供一種方式,哈希一致性是從演算法角度試圖來解決,但是FB經驗說明這種一刀切的辦法不具有通用性,只能根據不同的領域進行不同的切分,FB這種分片管理器平臺是一種有狀態服務平臺,不同于K8s那種無狀態服務平臺,分片管理器屬于分布式事務實作的一種方式,
分片簡介
人們熟悉分片作為擴展服務以支持高吞吐量的一種方式,下圖說明了典型Web堆疊的縮放比例,Web層通常是無狀態的,并且易于擴展,由于任何服務器都可以處理任何請求,因此可以使用多種通信量路由策略,例如輪循或隨機,

另一方面,縮放資料庫部分由于其狀態是不平凡的,我們需要應用一種方案來確定性地跨服務器分布資料,像散列這樣的簡單散列方案hash(data_key) % num_servers 可以散布資料,但是當按比例添加服務器時,存在將資料混排的問題,一致性哈希通過僅將一小部分資料從現有服務器重新分配到新服務器來解決此問題,但是,此方案要求應用程式具有細粒度的鍵才能使統計負載平衡有效,由于其本質,一致性哈希支持基于約束的分配的能力(例如,應將歐洲聯盟用戶的資料存盤在歐洲資料中心以降低延遲),結果,只有某些型別的應用程式(例如分布式快取)才采用此方案,
一種替代方案是將資料顯式磁區為分配給服務器的分片,數十億用戶的資料存盤在許多資料庫實體中,每個實體都可以視為一個分片,為了提高容錯能力,每個資料庫分片可以具有多個副本(又名副本),每個副本都可以發揮不同的作用 (例如,主要或次要),具體取決于一致性要求,
明確分配給服務器的分片具有合并各種約束(例如,哈希解決方案無法支持的位置首選項)的能力,我們發現分片方法比散列方法更靈活,并且適合更廣泛的分布式應用程式的需求,
采用這種分片方法的應用程式通常需要某些分片管理功能才能可靠地大規模運行,最基本的功能是故障轉移功能,如果發生硬體或軟體故障,系統可以將客戶端流量從故障服務器轉移開,甚至可能需要在運行狀況良好的服務器上重建受影響的副本,在大型資料中心中,服務器始終計劃停機以執行硬體或軟體維護,分片管理系統需要通過主動將副本從服務器上移開以確保每個分片具有足夠的正常副本,以便在必要時將其洗掉,
另外,可能不均勻且不斷變化的分片負載需要負載平衡,這意味著必須動態調整每個服務器主機的分片集,以實作統一的資源利用率并提高整體資源效率和服務可靠性,最后,客戶端流量的波動需要分片擴展,系統在每個分片的基礎上動態調整復制因子,以確保其平均每個副本負載保持最佳狀態,
我們發現,Facebook的不同服務團隊已經在構建自己的自定義解決方案,以實作不同程度的完整性,常見的情況是,服務能夠處理故障轉移,但是負載平衡的形式非常有限,這導致次優的可靠性和較高的操作開銷,這就是為什么我們將Shard Manager設計為通用的分片管理平臺的原因,
使用分片管理器將分片作為平臺
多年來,已將數百個分片應用程式構建或遷移到Shard Manager上,具有歷史超增長的上十萬個服務器上總共有上千萬個分片副本,這些應用程式有助于各種面向用戶的產品(包括Facebook應用程式,Messenger,WhatsApp和Instagram)的平穩運行,
首先,與Shard Manager集成意味著簡單地實作一個由add_shard 和原語組成的小而直接的界面drop_shard ,其次,每個應用程式都可以通過基于意圖的規范來宣告其可靠性和效率要求,第三,使用通用約束優化求解器使Shard Manager能夠提供通用的負載平衡功能,并輕松添加對新平衡策略的支持,
最后但并非最不重要的一點是,通過完全集成到包括容量和容器管理在內的整個基礎架構生態系統中,Shard Manager不僅支持分片應用程式的高效開發,而且還支持分片應用程式的安全運行,因此提供了端到端解決方案,這是同類平臺所沒有的提供,與類似的平臺(例如基于Hex的Apache Helix)(包括基于Paxos的存盤系統用例)相比,Shard Manager支持更復雜的用例,
Shard Manager應用程式的型別
我們在Shard Manager上抽象了應用程式的通用性,并將它們分為三種型別:僅主,僅次和主次,
僅主Primary only:
主副本**:**每個分片都有一個副本,稱為主副本,這些型別的應用程式通常將狀態存盤在外部系統中,例如資料庫和資料倉庫,一個常見的范例是,每個分片代表一個作業程式,該作業程式使用諸如批處理之類的可選優化來獲取指定的資料,對其進行處理,有選擇地服務于客戶端請求并回寫結果,流處理是一個真實的示例,它處理來自輸入流的資料并將結果寫入輸出流,Shard Manager提供了至多一項主要保證,以幫助防止由于重復資料處理而導致的資料不一致,就像傳統的基于ZooKeeper鎖的方法一樣,
僅次Secondaries only:
節點**:**每個分片具有多個角色相同的副本,稱為輔助節點,來自多個副本的冗余提供了更好的容錯能力,此外,可以根據作業負載調整復制因子:熱分片可以具有更多副本來分散負載,通常,這些型別的應用程式是只讀的,沒有很強的一致性要求,他們從外部存盤系統中獲取資料,可選地處理資料,在本地快取結果,并根據本地資料提供查詢,一個真實的例子是機器學習推理系統,該系統從遠程存盤中下載經過訓練的模型并服務于推理請求,
主次
節點**:**每個分片具有主次節點兩個角色的多個副本,這些型別的應用程式通常是對資料一致性和持久性有嚴格要求的存盤系統,其中主副本接受寫請求并驅動所有副本之間的復制,而輔助副本提供冗余,并且可以選擇提供讀取以減少主副本上的負載,一個示例是ZippyDB,它是具有基于Paxos的復制的全域鍵值存盤,
我們發現以上三種型別可以在Facebook上對大多數分片應用程式建模,截至2020年8月的百分比分布如下所示,由于架構的簡單性和與傳統ZooKeeper基于鎖的解決方案的概念相似性,百分之六十七的應用程式是僅主的應用程式,但是,就服務器數量而言,僅主的應用程式僅占17%,這意味著僅主的應用程式平均比其他兩種型別的應用程式小,

使用Shard Manager構建應用程式
在應用程式所有者決定如何將其作業負載/資料切成分片以及哪種應用程式型別適合其需求之后,無論用例如何,在Shard Manager上構建分片應用程式都需要執行三個簡單的標準化步驟,
- 應用程式鏈接了Shard Manager庫,并通過插入其業務邏輯來實作分片狀態轉換介面,
- 應用程式所有者提供基于意圖的規范來配置約束,Shard Manager提供了四組主要的開箱即用功能:容錯,負載平衡,分片擴展和操作安全性,
- 應用程式客戶端使用公共路由庫來路由特定于分片的請求,
分片管理器的設計與實作
在Facebook,我們的整體基礎架構是采用分層方法構建的,各層次之間的關注點清晰分開,這使我們能夠獨立,穩健地發展和擴展每一層,下圖顯示了基礎架構的層次結構,每一層分配并定義相鄰上層操作的范圍,

- 主機管理:資源配額系統管理所有物理服務器,并為組織和團隊分配容量,
- 容器管理:Twine從資源配額系統獲取容量,并將其分配給以容器為單位的各個應用程式,
- 分片管理:分片管理器在Twine提供的容器內為分片應用程式分配分片,
- 分片應用程式:在每個分片中,應用程式分配并運行關聯的作業負載,
- 產品:這些是面向用戶的產品,例如移動應用程式,由分片的后端應用程式提供支持,
除了每一層在相鄰較低層上的向下功能依賴關系之外,整個基礎結構堆疊都經過代碼簽名,并通過向上傳播的信號和事件協同作業,特別是對于Shard Manager層,TaskControl是我們實作協作調度的機制,
架構
Shard Manager的體系結構如下:

- 應用程式所有者向Shard Manager Scheduler提供了一個規范,其中包含管理應用程式所需的所有資訊,
- Shard Manager Scheduler是協調分片過渡和移動的中央服務,它收集應用程式狀態;監視狀態更改,例如服務器連接,服務器故障和負載更改;調整分片分配;并通過對應用程式服務器的RPC呼叫來驅動分片狀態轉換,Shard Manager Scheduler在內部被分片以橫向擴展,
- 應用程式 鏈接Shard Manager庫,該庫通過連接到ZooKeeper來提供服務器成員身份和活動檢查的透明度,應用程式實作分片狀態轉換介面,并由分片管理器調度程式指示狀態轉換,應用程式可以測量和公開由Shard Manager Scheduler收集的動態負載資訊,
- 分片管理器調度程式將分片分配的公共視圖發布到高度可用且可擴展的服務發現系統,該系統將資訊傳播到應用程式客戶端以路由請求,
- 應用程式客戶端鏈接一個通用路由庫,該路由庫在每個分片的基礎上封裝了服務器端點的發現,端點發現后,客戶端請求將直接發送到應用程式服務器,因此,分片管理器調度程式不在請求服務的關鍵路徑上,
總結
Shard Manager提供了用于構建分片應用程式的通用平臺,用戶只需要實作分片狀態轉換介面,并通過基于意圖的規范來表達分片約束,該平臺與Facebook生態系統的其余部分完全集成,這使整體基礎結構隱藏了基礎架構的復雜性,并使我們的工程師能夠專注于其應用程式和產品的核心業務邏輯,
Shard Manager從九年前開始發展,但是旅程還遠未完成,我們將繼續努力提供一流的解決方案,以在Facebook上構建分片服務,
盡管我們取得了成功,但我們仍在多個方面擴展Shard Manager的規模和功能,以下是我們計劃在未來幾年應對的各種挑戰:
- 通過在內部將應用程式劃分為較小的獨立磁區,每個應用程式可支持數千萬個分片,以滿足不斷增長的大型應用程式的需求,
- 通過提供更高的模塊化和可插入性以供用戶自定義,同時使Shard Manager保持簡單,從而支持更復雜的應用程式,
- 簡化了當前抽象過于繁瑣的小型,簡單應用程式的長尾使用體驗,
通過展示構建通用分片解決方案的可行性,我們希望我們可以促進進一步的討論,并幫助圍繞技術領域中這一前沿問題共同推動該領域的發展,
banq注:資料庫分片其實是業務資料切分,DDD有界背景關系提供一種方式,哈希一致性是從演算法角度試圖來解決,但是FB經驗說明這種一刀切的辦法不具有通用性,只能根據不同的領域進行不同的切分,FB這種分片管理器平臺是一種有狀態服務平臺,不同于K8s那種無狀態服務平臺,分片管理器屬于分布式事務實作的一種方式,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/252118.html
標籤:其他
下一篇:deepin20.1系統安裝MySQL8.0.23(最美國產Liunx系統,最新,最詳細的MySQL8安裝教程)
