來源:Juicedata
近期,DeepSeek 開源了其文件系統(tǒng) Fire-Flyer File System (3FS),使得文件系統(tǒng)這一有著 70 多年歷時(shí)的“古老”的技術(shù),又獲得了各方的關(guān)注。在 AI 業(yè)務(wù)中,企業(yè)需要處理大量的文本、圖像、視頻等非結(jié)構(gòu)化數(shù)據(jù),還需要應(yīng)對數(shù)據(jù)量的爆炸式增長,分布式文件系統(tǒng)因此成為 AI 訓(xùn)練的關(guān)鍵存儲技術(shù)。
本文旨在通過深入分析 3FS 的實(shí)現(xiàn)機(jī)制,并與 JuiceFS 進(jìn)行對比,以幫助用戶理解兩種文件系統(tǒng)的區(qū)別及其適用場景。同時(shí),我們將探討 3FS 中的值得借鑒的創(chuàng)新技術(shù)點(diǎn)。
01 架構(gòu)對比
3FS
3FS[1](Fire-Flyer File System) 是一款高性能的分布式文件系統(tǒng),專為解決 AI 訓(xùn)練和推理工作負(fù)載而設(shè)計(jì),該系統(tǒng)使用高性能的 NVMe 和 RDMA 網(wǎng)絡(luò)提供共享存儲層。3FS 由 DeepSeek 在 2025 年 2 月開源。
3FS 主要包括以下模塊:
? 集群管理服務(wù)(Cluster Manager)
? 元數(shù)據(jù)服務(wù)(Metadata Service)
? 存儲服務(wù)(Storage Service)
? 客戶端 (FUSE Client、Native Client)
3FS 架構(gòu)
所有模塊通過 RDMA 網(wǎng)絡(luò)通信。元數(shù)據(jù)服務(wù)和存儲服務(wù)向集群管理服務(wù)發(fā)送心跳信號。集群管理服務(wù)負(fù)責(zé)處理成員變更,并將集群配置分發(fā)給其他服務(wù)和客戶端。為了提高系統(tǒng)的可靠性和避免單點(diǎn)故障,會部署多個(gè)集群管理服務(wù),其中一個(gè)被選為主節(jié)點(diǎn)。當(dāng)主節(jié)點(diǎn)發(fā)生故障時(shí),另一個(gè)管理器會被提升為主節(jié)點(diǎn)。集群配置通常存儲在可靠的分布式服務(wù)中,例如 ZooKeeper 或 etcd。
當(dāng)進(jìn)行文件元數(shù)據(jù)操作(例如打開或創(chuàng)建文件/目錄),請求被發(fā)送到元數(shù)據(jù)服務(wù),以實(shí)現(xiàn)文件系統(tǒng)語義。元數(shù)據(jù)服務(wù)有多個(gè),并且是無狀態(tài)的,它們不直接存儲文件元數(shù)據(jù),而是依賴支持事務(wù)的鍵值數(shù)據(jù)庫 FoundationDB 來存儲這些數(shù)據(jù)。因此,客戶端可以靈活地連接到任意元數(shù)據(jù)服務(wù)。這種設(shè)計(jì)使得元數(shù)據(jù)服務(wù)可以在沒有狀態(tài)信息的情況下獨(dú)立運(yùn)作,進(jìn)而增強(qiáng)了系統(tǒng)的可伸縮性和可靠性。
每個(gè)存儲服務(wù)管理若干本地 SSD,并提供 chunk 存儲接口。存儲服務(wù)采用 CRAQ ( Chain Replication with Apportioned Queries)來確保強(qiáng)一致性。3FS 中存儲的文件被拆分為默認(rèn) 512K 大小相等的塊,并在多個(gè) SSD 上進(jìn)行復(fù)制,從而提高數(shù)據(jù)的可靠性和訪問速度。
3FS 客戶端提供兩種接入方式:FUSE Client 和 Native Client。FUSE Client 提供常見 POSIX 接口的支持,簡單易用。Native Client 提供更高的性能,但是用戶需要調(diào)用客戶端 API ,具有一定的侵入性,下文我們還將對此作更詳盡的解析。
JuiceFS
JuiceFS 是一個(gè)云原生分布式文件系統(tǒng),其數(shù)據(jù)存儲在對象存儲中。社區(qū)版[2]可與多種元數(shù)據(jù)服務(wù)集成,適用場景廣泛,于 2021 年在 GitHub 開源。企業(yè)版專為高性能場景設(shè)計(jì),廣泛應(yīng)用于大規(guī)模 AI 任務(wù),涵蓋生成式 AI、自動駕駛、量化金融和生物科技等。
JuiceFS 文件系統(tǒng)包括三部分組成:
? 元數(shù)據(jù)引擎:用于存儲文件元數(shù)據(jù),包括常規(guī)文件系統(tǒng)的元數(shù)據(jù)和文件數(shù)據(jù)的索引。
? 數(shù)據(jù)存儲:一般是對象存儲服務(wù),可以是公有云的對象存儲也可以是私有部署的對象存儲服務(wù)。
? JuiceFS 客戶端:提供 POSIX(FUSE)、Hadoop SDK、CSI Driver、S3 網(wǎng)關(guān)等不同的接入方式。
JuiceFS 社區(qū)版架構(gòu)圖
架構(gòu)差異
從模塊劃分上看兩個(gè)文件系統(tǒng)差異不大,都采用了元數(shù)據(jù)與數(shù)據(jù)分離的設(shè)計(jì),各個(gè)模塊功能也較類似。不同于 3FS 和 JuiceFS 企業(yè)版,JuiceFS 社區(qū)版兼容多種開源數(shù)據(jù)庫存儲元數(shù)據(jù),對元數(shù)據(jù)的操作都封裝在客戶端,用戶不需要再單獨(dú)運(yùn)維一個(gè)無狀態(tài)的元數(shù)據(jù)服務(wù)。
存儲模塊
3FS 使用大量本地 SSD 進(jìn)行數(shù)據(jù)存儲,為了保證數(shù)據(jù)存儲的一致性,3FS 使用 CRAQ 這一簡潔的數(shù)據(jù)一致性算法 。幾個(gè)副本被組成一個(gè) Chain,寫請求從 Chain 的 Head 開始,一直到達(dá) Chain 的 Tail 時(shí)返回寫成功應(yīng)答。讀請求可以發(fā)送到 Chain 的所有副本,如果讀到臟節(jié)點(diǎn)的數(shù)據(jù),該節(jié)點(diǎn)會聯(lián)系 Tail 節(jié)點(diǎn)檢查狀態(tài)。如下圖所示。
CRAQ 一致性算法
數(shù)據(jù)的寫入是按順序逐節(jié)點(diǎn)傳遞,因此會帶來比較高的延時(shí)。如果 Chain 當(dāng)中的某個(gè)副本不可用, 3FS 會把這個(gè)副本移到 Chain 的末尾,等副本可用的時(shí)候再做恢復(fù)。恢復(fù)的時(shí)候需要把整個(gè) Chunk 的內(nèi)容復(fù)制到這個(gè)副本,而非使用不可用期間的增量數(shù)據(jù)。如果要做到同步寫所有副本和增量恢復(fù)數(shù)據(jù),那寫的邏輯會復(fù)雜非常多,比如 Ceph 使用 pg log 保證數(shù)據(jù)一致性。盡管 3FS 這種設(shè)計(jì)會導(dǎo)致寫延遲,但是對于以讀為主的 AI 應(yīng)用場景,影響不大。
JuiceFS 利用對象存儲作為數(shù)據(jù)存儲解決方案,從而可享有對象存儲帶來的若干優(yōu)勢,如數(shù)據(jù)可靠性、一致性等。存儲模塊提供了一組用于對象操作的接口,包括 GET/PUT/HEAD/LIST 等,用戶可以根據(jù)自己的需求對接具體的存儲系統(tǒng)。比如不同云廠商的對象存儲,也可以選擇私有部署的對象存儲比如 MinIO、Ceph RADOS 等系統(tǒng)。社區(qū)版 JuiceFS 提供本地緩存來應(yīng)對 AI 場景下的帶寬需求,JuiceFS 企業(yè)版使用分布式緩存滿足更大的聚合讀帶寬的需求。
元數(shù)據(jù)模塊
在 3FS 中,文件的屬性以 KV 的形式存儲在元數(shù)據(jù)服務(wù)中。該服務(wù)是一個(gè)無狀態(tài)的高可用服務(wù),依靠 FoundationDB 做支撐。FoundationDB 是 Apple 開源的優(yōu)秀分布式 KV 數(shù)據(jù)庫,具有很高的穩(wěn)定性。FoundationDB 所有鍵值使用 Key 做全局排序,然后均勻拆分到不同的節(jié)點(diǎn)上。
為了優(yōu)化 list 目錄的效率,3FS 使用字符 “DENT” 前綴加父目錄 inode 號和名字作為 dentry 的 Key。Inode 的 Key 是通過將 "INOD" 前綴與 inode ID 連接而構(gòu)造的,其中 inode ID 采用小端字節(jié)序編碼,以便將 inodes 分布到多個(gè) FoundationDB 節(jié)點(diǎn)上。這個(gè)設(shè)計(jì)與 JuiceFS 使用的TKV(Transactional Key-Value Database)[3]進(jìn)行元數(shù)據(jù)服務(wù)的存儲方式類似。
JuiceFS 社區(qū)版的元數(shù)據(jù)模塊,與存儲模塊類似也提供一組操作元數(shù)據(jù)的接口,可以接入不同的元數(shù)據(jù)服務(wù),比如 Redis,TiKV 等 KV 數(shù)據(jù)庫,MySQL,PostgreSQL 等關(guān)系型數(shù)據(jù)庫,也可以使用 FoundationDB。JuiceFS 企業(yè)版使用自研高性能元數(shù)據(jù)服務(wù),可根據(jù)負(fù)載情況來平衡數(shù)據(jù)和熱點(diǎn)操作,以避免大規(guī)模訓(xùn)練中元數(shù)據(jù)服務(wù)熱點(diǎn)集中在某些節(jié)點(diǎn)的問題(比如因?yàn)轭l繁操作臨近目錄文件的元數(shù)據(jù)引起)。
客戶端
3FS 的客戶端除了提供 FUSE 操作外,還提供了一組 API 用于繞過 FUSE 直接操作數(shù)據(jù),也就是 Native Client,接口的調(diào)用方式有點(diǎn)類似于 Linux AIO。這組 API 的作用是避免使用 FUSE 模塊帶來的數(shù)據(jù)拷貝,從而減少 I/O 延遲和對內(nèi)存帶寬的占用。下面將詳細(xì)解析這組 API 如何實(shí)現(xiàn)用戶進(jìn)程與 FUSE 進(jìn)程之間的零拷貝通信。
3FS 通過hf3fs_iov保存共享內(nèi)存的大小,地址和其他一些屬性,使用IoRing在兩個(gè)進(jìn)程間通信。
3FS NATIVE Client API
當(dāng)用戶調(diào)用接口,創(chuàng)建hf3fs_iov時(shí),會在/dev/shm上分配內(nèi)存,并創(chuàng)建一個(gè)指向這個(gè)共享內(nèi)存的軟鏈接,軟鏈接的地址位于/mount_point/3fs-virt/iovs/,這是個(gè)虛擬目錄。3FS FUSE 進(jìn)程收到創(chuàng)建軟鏈接請求,并且發(fā)現(xiàn)它的地址位于上述虛擬目錄后,就會根據(jù)軟鏈接的名字解析出這塊共享內(nèi)存的相關(guān)參數(shù),并將內(nèi)存的地址注冊到所有 RDMA 設(shè)備(除了IORing)。ibv_reg_mr返回的結(jié)果被存在RDMABuf::Inner數(shù)據(jù)結(jié)構(gòu)中,用于后續(xù)發(fā)送 RDMA 請求。
同時(shí),IORing的內(nèi)存也使用hf3fs_iov保存,只是在創(chuàng)建對應(yīng)的軟鏈接時(shí),文件名中會有更多的IORing相關(guān)的信息。如果 FUSE 進(jìn)程發(fā)現(xiàn)這個(gè)內(nèi)存是用于創(chuàng)建IORing,也會在它的進(jìn)程內(nèi)創(chuàng)建對應(yīng)的IORing。這樣設(shè)置之后,用戶進(jìn)程和 FUSE 進(jìn)程就可以訪問相同的IORing了。
進(jìn)程間協(xié)作方面,3FS 在/mount_point/3fs-virt/iovs/目錄中創(chuàng)建 3 個(gè)不同的虛擬文件用于共享 3 個(gè)不同優(yōu)先級的提交信號量 (submit sem ),用戶進(jìn)程將請求放到IORing后使用這些信號量通知 FUSE 進(jìn)程有新的請求。IORing尾部包含請求完成信號量,F(xiàn)USE 進(jìn)程通過調(diào)用sem_post通知用戶進(jìn)程IORing上有新的請求完成。以上整個(gè)機(jī)制確保了兩個(gè)進(jìn)程間的高效數(shù)據(jù)通信和操作同步。
3FS 的 FUSE 客戶端實(shí)現(xiàn)了文件和目錄的基本操作,而 JuiceFS FUSE 客戶端的實(shí)現(xiàn)更加全面。比如,在 3FS 文件系統(tǒng)中文件的長度是最終一致的,這意味著在寫的過程中用戶可能訪問到不正確的文件長度。而 JuiceFS 在每次成功上傳對象后會立即更新文件長度。此外,JuiceFS 還提供了以下這些常用的高級文件系統(tǒng)功能:
? 支持 BSD 鎖(flock)和 POSIX 鎖(fcntl)
? 支持file_copy_range接口
? 支持readdirplus接口
? 支持fallocate接口
除了 FUSE 客戶端,JuiceFS 還提供 Java SDK,S3 Gateway,CSI Driver 等接入方式。企業(yè)版還提供 Python SDK,Python SDK 將 JuiceFS 客戶端在用戶進(jìn)程中運(yùn)行,避免了通過 FUSE 導(dǎo)致的額外性能開銷。具體見文檔:Python SDK[4]。
02 文件分布對比
3FS 文件分布
3FS 將每個(gè)文件分成固定長度的 chunk,每個(gè) chunk 位于一個(gè)上文提到的鏈上( CRAQ 算法)。用戶使用 3FS 提供的一個(gè)腳本,生成一個(gè) chain table。然后將這個(gè)表提交到元數(shù)據(jù)服務(wù)。創(chuàng)建新文件時(shí),系統(tǒng)會從表中選取特定數(shù)量的 chain (數(shù)量由 stripe 定義),并將這些 chain 的信息存入文件的元數(shù)據(jù)中。
因?yàn)?3FS 中的 chunk 是固定的,客戶端只需要獲取一次 inode 的 chain 信息,就可以根據(jù)文件 inode 和 I/O 請求 的 offset,length 計(jì)算出這個(gè)請求位于哪些 chunk 上,從而避免了每個(gè) I/O 都從數(shù)據(jù)庫查詢的需求??梢酝ㄟ^offset/chunk_size得到 chunk 的索引。而 chunk 所在的 chain 的索引就是chunk_id%stripe。有了 chain 的索引就可以得到 chain 的詳細(xì)信息(比如這個(gè) chain 由哪些 target 組成)。然后,客戶端根據(jù)路由信息將 I/O 請求發(fā)送到相應(yīng)的存儲服務(wù)。存儲服務(wù)收到寫請求后以 copy-on-write (COW)的方式將數(shù)據(jù)寫入新的位置。原來的數(shù)據(jù)在引用數(shù)據(jù)清零前仍然是可讀的。
為了應(yīng)對數(shù)據(jù)不平衡問題,每個(gè)文件的第一個(gè) chain 按照輪詢( round roubin) 的方式選擇。比如當(dāng) stripe 為 3 時(shí),創(chuàng)建一個(gè)文件,其選擇的 chain 為:chain0,chain1,chain2。那么下一個(gè)文件的 chain 為:chain1,chain2 和 chain3。系統(tǒng)會將選擇的 3 個(gè) chain 做隨機(jī)排序,然后存儲到元數(shù)據(jù)中。下圖為 stripe 為 3 時(shí)一個(gè)文件的分布示例,chain 隨機(jī)排序后的順序是:1,3,2。
3FS 文件分布
JuiceFS 文件分布
JuiceFS 按照 Chunk、Slice、Block 的規(guī)則進(jìn)行數(shù)據(jù)塊管理。每個(gè) Chunk 的大小固定為 64M,主要用于優(yōu)化數(shù)據(jù)的查找和定位。實(shí)際的文件寫入操作則在 Slice 上執(zhí)行,每個(gè) Slice 代表一次連續(xù)的寫入過程,屬于特定的 Chunk,并且不會跨越 Chunk 的邊界,因此長度不超過 64M。Chunk 和 Slice 主要是邏輯上的劃分,而 Block(默認(rèn)大小為 4M)則是物理存儲的基本單位,用于在對象存儲和磁盤緩存中實(shí)現(xiàn)數(shù)據(jù)的最終存儲。更多細(xì)節(jié)可以參考官網(wǎng)介紹[5]。
JuiceFS 文件分布
JuiceFS 中的 Slice 是在他文件系統(tǒng)中不常見的一個(gè)結(jié)構(gòu)。主要功能是記錄文件的寫入操作,并在對象存儲中進(jìn)行持久化。對象存儲不支持原地文件修改,因此,JuiceFS 通過引入 Slice 結(jié)構(gòu)允許更新文件內(nèi)容,而無需重寫整個(gè)文件。這與 Journal File System 有些類似,其中寫入操作僅創(chuàng)建新對象,而不是覆蓋現(xiàn)有對象。修改文件時(shí),系統(tǒng)會創(chuàng)建新的 Slice,并在該 Slice 上傳完畢后更新元數(shù)據(jù),從而將文件內(nèi)容指向新的 Slice。被覆蓋的 Slice 內(nèi)容隨后通過異步壓縮過程從對象存儲中刪除,導(dǎo)致在某些時(shí)刻對象存儲的使用量會暫時(shí)超過文件系統(tǒng)實(shí)際使用量。
此外,JuiceFS 的所有 Slice 均為一次性寫入,這減少了對底層對象存儲一致性的依賴,并大大簡化了緩存系統(tǒng)的復(fù)雜度,使數(shù)據(jù)一致性更易于保證。這種設(shè)計(jì)還為實(shí)現(xiàn)文件系統(tǒng)的零拷貝語義提供了便利,支持如 copy_file_range 和 clone 等操作。
03 3FS RPC (Remote Procedure Call) 框架
3FS 使用 RDMA 作為底層網(wǎng)絡(luò)通信協(xié)議,目前 JuiceFS 尚未支持,下面對此做一些分析。
3FS 通過實(shí)現(xiàn)一個(gè) RPC 框架,來完成對底層 IB 網(wǎng)絡(luò)的操作。除了網(wǎng)絡(luò)操作外,RPC 框架還提供序列化,小包合并等能力。因?yàn)?C++ 不具有反射能力,所以 3FS 還通過模版實(shí)現(xiàn)了一個(gè)反射庫,用于序列化 RPC 使用的 request、response 等數(shù)據(jù)結(jié)構(gòu)。需要被序列化的數(shù)據(jù)結(jié)構(gòu)只需要使用特定的宏定義需要序列化的屬性。RPC 調(diào)用都是異步完成的,所以序列化后的數(shù)據(jù)只能從堆上分配,等待調(diào)用完成后再釋放。為了提高內(nèi)存的分配和釋放速度,分配對象都使用了緩存。3FS 的緩存有兩部份組成,一個(gè) TLS 隊(duì)列和一個(gè)全局隊(duì)列。從 TLS 隊(duì)列獲取緩存時(shí)不需要加鎖;當(dāng) TLS 緩存為空時(shí)就得加鎖,從全局隊(duì)列中獲取緩存。所以在最優(yōu)情況下,獲取緩存是不需要加鎖的。
與 I/O 請求的負(fù)載不同,緩存對象的內(nèi)存都未注冊到 RDMA 設(shè)備中。因此,當(dāng)數(shù)據(jù)到達(dá) IBSocket 后,會被拷貝到一個(gè)在 IB 設(shè)備注冊過的緩沖區(qū)中。多個(gè) RPC 請求可能被合并為一個(gè) IB 請求發(fā)送到對端。下圖為 FUSE Client 調(diào)用 Meta 服務(wù)的 RPC 過程。
3FS FUSE Client 調(diào)用 Metadata服務(wù)的 RPC 過程
04 特性對比
05 總結(jié)
大規(guī)模 AI 訓(xùn)練中最主要的需求是高讀帶寬,為此 3FS 采用了性能優(yōu)先的設(shè)計(jì)策略,將數(shù)據(jù)存儲在高速磁盤上,并且用戶需要自行管理底層數(shù)據(jù)存儲。這種方法提升了性能,但成本較高,維護(hù)也更繁重。此外,為了充分發(fā)揮底層硬件的性能,其架構(gòu)實(shí)現(xiàn)了客戶端到網(wǎng)卡的零拷貝,利用共享內(nèi)存和信號量減少 I/O 延遲和內(nèi)存帶寬占用。此外,通過帶 TLS 的 I/O buffer pool 和合并網(wǎng)絡(luò)請求,3FS 增強(qiáng)了小 I/O 和文件元數(shù)據(jù)操作的能力,并引入了性能更優(yōu)的 RDMA 技術(shù)。我們將繼續(xù)關(guān)注 3FS 在性能優(yōu)化方面的進(jìn)展,并探索如何將這些技術(shù)應(yīng)用于我們的場景中。
JuiceFS 使用對象存儲作為底層數(shù)據(jù)存儲,用戶因此可大幅降低存儲成本并簡化維護(hù)工作。為了滿足 AI 場景的對讀性能的需求,JuiceFS 企業(yè)版引入了分布式緩存、分布式元數(shù)據(jù)服務(wù)和 Python SDK,從而提高文件系統(tǒng)的性能和擴(kuò)展能力,并同時(shí)兼顧低存儲成本。在接下來發(fā)布的 v5.2 企業(yè)版中,在 TCP 網(wǎng)絡(luò)中實(shí)現(xiàn)了零拷貝,進(jìn)一步提升數(shù)據(jù)傳輸效率。
JuiceFS 提供完整的 POSIX 兼容性和成熟活躍的開源生態(tài),適應(yīng)更廣泛的使用場景,并支持Kubernetes CSI,極大簡化了云平臺的部署和運(yùn)維工作。此外,JuiceFS 還提供了 Quota、安全管理和數(shù)據(jù)災(zāi)備等多項(xiàng)企業(yè)級管理功能,讓企業(yè)可以更便捷地在生產(chǎn)環(huán)境中部署和應(yīng)用 JuiceFS。
關(guān)于作者
劉慶
Juicedata 核心系統(tǒng)開發(fā)工程師
-
存儲
+關(guān)注
關(guān)注
13文章
4517瀏覽量
87244 -
文件系統(tǒng)
+關(guān)注
關(guān)注
0文章
295瀏覽量
20338 -
開源
+關(guān)注
關(guān)注
3文章
3642瀏覽量
43659 -
DeepSeek
+關(guān)注
關(guān)注
1文章
789瀏覽量
1540
原文標(biāo)題:DeepSeek 3FS與JuiceFS:架構(gòu)與特性比較
文章出處:【微信號:OSC開源社區(qū),微信公眾號:OSC開源社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
在龍芯3a6000上部署DeepSeek 和 Gemma2大模型
了解DeepSeek-V3 和 DeepSeek-R1兩個(gè)大模型的不同定位和應(yīng)用選擇
添越智創(chuàng)基于 RK3588 開發(fā)板部署測試 DeepSeek 模型全攻略
鴻蒙原生應(yīng)用開發(fā)也可以使用DeepSeek了
RK3588開發(fā)板上部署DeepSeek-R1大模型的完整指南
HarmonyOS NEXT開發(fā)實(shí)戰(zhàn):DevEco Studio中DeepSeek的使用
DeepSeek推動AI算力需求:800G光模塊的關(guān)鍵作用
【書籍評測活動NO.62】一本書讀懂 DeepSeek 全家桶核心技術(shù):DeepSeek 核心技術(shù)揭秘
貼片電容0402與0603型號規(guī)格全面對比

華為ModelEngine AI平臺全面支持DeepSeek

評論