AI 場景的存儲優化之路(二)

前言

回顧上一篇《AI 場景的存儲優化之路》中,我們分析了AI場景中分佈式文件存儲面臨三大挑戰:海量文件、小文件訪問性能、目錄熱點,其中對目錄熱點問題做了詳細分析,並介紹了YRCloudFile在該問題上的方案實現。

而文中提到的元數據的靜態子樹、動態子樹、目錄hash三種分佈模式,抽象出來,大致對應集中式、分佈式、無元數據三種架構模型,這三種模型是業界通用的元數據管理方式,在特定業務場景中,各有所長,集中式模型的問題在於單點故障、性能孤島等;分佈式模型的問題在於主從同步的性能開銷,一致性問題等;無元數據模型的問題在於它通常使用用類似DHT計算方式替代查詢,這破壞了元數據中對於文件系統的樹形拓撲結構,導致元數據性能不高。所以沒有說哪一種方案可以在所有業務場景中,都能保持最優的性能。在實際的產品設計中,依據產品定位,需要做一定的取捨。

架構設計 

無論是設計針對AI場景,還是針對通用場景的存儲產品,對於一個企業級存儲產品而言,數據可靠性、可用性以及性能是架構層面首先要考慮的要素。

企業級存儲產品,首先需要保證數據的可靠性,然後才能談數據的高性能和高可用。因爲對於絕大部分應用場景,存儲的數據都必須是有狀態的,所以不保證數據可靠性的存儲,應用是無法使用的。

數據的可靠性保證,從架構上首先要避免單點故障,單點故障可能會導致的數據不可恢復,此外單點故障還會引入很多其它問題,如系統可用性低、性能瓶頸等。對於已經持久化的數據,也要防止靜默數據損壞,存儲層面的數據掃描以及驅動層的520扇區校驗等機制也十分必要。因此很多分佈式塊或文件存儲產品,都會在應用不感知的前提下,週期性地做數據檢查,一方面能儘早發現並修復靜默數據錯誤和集羣中副本間不一致的數據,另一方面也是集羣健康狀態監控的需要,通過數據檢查,可以發現集羣業務延時是否合理,集羣是否異常導致IO hang等情況。從業務層面看,架構上對數據可靠性的設計也反映了對於一致性的要求,上層應用是期望最終一致性還是強一致性,在多客戶端併發訪問公共存儲資源場景中,業務端觀測到的數據一致性就變得更復雜,這些考量最終會體現在存儲的架構設計上。

數據的可用性保證,一般元數據用副本,數據存儲用副本或糾刪碼(EC)來實現HA,無論是元數據和存儲服務、副本之間數據一致性策略、主從切換策略、集羣視圖推送策略,還是可升級維護性等,都是複雜的技術環節。這些問題會因爲集羣規模變大而被進一步放大,任何一步處理不當,都有可能導致數據錯誤,因此在設計上,所有場景的處理必須保證閉環,處理上也會更傾向於保守策略。

爲了實現數據讀寫的高性能,在軟件層面,需要儘可能地提高併發度,儘量降低處理中的串行化比重。例如,由於控制流和數據流的分離,客戶端從元數據服務器獲取控制權或資源後,將直接和存儲集羣進行IO交互,或是爲保證操作的合法性以及數據的一致性,在集羣恢復時發生的IO交互,在交互過程中,不可避免會遇到需要串行化處理的地方,這種串行化佔比越高,對分佈式集羣的性能影響越大。

實現思路 

架構設計是產品性能的基本保證,代碼實現決定產品性能的上限。YRCloudFile在設計之初,分析了衆多方案,取各個架構的優點,在確保數據可靠性的前提下,通過不斷迭代提高產品的可用性和性能。

分佈式文件存儲提供全局統一命名空間,對於客戶而言,就是一個獨立的掛載目錄,空間和文件個數將不會受到限制。後端將不同存儲介質資源池化成多個存儲池,而存儲資源可以根據空間需要,在虛擬存儲池中進行彈性擴展擴容,元數據爲了性能和空間需要進行橫向擴展,做到擴容對應用透明。

系統拓撲大致如下:

 

提升大文件IO的吞吐性能

在保證大文件IO的吞吐性能方面,要儘可能地縮短IO路徑,減少內存拷貝和上下文切換等操作,採用常見的將控制流和數據流(即元數據和數據存儲)分離方案,客戶端在獲得文件訪問控制權後,直接對後端存儲分片進行併發訪問。對文件屬性的更新採用的lazy模式,即在客戶端調用close時更新MDS中的文件信息。這種方式能夠減少對MDS更新的頻率,可以提高IO性能,但副作用是文件的元數據信息沒有及時更新,IO期間stat操作無法獲取最新的信息。可以在元數據服務中引入ServerType + ServerNodeID + GloballyUniqueFileID組成sessionMap,來區分該文件目前的狀態,決定stat時,是否從後端存儲獲取最新信息並更新及返回,從而兼顧在更新文件時,對文件進行stat的少數請求。

提升小文件IO訪問性能

小文件IO訪問性能方面,考驗的是元數據的性能,一方面要支持海量文件,另一方面還要支持高效的元數據操作。我們的集羣整個命名空間目錄樹由元數據集羣來維護,系統目錄樹架構:基於該架構實現的元數據集羣,如果基於本地文件系統做元數據服務,那麼瓶頸就在於本地文件系統(如海量文件性能,單目錄文件個數,單臺服務器性能瓶頸等),基於DB管理裸盤元數據服務,能較好避免上述問題,但還是會存在上圖中MDS4的單目錄海量文件的增刪改查的性能問題,解決方案就是子目錄拆分,下面討論下基於該方案的一致性訪問控制。

多客戶端的一致性訪問

作爲一個分佈式文件系統,多個客戶端會併發訪問集羣內的文件,由於客戶端間各自獨立,互相不感知,數據一致性就需要存儲集羣來保證,在元數據集羣中,對被訪問的文件資源進行保護,能保證應用在併發訪問時候,看到的數據是一致的。爲保證業務數據實時持久化,保證集羣出現軟硬件異常或整集羣掉電重啓後,業務數據的一致性,一般都是採用分佈式集羣鎖,例如zookeeper的順序臨時節點、通過向某數據結構中插入key是否成功作爲併發訪問控制的依據。

在上圖的樹形架構中,可以基於MDS實現文件、目錄級別的鎖,從而達到多客戶端併發訪問控制的目的。鎖可以在MDS進行細粒度實現,雖然鎖的細粒度化,必然會增加MDS服務器的壓力,但由於YRCloudFile的MDS集羣是多臺服務器組成,還可以不斷橫向擴展,大量的MDS節點會分攤鎖的壓力,性能上是可以保證的。

維護語義的正確性和操作的冪等性

分佈式系統中,在客戶端請求的整個生命週期中,任何地方都有可能由於各類軟硬件異常導致的請求重試,尤其在主從切換場景中,這時就需要保證語義的正確性和操作的冪等性。

因此,從客戶端發起的某個請求,在其整個生命週期內都是可以被跟蹤的,我們用GUID+ServerType + ServerNodeID + GloballyUniqueFileID組成唯一的請求ID,在任何一個階段都需要緩存其執行結果,即使在各個階段存在重試,也可實現操作的正確性和冪等性。

基於AI場景的針對性優化

現在非結構化數據迅速增長,分佈式文件存儲已成爲對非結構化數據進行管理的一個普遍接受的解決方案,尤其AI場景中,以小文件讀多寫少爲主,對小文件而言,多客戶端併發訪問相同文件資源的情況不多,部分場景中甚至可容忍少量數據的丟失。因此,爲了針對AI特定的讀寫場景,實現高性能,開啓各類緩存就十分必要。

客戶端的優化

開啓客戶端讀寫緩存,可以複用系統pagecache。增大客戶端緩存失效時間,降低revalidate dentry操作的頻率。對於大塊IO寫請求,由於客戶端內存資源有限,爲避免緩存污染,可以將大塊IO直接寫入到後端存儲節點的緩存中,將小塊IO寫入到客戶端緩存中,後臺異步flush dirty數據到後端存儲。

增大客戶端緩存失效時間,降低revalidate dentry操作的頻度。文件的查找過程,就是從根目錄逐級往下找,系統dentry能加速這些操作,如果該文件路徑緩存命中,那麼就能快速找到對應的inode信息,然後就可以直接去元數據集羣去查找該文件了。

元數據性能優化

無論採用什麼模式的元數據管理方式,都需要從多維度考慮方案的性能問題,在分佈式系統中,單點硬件資源一般很難成爲瓶頸,而真正成爲瓶頸的還是某些特定IO流程,不可避免有串行化的地方,而這種串行化的比重越重,對分佈式集羣的性能的制約會更爲嚴重,所以元數據的優化首先要減少這種串行化的限制。

  1. 性能的local原則,在這棵樹形架構中,即同級目錄下的文件,元數據儘量分佈在同一個節點中,這樣能提供較好的本地化性能,而當該目錄下有上億的海量文件時,有需要將改目錄拆分,把壓力分佈在多個元數據服務中。
  2. 延遲化ops方式,即批量併發處理非相關性請求操作,可解決上圖中mds4的性能瓶頸。
  3. 降低mds負載,用緩存取代磁盤訪問,減少交互次數,避免上下文切換。所有和磁盤交互的地方,能異步儘量異步,如耗時的異步刪除等。

後端存儲優化 

充分利用後端存儲性能,如果後端存儲夠快,就用direct模式,如果不夠快,就依賴pagecache,如果是機械盤,就給他加緩存層等。

測試配置爲:客戶端爲E5-2603 v3 + 128G ddr4 ,存儲集羣爲2副本,有SSD給HDD加速。

開啓緩存前後性能對比圖:

 

總結 

本文主要分析了從設計到實現中,保證系統一致性和高性能的需要關注的點,以及在AI場景下,通過客戶端緩存進一步滿足客戶對高性能的需求,以及我們的優化思路,也希望藉此文和更多技術專家交流如何對AI場景下的存儲方案進行針對性的優化。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章