百億級小文件存儲,JuiceFS 在自動駕駛行業的最佳實踐


自動駕駛是最近幾年的熱門領域,專注於自動駕駛技術的創業公司、新造車企業、傳統車廠都在這個領域投入了大量的資源,推動着 L4、L5 級別自動駕駛體驗能盡早進入我們的日常生活。

自動駕駛技術實現的核心環節是自動駕駛模型的訓練,訓練數據是由汽車實際采集回來的真實道路駕駛視頻,數據規模有數 PB 到數十 PB 之多。在模型訓練之前,先要對這些原始視頻進行處理,截取其中的關鍵幀保存為照片。然后再由專業數據標注團隊在圖片上標記關鍵信息,比如紅綠燈、道路標記等。最終經過標記的數十億圖片和標記數據成為真正要「喂給」訓練框架的內容。

熟悉分布式系統和分布式存儲的朋友一定知道,LOSF(Lots of Small Files,海量小文件)是存儲領域的大難題。而在人工智能 CV(Computer Vision)領域中基於 LOSF 的訓練又是剛需,包括自動駕駛、人臉識別、物體檢測等細分領域。

本篇文章來自 JuiceFS 某自動駕駛行業客戶的架構實踐,在百億規模小文件訓練場景下進行了一系列成功的探索,希望能為相關行業的應用帶來一些參考和啟發。

百億小文件管理的極致挑戰

自動駕駛系統的訓練數據集大多有數十億到數百億小文件(小於 1MiB 的文件),一次訓練通常需要數千萬到數億文件。而且訓練 worker 每一次生成 mini-batch 都需要頻繁訪問存儲系統,其中大部分是對元數據的請求,因此,元數據性能直接影響模型訓練的效率。

這就要求存儲系統不僅要具備管理百億文件的能力,還必須在高並發請求下,保持低時延、高吞吐的元數據性能。

在存儲系統選型中,對象存儲是能夠承載百億規模文件的,但是缺少原生目錄支持、缺少完整 POSIX 語義支持、元數據性能弱這三方面的問題讓對象存儲並不適合海量小文件訓練場景。

在一些常見的分布式文件系統架構設計中,HDFS 並不適合存儲小文件,雖然可以采用 Scale-Up NameNode 和聯邦(federation)的方式容納一定規模的數據,但要存儲百億級小文件依然是一件非常困難的事情;CephFS 的 MDS 雖然有 Scale-Out 能力,但單進程的並發處理能力不高,隨着 MDS 集群規模的增長進程間協調開銷增大,使得整體性能達不到線性增長。

雖然在 TensorFlow 中支持將多個小文件合並成大文件的 TFRecord 格式來降低訓練過程中對存儲系統的元數據負載壓力,但是在自動駕駛領域,這種方案降低了數據集隨機取樣的精度,而且其它訓練框架(如 PyTorch)也不兼容,造成很多不便。

JuiceFS 如何解決?

JuiceFS 是面向雲原生環境設計的開源分布式文件系統,JuiceFS 的創新在於:

  • 可以用任意對象存儲作為數據持久層,保存數據內容。無論任何公有雲、私有雲環境,只要有對象存儲服務,都能用 JuiceFS;
  • 100% 兼容 POSIX、HDFS、S3 三大主流訪問協議,能對接所有應用;
  • 元數據引擎是可插拔架構,支持包括 Redis、TiKV、MySQL 等多種數據庫作為存儲引擎,同時,也提供兼具高性能和海量存儲的商用元數據引擎。

JuiceFS 的商用元數據引擎采用 Raft 算法組成分布式集群,保證數據的可靠性、一致性和高可用性。元數據全部存儲在節點的內存中,保證低時延響應。元數據引擎采用動態目錄樹方案進行橫向擴展,每個分片(shard)是一個獨立的 Raft 組,文件系統目錄樹可以任意划分,分配到需要的分片中,自動均衡與手動均衡相結合。分片機制對於客戶端訪問透明。

靈活配置緩存大幅提升訓練效率

既然訓練任務需要頻繁訪問存儲系統,每次經過網絡的開銷疊加起來也是不小的冗余,目前工業界都在探索存儲與計算分離后的緩存加速方案。JuiceFS 已經內置了緩存能力,客戶端訪問過的數據,可以自動緩存在該節點指定的存儲介質上,下次訪問就能直接命中緩存,不用再通過網絡讀取。同樣,元數據也會自動緩存到客戶端內存中。

緩存機制在使用上是透明的,無需改變現有應用,只要在 JuiceFS 客戶端掛載時添加幾個參數,說明緩存的路徑、容量等信息即可。緩存對於訓練加速的效果非常明顯,可以參考我們另外一篇文章「如何借助 JuiceFS 為 AI 模型訓練提速 7 倍」。緩存不僅能加速訓練,還能顯著減少對象存儲 API 的調用,從而降低費用開銷。

對於分布式訓練平台來說,相同的訓練數據可能會被不同的任務共享,這些任務不一定會被調度到同一個節點上,如果是分布在不同節點那緩存數據還能共享嗎?利用 JuiceFS 的「緩存數據共享」特性,多個訓練節點共同組成一個緩存集群,在這個集群中的訓練任務都可以共享緩存數據。也就是說當訓練任務所處的節點沒有命中緩存時,能夠通過同一集群中的其它節點來獲取數據,而不用去請求遠端的對象存儲。

訓練節點可能不是一個靜態的資源,特別是在容器平台里,生命周期的變換是很快的,是否會影響緩存數據共享的效果呢?這就要引出下一個問題。

緩存機制在彈性集群中的挑戰

每一家自動駕駛領域的公司都有很多算法研究員、工程師,他們的算法要共享公司的計算資源完成訓練和驗證。從平台角度講,資源彈性伸縮是一個提高整體利用率的好方法,按需給每個訓練任務分配資源,避免浪費。

但在這種彈性伸縮的集群中,前面提到的本地緩存數據會受到一定影響。雖然緩存集群通過一致性哈希確保了當集群成員發生變化時,需要遷移的數據盡量少,但是對於大規模的訓練集群來說這樣的數據遷移還是會對整體的訓練效率造成影響。

有沒有一種方法既能滿足訓練集群資源彈性伸縮的需求,又不顯著影響模型訓練效率呢?

這就需要 JuiceFS 獨有的「獨立緩存集群」特性了。

所謂獨立緩存集群,就是將負責存儲緩存數據的節點獨立部署,提供常駐的緩存數據服務。這樣不會受訓練集群動態變化的影響,讓訓練任務有更高、更穩定的緩存命中率。

整體系統的架構如下圖所示:

比如有一個動態的訓練集群 A 和專門用來做緩存的集群 B,他們都需要使用相同的掛載參數 --cache-group=CACHEGROUP 來構建一個緩存組,其中集群 A 的節點掛載時需要加上 --no-sharing 參數。當集群 A 的應用讀數據時,如果當前節點的內存和緩存盤上沒有該緩存數據,它就會根據一致性哈希從集群 B 中選擇一個節點來讀取數據。

此時整個系統由 3 級緩存構成:訓練節點的系統緩存、訓練節點的磁盤緩存、緩存集群 B 中的緩存,用戶可以根據具體應用的訪問特點配置各個層級的緩存介質和容量。

為了確保當磁盤損壞時不會對訓練任務產生影響,JuiceFS 還提供了緩存數據容災能力。如果緩存節點的磁盤意外損壞,更換新的磁盤后 JuiceFS 可以自動重建需要的緩存數據。

如何實現混合雲中的降本增效?

自動駕駛的訓練任務需要大量的 GPU 資源,在充分利用的情況下,自己在機房中采購 GPU,可以比使用公有雲便宜不少,這也是目前很多自動駕駛公司的選擇。但是,在機房中自建存儲系統則沒這么簡單,會遇到兩個挑戰:

  • 數據增長快,采購很難跟上擴容速度,一次買太多,又會造成浪費;
  • 維護大規模的存儲集群,必須面對磁盤損壞等問題,運維成本高,效率低;

相比自建存儲系統,公有雲上的對象存儲服務可以彈性伸縮,無限擴容,單位成本便宜,數據的可靠性和服務的可用性相比機房自建存儲都更高,是存儲海量數據的不錯選擇。

JuiceFS 非常適合這種 IDC 機房 + 公有雲的混合雲架構。用戶將自己的 IDC 機房與公有雲專線連接,數據通過 JuiceFS 持久化到公有雲對象存儲中,在 IDC 機房里設置一個緩存集群,起到緩存數據加速訓練的效果,相比每次從對象存儲訪問數據,既能節省專線帶寬,還能節省對象存儲 API 調用費用。

當混合雲架構結合 JuiceFS 之后,既享受了雲存儲帶來的便利,又通過自建 IDC 降低了 GPU 成本。對於訓練平台的使用者、維護者來說都非常簡單方便,滿足企業多樣化的基礎設施架構設計需求。

多機房的數據同步與管理

在這個實踐案例中,客戶有兩個 IDC,相距上千公里,訓練任務也會被分配到兩個 IDC 中,因此數據集也需要在兩個 IDC 中被訪問。之前,客戶是手工維護將數據集復制到兩個 IDC 中。使用 JuiceFS 后,「數據鏡像」特性可以省去此前的手工勞動,數據實時同步,滿足多地協同工作的需求。

具體來說,數據鏡像功能需要在兩個 IDC 中都部署 JuiceFS 的元數據集群,當數據鏡像啟用后,原始文件系統會自動將元數據復制到鏡像區域。鏡像文件系統被掛載后,客戶端會從原始文件系統的對象存儲拉取數據,寫入到鏡像文件系統的對象存儲。鏡像文件系統掛載后,數據會優先從本地的對象存儲讀取,如果因同步未完成而出現讀取失敗,則會嘗試從原始文件系統的對象存儲讀取。

啟用數據鏡像后,所有數據可以自動復制到兩個對象存儲中,起到異地災備的作用。如果不需要異地災備,在鏡像區域可以不配置對象存儲,只進行元數據的復制,數據可以提前預熱到鏡像區域的獨立緩存集群來加速訓練。這樣可以省去一份對象存儲的成本,本案例中的客戶就采用了此方案。

全方位數據安全保護

不管是為了實現輔助駕駛還是真正的自動駕駛,日常都需要通過路采車收集大量的路采數據,這些數據會再經過一些處理流程二次加工以后最終存儲到企業的存儲系統中。自動駕駛企業對於這些數據的安全性和可靠性有着極高的要求,因此數據保護是一個非常關鍵的問題。

我們首先來看看企業上雲以后的安全問題。很多時候企業對於上雲會存在一定的數據安全擔憂,特別是當涉及到一些敏感數據時。JuiceFS 提供的「數據加密」特性同時支持傳輸中加密(encryption in transit)和靜態加密(encryption at rest),保障上雲過程中各個環節的數據安全性。

其次可能面臨的是數據管理問題。為了防止數據泄漏或誤操作,企業可能需要針對不同團隊、不同用戶進行權限管理和控制。JuiceFS 托管服務通過「訪問令牌」可以限定某個 IP 范圍的讀寫權限以及可訪問的子目錄。掛載之后,JuiceFS 支持基於「用戶/用戶組」 的權限管理模型,可以靈活針對團隊或者個人進行權限設置。

如果某個用戶已經具備訪問某些數據的權限,也還是需要進一步對數據進行保護,比如用戶可能誤刪除或者誤更新數據。對於誤刪除,JuiceFS 托管服務提供的「回收站」功能可以確保數據被刪除以后的一段時間內能夠再次恢復。

但是如果數據被誤更新了或者因為某種原因損壞了,即使有回收站也無濟於事,此時 JuiceFS 的「實時數據保護」特性就非常有用了。這個功能的實現原理是保留一定時間的 Raft 日志,這樣當數據誤更新發生時可以通過回放歷史日志的方式將當時的元數據恢復。同時由於 JuiceFS 寫入對象存儲的文件是分塊(block)存儲,更新文件不會修改歷史的 block 而是生成新的 block,因此只要對象存儲上的歷史 block 還沒有被刪除就可以完整恢復數據,就像一個可以隨時時光倒流的「時間機器」一樣!

總結

完整架構設計

下圖是本案例的整體架構圖,在機房 A、B 中都部署了 JuiceFS 的元數據集群以及對應的獨立緩存集群,模型訓練時將會優先通過緩存集群讀取數據集,如果緩存沒有命中再從對象存儲讀取數據。在實際測試中,因為緩存命中率非常高,機房 B 幾乎不需要跨機房訪問對象存儲。

下圖描述了數據寫入流程。客戶通過 JuiceFS 提供的 S3 網關寫入數據。當新數據寫入以后,就會按照前面介紹的數據鏡像流程來將元數據復制到另一個機房。同時在兩個機房中都有對應的任務負責預熱獨立緩存集群,確保新數據能夠及時建立緩存。

客戶收益

這套方案已經上線到客戶生產環境中,下面列一些重要指標:

  • 已經存儲了數十億的文件,仍在持續增長;
  • JuiceFS 元數據在數十萬 QPS 壓力下依然能提供 1ms 時延響應;
  • 模型訓練吞吐數十 GiB/s;
  • 獨立緩存集群命中率 95%+;
  • 兩個 IDC 之間數據同步的平均時延在數十毫秒級別。

通過升級到基於 JuiceFS 的存儲系統,客戶不僅能夠輕松管理好海量數據集,同時借助 JuiceFS 的獨立緩存集群特性保證了模型訓練的效率。運維成本顯著降低的同時,機房 + 公有雲的混合雲架構相比單一公有雲的架構 TCO 也更低,既能利用機房高性價比的計算資源,也能結合公有雲上彈性的存儲資源

得益於 JuiceFS 完全兼容 POSIX 的特性,客戶在遷移過程中,訓練任務的代碼不需要做任何修改。

通過 JuiceFS 的數據鏡像特性,自動地將數據從一個機房同步到另一個機房,解決多地協作問題,也滿足了企業異地災備的需求。

推薦閱讀:
Elasticsearch 存儲成本省 60%,稿定科技干貨分享

項目地址: Github (https://github.com/juicedata/juicefs)如有幫助的話歡迎關注我們喲! (0ᴗ0✿)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM