韩国国民搜索 NAVER:为 AI 平台引入存储方案 JuiceFS
NAVER 是一家多元化的互聯(lián)網(wǎng)公司,擁有韓國(guó)最大的搜索引擎并在人工智能、自動(dòng)駕駛等高科技領(lǐng)域積極投入。
在搭建 AI 平臺(tái)時(shí),NAVER 評(píng)估了公有云平臺(tái)的存儲(chǔ)產(chǎn)品、Alluxio 以及高性能專(zhuān)用存儲(chǔ)產(chǎn)品等多種選項(xiàng)后,最終決定采用 JuiceFS。通過(guò)使用JuiceFS,NAVER 成功地將內(nèi)部存儲(chǔ)資源升級(jí)為高性能、適應(yīng) AI 工作負(fù)載的存儲(chǔ)解決方案。
AiSuite 是 NAVER 開(kāi)發(fā)者所使用的人工智能平臺(tái),它支持 NAVER 的各種服務(wù)的開(kāi)發(fā)和運(yùn)維。
AiSuite 提供基于 Kubernetes 的容器環(huán)境,用于高效管理成本高昂的 GPU 資源。它支持 Kubeflow,不僅便于 AI 模型的開(kāi)發(fā),還能整合模型訓(xùn)練和部署服務(wù)的完整 AI 工作流程。此外,AiSuite 還支持使用集成了公司內(nèi)部數(shù)據(jù)平臺(tái) Kubeflow 工作流組件。
在建設(shè) AI 平臺(tái)時(shí),最大的挑戰(zhàn)就是提供適合 AI 工作負(fù)載的存儲(chǔ)。隨著大型語(yǔ)言模型(LLM)的普及,為了生成優(yōu)質(zhì)的 AI 模型,所需數(shù)據(jù)的規(guī)模越來(lái)越大,且分布式學(xué)習(xí)需要多個(gè)節(jié)點(diǎn)能夠同時(shí)訪問(wèn)數(shù)據(jù)。此外,還應(yīng)能夠輕松應(yīng)用像?Llama 2、MPT?等迅速出現(xiàn)的各種大型語(yǔ)言模型開(kāi)源項(xiàng)目。
適用于 AI 平臺(tái)的存儲(chǔ)需求如下:
-
必須能夠處理大規(guī)模數(shù)據(jù);
-
為了進(jìn)行重復(fù)的訓(xùn)練,高性能是必須的;
-
必須能作為 Kubernetes 持久卷(persistent volume)使用,即支持?Kubernetes CSI Driver;
-
為了確保能夠直接使用各種開(kāi)源軟件和庫(kù)而無(wú)需進(jìn)行任何修改,存儲(chǔ)系統(tǒng)應(yīng)具備 POSIX 兼容性;
-
對(duì)于分布式學(xué)習(xí)和大規(guī)模服務(wù),必須支持多個(gè)進(jìn)程同時(shí)訪問(wèn)(參考?ReadWriteMany, ReadOnlyMany);
-
必須確保數(shù)據(jù)的一致性;
-
運(yùn)維工作應(yīng)當(dāng)盡可能小。
尋找能夠滿(mǎn)足所有這些要求的存儲(chǔ)解決方案并非易事。云平臺(tái)如?AWS EFS?和?Google Filestore?等服務(wù)與這些要求相似。但是,這些服務(wù)與 AWS S3 或 Google Cloud Storage 等對(duì)象存儲(chǔ)服務(wù)相比,它們的成本要高得多(標(biāo)準(zhǔn)費(fèi)率下 EFS和 AWS S3 有10倍的差異)。此外,由于 AiSuite 是在 NAVER 內(nèi)部部署的,因此無(wú)法使用 AWS、GCP 等外部云存儲(chǔ)服務(wù)。我們也可以引入一些專(zhuān)用的存儲(chǔ)解決方案,如?DDN EXAScaler,但這會(huì)帶來(lái)高昂的成本。本文將介紹為解決這些問(wèn)題所進(jìn)行的探討以及引入新存儲(chǔ)解決方案的經(jīng)驗(yàn)。
01 存儲(chǔ)方案選型
我們?cè)紤]引入像?GlusterFS、CephFS?這樣的開(kāi)源解決方案,但由此會(huì)帶來(lái)比較大的運(yùn)維負(fù)擔(dān)。
我們希望能夠使用 NAVER 內(nèi)部現(xiàn)有資源可支持的存儲(chǔ)解決方案。?NAVER 內(nèi)部現(xiàn)有的存儲(chǔ)方案情況如下:
-
NAVER 的 C3 HDFS(Hadoop 分布式文件系統(tǒng))可以處理大規(guī)模數(shù)據(jù)。但是,由于 HDFS 不支持 Kubernetes CSI Driver,因此無(wú)法將其用作 Kubernetes 的持久卷;
-
NAVER 的對(duì)象存儲(chǔ) nubes 也可以處理大規(guī)模數(shù)據(jù),并支持 CLI、REST、S3、POSIX 等多種接口。但是,由于對(duì)象存儲(chǔ)的特性,它并不完全支持 POSIX API。此外,由于不支持 Kubernetes -- CSI Driver,因此也不能將其用作 Kubernetes 的持久卷;
-
Ceph RBD 不支持?ReadWriteMany, ReadOnlyMany,因此無(wú)法在多個(gè) Pod 中同時(shí)訪問(wèn);
-
NFS 可以簡(jiǎn)單設(shè)置,但存在擴(kuò)展性和高可用性(HA)的問(wèn)題;
-
Local Path?將數(shù)據(jù)存儲(chǔ)在 Kubernetes 節(jié)點(diǎn)的磁盤(pán)上。盡管訪問(wèn)速度快,但不支持多用戶(hù)同時(shí)訪問(wèn)。此外,由于存儲(chǔ)的數(shù)據(jù)位于各個(gè)節(jié)點(diǎn)上,因此需要進(jìn)行特定的調(diào)度或在應(yīng)用程序級(jí)別實(shí)現(xiàn)相關(guān)功能。
初步方案:引入 Alluxio
為了在 AiSuite 中快速且輕松地使用在 Hadoop 集群中處理并存儲(chǔ)在 HDFS 上的數(shù)據(jù),我們引入了?Alluxio。但 Alluxio 在我們的場(chǎng)景中存在以下問(wèn)題:
不完全的 POSIX 兼容性
雖然可以將 Alluxio 用作 Kubernetes 持久卷,但它不支持某些 POSIX API,例如符號(hào)鏈接、截?cái)唷allocate、追加、xattr 等。例如,在掛載 Alluxio 的路徑 /data 后,追加操作將失敗,如下所示:
$?cd?/data/
$?echo?"appended"?>>?myfile.txt
bash:?echo:?write?error:?File?exists??
許多 AI 開(kāi)源軟件和庫(kù)默認(rèn)實(shí)現(xiàn)為假設(shè)數(shù)據(jù)位于本地文件系統(tǒng)上。如果不支持某些 POSIX API,可能無(wú)法正常工作。因此,在使用 Alluxio 的情況下,有時(shí)需要將數(shù)據(jù)復(fù)制到?ephemeral storage?后再使用。這樣做會(huì)導(dǎo)致 AI 開(kāi)發(fā)變得不便和低效。
數(shù)據(jù)不一致
Alluxio 更類(lèi)似于現(xiàn)有存儲(chǔ)系統(tǒng)上的一個(gè)緩存層,并非一個(gè)獨(dú)立的存儲(chǔ)解決方案。當(dāng)?shù)讓哟鎯?chǔ)采用 HDFS 時(shí),直接對(duì) HDFS 進(jìn)行更改而沒(méi)有經(jīng)過(guò) Alluxio,可能會(huì)引起 Alluxio 與HDFS 數(shù)據(jù)的不同步。
在 Alluxio 中,可以設(shè)置與原始存儲(chǔ)數(shù)據(jù)同步的時(shí)間間隔。更多詳細(xì)信息,請(qǐng)參考?UFS Metadata Sync。但是,如果同步過(guò)于頻繁,會(huì)對(duì)原始存儲(chǔ)產(chǎn)生過(guò)多的元數(shù)據(jù)請(qǐng)求。AiSuite 運(yùn)行了一個(gè)以 HDFS 作為原始存儲(chǔ)的 Alluxio 實(shí)例,以便與基于 Hadoop 的數(shù)據(jù)平臺(tái)進(jìn)行交互。但是,頻繁同步導(dǎo)致管理 HDFS 元數(shù)據(jù)的?NameNode?負(fù)載增加。
運(yùn)維壓力
Alluxio 需要運(yùn)行一個(gè)由 master 和 worker 服務(wù)器組成的單獨(dú)集群,這也帶來(lái)了一定的運(yùn)維壓力。不僅如此,由于 AiSuite 的所有用戶(hù)都共享這個(gè)系統(tǒng),一旦出現(xiàn)問(wèn)題,可能會(huì)影響到所有用戶(hù)。
為什么選擇使用 JuiceFS
JuiceFS?是一種分布式文件系統(tǒng),采用“數(shù)據(jù)”與“元數(shù)據(jù)”分離存儲(chǔ)的架構(gòu),文件數(shù)據(jù)本身會(huì)被切分保存在對(duì)象存儲(chǔ)(例如 Amazon S3),而元數(shù)據(jù)則可以保存在 Redis、MySQL、TiKV、SQLite 等多種數(shù)據(jù)庫(kù)中,這使得企業(yè)能夠利用現(xiàn)有存儲(chǔ)和數(shù)據(jù)庫(kù)。
接下來(lái),我會(huì)詳細(xì)介紹 JuiceFS,并解釋為什么選擇應(yīng)用 JuiceFS。
配置
元數(shù)據(jù)引擎(Metadata Engine):負(fù)責(zé)管理文件的元數(shù)據(jù)(文件名、大小等)。可以使用多種數(shù)據(jù)庫(kù),如 Redis、TiKV、MySQL/MariaDB、PostgreSQL 等(文檔:如何設(shè)置元數(shù)據(jù))。
數(shù)據(jù)存儲(chǔ)(Data Storage):實(shí)際存儲(chǔ)數(shù)據(jù)的地方。可以使用多種存儲(chǔ),包括 S3、OpenStack Swift、Ceph、MinIO、HDFS 等(文檔:如何設(shè)置對(duì)象存儲(chǔ));客戶(hù)端(Client):與元數(shù)據(jù)引擎、數(shù)據(jù)存儲(chǔ)進(jìn)行交互,執(zhí)行文件 I/O 操作。支持多種接口,適用于不同的環(huán)境;JuiceFS 的元數(shù)據(jù)和數(shù)據(jù)存儲(chǔ)能夠使用現(xiàn)有存儲(chǔ)和數(shù)據(jù)庫(kù),并且可適配 Kubernetes 環(huán)境。例如,只要準(zhǔn)備好了 S3 對(duì)象存儲(chǔ)和 Redis,就可以通過(guò) JuiceFS 創(chuàng)建一個(gè)高性能且功能豐富的存儲(chǔ)解決方案。這也是 JuiceFS 吸引我們的原因。使用 NAVER 內(nèi)部支持的存儲(chǔ)和數(shù)據(jù)庫(kù),可以方便地搭建存儲(chǔ)系統(tǒng)。
特性
JuiceFS 支持并發(fā)訪問(wèn),同時(shí)支持 POSIX 和 Kubernetes 環(huán)境。滿(mǎn)足前面提到的用于 AI 平臺(tái)的存儲(chǔ)要求,具體特性如下:
- POSIX 兼容:可像本地文件系統(tǒng)一樣使用;
- HDFS 兼容:支持?HDFS API,可用于 Spark、Hive等數(shù)據(jù)處理框架;
- S3 兼容:通過(guò)啟用?S3 網(wǎng)關(guān),可以使用 S3 兼容接口進(jìn)行訪問(wèn);
- 云原生:支持?CSI Driver,可用于 Kubernetes 持久卷;
- 分布式:可在多個(gè)服務(wù)器上同時(shí)共享;
- 強(qiáng)一致性:提交的更改立即在所有服務(wù)器上生效;
- 出色性能:詳細(xì)信息請(qǐng)參閱性能基準(zhǔn)測(cè)試;
- 數(shù)據(jù)安全:支持?jǐn)?shù)據(jù)加密;
- 文件鎖定:支持 BSD 鎖(flock)和 POSIX 鎖(fcntl);
- 數(shù)據(jù)壓縮:支持?LZ4,?Zstandard,可節(jié)省存儲(chǔ)空間。
存儲(chǔ)原理
JuiceFS 引入了以下概念來(lái)處理文件,目的是為了彌補(bǔ)分布式存儲(chǔ)在物理上的分散性和對(duì)象存儲(chǔ)中對(duì)象難以修改的缺點(diǎn)。
-
Chunk:每個(gè)文件被劃分為 64MB 大小的 Chunk 進(jìn)行管理。大文件可以根據(jù)偏移量并行讀取或?qū)懭耄@對(duì)于處理大規(guī)模數(shù)據(jù)非常有效;
-
Slice:每個(gè) Chunk 由一個(gè)或多個(gè) Slice 組成。每次寫(xiě)入時(shí)都會(huì)創(chuàng)建一個(gè)新的 Slice,它們可以與同一個(gè) Chunk 的其他 Slice 重疊。在讀取 Chunk 時(shí),會(huì)優(yōu)先讀取最新的 Slice。為了避免過(guò)多的 Slice 導(dǎo)致讀取性能下降,會(huì)定期將它們合并為一個(gè)。這使得 JuiceFS 能夠靈活地修改文件,解決了對(duì)象存儲(chǔ)在數(shù)據(jù)修改方面的限制;
-
Block:在實(shí)際存儲(chǔ)中,Slice 被劃分為基礎(chǔ)大小為 4MB(最大可達(dá) 16MB)的 Block 進(jìn)行存儲(chǔ)。Chunk 和 Slice 主要是邏輯概念,而實(shí)際存儲(chǔ)中可見(jiàn)的數(shù)據(jù)單位是 Block。通過(guò)分割為較小的 Block 并進(jìn)行并行處理,JuiceFS 彌補(bǔ)了分布式對(duì)象存儲(chǔ)遠(yuǎn)程且較慢的特點(diǎn);
元數(shù)據(jù)引擎管理著諸如文件名、文件大小等元數(shù)據(jù)。此外,它還包含了文件與實(shí)際存儲(chǔ)數(shù)據(jù)之間的映射信息。
緩存
JuiceFS 為了提高性能,采用了多個(gè)層級(jí)的緩存。在讀取請(qǐng)求時(shí),首先嘗試從內(nèi)核頁(yè)緩存、客戶(hù)端進(jìn)程緩存和本地磁盤(pán)緩存中讀取數(shù)據(jù)。若這些緩存未命中,則會(huì)從遠(yuǎn)端存儲(chǔ)中讀取所需數(shù)據(jù)。從遠(yuǎn)端存儲(chǔ)中獲取的數(shù)據(jù)隨后會(huì)被異步地存儲(chǔ)在各級(jí)緩存中,以便未來(lái)能更快速地訪問(wèn)同樣的數(shù)據(jù)。
02 Alluxio vs JuiceFS
早期引入的 Alluxio 并沒(méi)有滿(mǎn)足我們所需的存儲(chǔ)要求。那么 JuiceFS 呢?以下是對(duì) Alluxio 和 JuiceFS 進(jìn)行比較的表格。
JuiceFS 和 Alluxio 都支持多種接口,并可以通過(guò)緩存來(lái)提高性能。與 Alluxio 相比,JuiceFS 具有以下優(yōu)點(diǎn):
完全兼容 POSIX
Alluxio 在某些 POSIX API 上提供有限支持。而 JuiceFS 能夠完全支持 POSIX 標(biāo)準(zhǔn),因此可以像本地文件系統(tǒng)一樣使用。這意味著,無(wú)需修改存儲(chǔ)在 JuiceFS 中的訓(xùn)練數(shù)據(jù)和代碼,就可以使用各種 AI 開(kāi)源工具和庫(kù)。下面是 POSIX 兼容性測(cè)試?pjdfstest?的結(jié)果。與AWS EFS 和 Google Filestore 相比,JuiceFS 在支持 POSIX 方面表現(xiàn)更佳。
強(qiáng)一致性
Alluxio 更接近于對(duì)原始存儲(chǔ)進(jìn)行緩存,而 JuiceFS 是一個(gè)獨(dú)立的存儲(chǔ)系統(tǒng)。在 JuiceFS 中,元數(shù)據(jù)由元數(shù)據(jù)引擎管理,不依賴(lài)于外部系統(tǒng)。數(shù)據(jù)存儲(chǔ)僅用于存放 Block 數(shù)據(jù)。因此,不會(huì)像 Alluxio 那樣出現(xiàn)與原始存儲(chǔ)不同步的問(wèn)題。
減輕運(yùn)維負(fù)擔(dān)
Alluxio 需要運(yùn)行和維護(hù) master 和 worker 服務(wù)器,這增加了一定的運(yùn)維負(fù)擔(dān)。此外,因?yàn)锳lluxio被所有用戶(hù)共享,一旦發(fā)生故障,可能會(huì)對(duì)所有用戶(hù)造成影響。JuiceFS 可以直接利用現(xiàn)有熟悉的存儲(chǔ)和數(shù)據(jù)庫(kù)作為元數(shù)據(jù)引擎和數(shù)據(jù)存儲(chǔ),僅需 JuiceFS 客戶(hù)端即可運(yùn)行,無(wú)需部署獨(dú)立服務(wù)器。此外,每個(gè)用戶(hù)都可以獨(dú)立配置自己的元數(shù)據(jù)引擎和數(shù)據(jù)存儲(chǔ),從而避免相互干擾。
03 如何使用 JuiceFS 構(gòu)建存儲(chǔ)方案
使用 JuiceFS,需要準(zhǔn)備一個(gè)用作元數(shù)據(jù)引擎的數(shù)據(jù)庫(kù)和對(duì)象存儲(chǔ)。如前所述,JuiceFS 支持多種數(shù)據(jù)庫(kù)和對(duì)象存儲(chǔ)。為了減輕運(yùn)維負(fù)擔(dān),我們使用了 NAVER 現(xiàn)有的平臺(tái)。
如下圖所示,AiSuite 通過(guò)以下內(nèi)部平臺(tái)使用 JuiceFS。
元數(shù)據(jù)引擎
在 NAVER,可以使用?nBase-ARC?Redis 服務(wù)或通過(guò) MySQL 支持來(lái)設(shè)置元數(shù)據(jù)引擎。如果是進(jìn)行開(kāi)發(fā)和測(cè)試,也可以通過(guò)?Helm chart?直接安裝并使用 Redis、PostgreSQL 等。JuiceFS 默認(rèn)每小時(shí)將元數(shù)據(jù)自動(dòng)備份到數(shù)據(jù)存儲(chǔ)中,且備份周期是可配置的。因此,即使元數(shù)據(jù)引擎的數(shù)據(jù)丟失,也可以進(jìn)行恢復(fù),但由于元數(shù)據(jù)備份周期的設(shè)定,仍有可能會(huì)有部分?jǐn)?shù)據(jù)丟失。有關(guān)詳細(xì)信息,請(qǐng)參考元數(shù)據(jù)備份和恢復(fù)。
數(shù)據(jù)存儲(chǔ)
可以使用 NAVER 內(nèi)部的 HDFS 或 nubes Object Storage 存儲(chǔ)大規(guī)模數(shù)據(jù)。利用這些資源,可以進(jìn)行大容量且穩(wěn)定的數(shù)據(jù)存儲(chǔ)。
nubes
nubes?是 NAVER 的對(duì)象存儲(chǔ)。JuiceFS 本身不直接支持 nubes,但可以通過(guò)使用具有 MinIO 接口的 nubes-s3-proxy 來(lái)訪問(wèn)。
HDFS
HDFS?是 JuiceFS 默認(rèn)支持的存儲(chǔ)系統(tǒng)。但是,為了在大規(guī)模、多租戶(hù)的 HDFS 中應(yīng)用 Kerberos,需要進(jìn)行以下改進(jìn):
支持 Kerberos keytab 文件
NAVER 內(nèi)部的 HDFS 應(yīng)用了 Kerberos。因此,當(dāng) JuiceFS 使用 HDFS 時(shí),需要進(jìn)行 Kerberos 認(rèn)證。原先的 JuiceFS 是通過(guò)設(shè)置 KRB5CCNAME 環(huán)境變量為?credential cache?進(jìn)行 HDFS 認(rèn)證。但這個(gè)方式會(huì)在一定時(shí)間后過(guò)期失效。為解決這一問(wèn)題,進(jìn)行了改進(jìn),可以通過(guò)設(shè)置 KRB5KEYTAB、KRB5PRINCIPAL 環(huán)境變量使用 keytab 文件。(參見(jiàn)?JuiceFS issue #3283)
支持 base64 編碼的 keytab 文件
AiSuite 是一個(gè)多租戶(hù) Kubernetes 集群,共享給多個(gè)用戶(hù),目標(biāo)是允許每個(gè)用戶(hù)使用自己選擇的元數(shù)據(jù)引擎和數(shù)據(jù)存儲(chǔ)來(lái)運(yùn)行 JuiceFS。用戶(hù)需要自己編寫(xiě)?Kubernetes Secret,設(shè)置訪問(wèn)元數(shù)據(jù)引擎和數(shù)據(jù)存儲(chǔ)的路徑和認(rèn)證信息。但是,KRB5KEYTAB 僅是一個(gè)文件路徑,并不能讓用戶(hù)傳遞實(shí)際的 keytab 文件。為解決這個(gè)問(wèn)題,進(jìn)行了改進(jìn),允許通過(guò)設(shè)置 KRB5KEYTAB_BASE64 環(huán)境變量使用 base64 編碼的 keytab 文件字符串。(參見(jiàn)?JuiceFS issue #3817)
支持用戶(hù)指定的 HDFS 路徑
NAVER 內(nèi)部的 HDFS 由多個(gè)用戶(hù)共享,每個(gè)用戶(hù)僅在分配給他們的 HDFS 路徑上擁有權(quán)限。但是,原來(lái)的 JuiceFS 無(wú)法指定用于數(shù)據(jù)存儲(chǔ)的 HDFS 路徑,因此總是必須將數(shù)據(jù)存儲(chǔ)在 root 目錄下,這導(dǎo)致用戶(hù)遇到了沒(méi)有權(quán)限訪問(wèn)的路徑問(wèn)題。為解決這個(gè)問(wèn)題,進(jìn)行了改進(jìn),允許用戶(hù)設(shè)置自己的 HDFS 路徑。(參見(jiàn)?JuiceFS issue #3526)
支持 HDFS 路徑 hdfs://nameservice
NAVER 內(nèi)部的 HDFS 為了大規(guī)模運(yùn)營(yíng),采用了?HDFS Federation,由多個(gè) NameNode 和 Namespace 組成。原本的 JuiceFS 需要直接指定 NameNode 路徑,如 nn1.example.com:8020,這對(duì)用戶(hù)來(lái)說(shuō)確認(rèn)和設(shè)置很不方便。為了解決這個(gè)問(wèn)題,進(jìn)行了改進(jìn),現(xiàn)在可以像 hdfs://nameservice 這樣設(shè)置 Namespace。(參見(jiàn)?JuiceFS issue #3576)
CSI Driver
AiSuite 是一個(gè)多租戶(hù) Kubernetes 集群,每個(gè)用戶(hù)通過(guò)?Kubernetes namespace?進(jìn)行區(qū)分。如果用戶(hù)間共享 JuiceFS,可能會(huì)相互影響,降低穩(wěn)定性并增加運(yùn)維難度。因此,我們的目標(biāo)是使每個(gè)用戶(hù)都能單獨(dú)準(zhǔn)備自己的元數(shù)據(jù)引擎和數(shù)據(jù)存儲(chǔ),并獨(dú)立使用 JuiceFS。此外,為了減輕運(yùn)維負(fù)擔(dān)并提高用戶(hù)便利性,支持?Dynamic Volume Provisioning,使用戶(hù)無(wú)需管理員介入,就能直接定義和使用 PVC(PersistentVolumeClaim)。為此,需要進(jìn)行以下改進(jìn):
支持模板 Secret
用戶(hù)需要?jiǎng)?chuàng)建?Secret,以設(shè)置各自準(zhǔn)備的元數(shù)據(jù)引擎和數(shù)據(jù)存儲(chǔ)的訪問(wèn)路徑和認(rèn)證信息。然后,需要在?StorageClass?中設(shè)置以引用這些 Secret。這些設(shè)置的 Secret 會(huì)被用于 Dynamic Volume Provisioning。但是,原有的 JuiceFS CSI Driver 只能在 StorageClass 中設(shè)置一個(gè)固定的 Secret。為解決這一問(wèn)題,進(jìn)行了改進(jìn),允許通過(guò) ${pvc.name}, ${pvc.namespace}, ${pvc.annotations['']} 等方式,從用戶(hù)創(chuàng)建的 PVC 中引用 Secret。(參見(jiàn)?JuiceFS CSI Driver issue #698)
支持 Secret Finalizer
用戶(hù)的 Secret 不僅在創(chuàng)建 PVC 時(shí)使用,還在刪除 PVC 時(shí)用于刪除 JuiceFS 數(shù)據(jù)。如果在刪除 PVC 之前關(guān)聯(lián)的 Secret 被移除,JuiceFS 數(shù)據(jù)將不會(huì)被清理,而會(huì)持續(xù)留存。為了防止這個(gè)問(wèn)題,在 PVC 被刪除之前,設(shè)置?Finalizer?以防止關(guān)聯(lián)的 Secret 被移除。在 StorageClass 的?parameters?中設(shè)置 secretFinalizer: "true" 可以啟用此功能。(參見(jiàn)?JuiceFS CSI Driver issue #707)
支持根據(jù) PVC 元數(shù)據(jù)設(shè)置 mountOptions
AiSuite 中存在多種 AI 工作負(fù)載,如 AI 學(xué)習(xí)、服務(wù)和數(shù)據(jù)處理等。為了實(shí)現(xiàn)最優(yōu)性能,根據(jù)工作類(lèi)型可能需要單獨(dú)配置 JuiceFS。例如,在使用只讀數(shù)據(jù)進(jìn)行 AI 訓(xùn)練的情況下,可以通過(guò)添加 --open-cache 設(shè)置來(lái)提高讀取性能。有關(guān)詳細(xì)信息,請(qǐng)參考客戶(hù)端內(nèi)存中的元數(shù)據(jù)緩存。原先的 JuiceFS 只能應(yīng)用 StorageClass 中固定的配置。現(xiàn)在進(jìn)行了改進(jìn),允許根據(jù)用戶(hù)創(chuàng)建的 PVC 進(jìn)行設(shè)置,例如使用 ${.PVC.namespace}, ${.PVC.name}, ${.PVC.labels.foo}, ${.PVC.annotations.bar} 這樣的方法。(參見(jiàn)?JuiceFS CSI Driver issue)
04 JuiceFS 應(yīng)用方案
為了在 Kubernetes 中支持 JuiceFS,管理員需要部署 JuiceFS CSI Driver,而用戶(hù)則需要定義自己的 Secret 和 PVC。在多租戶(hù) Kubernetes 環(huán)境 AiSuite 中,將詳細(xì)說(shuō)明如何部署和提供 JuiceFS,包括具體的示例。
部署方法
安裝 JuiceFS CSI Driver 后,可以按照標(biāo)準(zhǔn) Kubernetes 卷的使用方式進(jìn)行操作,支持通過(guò) Helm 或 kubectl 進(jìn)行安裝。有關(guān)詳細(xì)信息,請(qǐng)參考?JuiceFS CSI Driver 安裝指南。進(jìn)行部署需要 Kubernetes 管理員權(quán)限。為了讓每個(gè)用戶(hù)使用自己的元數(shù)據(jù)引擎和數(shù)據(jù)存儲(chǔ),StorageClass 設(shè)置如下。
apiVersion:?storage.k8s.io/v1??
kind:?StorageClass??
metadata:??
??name:?juicefs
provisioner:?csi.juicefs.com??
parameters:??
??#配置系統(tǒng)以便用戶(hù)可以引用自己創(chuàng)建的?Secret
??#用戶(hù)需要在?PVC?'csi.juicefs.com/secret-name'注釋中設(shè)置Secret的名稱(chēng)
??csi.storage.k8s.io/provisioner-secret-name:?${pvc.annotations['csi.juicefs.com/secret-name']}
??csi.storage.k8s.io/provisioner-secret-namespace:?${pvc.namespace}
??csi.storage.k8s.io/node-publish-secret-name:?${pvc.annotations['csi.juicefs.com/secret-name']}
??csi.storage.k8s.io/node-publish-secret-namespace:?${pvc.namespace}
??csi.storage.k8s.io/controller-expand-secret-name:?${pvc.annotations['csi.juicefs.com/secret-name']}
??csi.storage.k8s.io/controller-expand-secret-namespace:?${pvc.namespace}
??juicefs/clean-cache:?"true"
??#激活?secretFinalizer,以防止用戶(hù)定義的?Secret?被隨意刪除
??secretFinalizer:?"true"
??#通過(guò)指定?pathPattern來(lái)設(shè)置路徑,可以掛載所需的路徑
??#用戶(hù)可以在?PVC?'csi.juicefs.com/subdir'注釋中設(shè)置所需的路徑
??pathPattern:?"${.PVC.annotations.csi.juicefs.com/subdir}"
allowVolumeExpansion:?true??
reclaimPolicy:?Delete??
mountOptions:??
??#允許用戶(hù)根據(jù)需要設(shè)置各自的選項(xiàng)
??#用戶(hù)可以在PVC的'csi.juicefs.com/additional-mount-options'注釋中設(shè)置所需的JuiceFS選項(xiàng)。
??-?${.PVC.annotations.csi.juicefs.com/additional-mount-options}
使用方法
用戶(hù)需要為自己準(zhǔn)備的元數(shù)據(jù)引擎和數(shù)據(jù)存儲(chǔ)創(chuàng)建 Secret,包括路徑和認(rèn)證信息等。
apiVersion:?v1??
kind:?Secret??
metadata:??
?name:?myjfs
type:?Opaque??
stringData:??
?#JuiceFS文件系統(tǒng)名稱(chēng)。
?name:?myjfs
?#MINIO_ROOT_USER
?access-key:?user
?#MINIO_ROOT_PASSWORD
?secret-key:?password
?#元數(shù)據(jù)引擎 Redis 路徑
?metaurl:?redis://:@redis.user1.svc.cluster.local:6379/0
?#minio
?storage:?minio
?#bucket1
?bucket:?http://nubes-s3-proxy.user1.svc.cluster.local:10000/bucket1
?#https://juicefs.com/docs/community/command_reference/#format
?format-options:?trash-days=0,block-size=16384
定義 PVC。此外,需要設(shè)置以下注釋?zhuān)╝nnotation):
-
csi.juicefs.com/secret-name:指定引用的 Secret 名稱(chēng); -
csi.juicefs.com/subdir:如果是新的卷,則指定 PVC 名稱(chēng)。如果需要掛載已存在的 JuiceFS 路徑,則可以指定所需的路徑; -
csi.juicefs.com/additional-mount-options:可以添加適合工作負(fù)載的 JuiceFS 掛載選項(xiàng)。有關(guān)詳細(xì)信息,請(qǐng)參考掛載指南。
apiVersion:?v1??
kind:?PersistentVolumeClaim??
metadata:??
?name:?myjfs
?annotations:
???csi.juicefs.com/secret-name:?myjfs?#?之前創(chuàng)建的Secret名稱(chēng)
???csi.juicefs.com/subdir:?myjfs?#?在JuiceFS文件系統(tǒng)中的路徑
???csi.juicefs.com/additional-mount-options:?"writeback,upload-delay=1m"?#?如果需要,可以添加JuiceFS的配置
spec:??
?accessModes:
?-?ReadWriteMany
?resources:
???requests:
?????storage:?100Gi
?storageClassName:?juicefs
創(chuàng)建 Secret 和 PVC 后,可以像使用普通卷一樣使用它們。下面是一個(gè)將之前創(chuàng)建的 myjfs PVC 掛載到 /data 上的 Pod 示例。
apiVersion:?v1??
kind:?Pod??
metadata:??
?name:?example
spec:??
?containers:
?-?name:?app
...
???volumeMounts:
???-?mountPath:?/data
?????name:?juicefs-pv
?volumes:
?-?name:?juicefs-pv
???persistentVolumeClaim:
?????claimName:?myjfs
05 性能測(cè)試
JuiceFS 性能基準(zhǔn)測(cè)試如下所示,與?EFS,?S3FS?相比,其性能更高。
我們需要驗(yàn)證當(dāng)使用 nubes 對(duì)象存儲(chǔ)和 HDFS 作為數(shù)據(jù)存儲(chǔ)時(shí)的性能表現(xiàn)。由于 JuiceFS 的性能可能會(huì)根據(jù)所使用的數(shù)據(jù)存儲(chǔ)類(lèi)型而有所差異,我們還需關(guān)注由于使用 UserSpace 中的 Fuse 而可能出現(xiàn)的性能降低。特別是需要檢驗(yàn)因 JuiceFS Fuse 引起的性能下降情況。測(cè)試的主要目的是確定,相比直接使用數(shù)據(jù)存儲(chǔ),JuiceFS 是否會(huì)導(dǎo)致性能下降。如果性能差異不顯著,那么我們可以在保持性能的同時(shí)支持 POSIX 兼容性、并發(fā)訪問(wèn)等多項(xiàng)功能。
順序讀寫(xiě)
參考?Fio Standalone Performance Test,按照以下方式進(jìn)行了測(cè)試:
-
元數(shù)據(jù)引擎使用 Redis;
-
在單個(gè)節(jié)點(diǎn)上使用?fio?進(jìn)行測(cè)試時(shí),調(diào)整
--numjobs選項(xiàng); -
單節(jié)點(diǎn)的最大網(wǎng)絡(luò)帶寬為 1200MB/s,即此測(cè)試的可能最高值;
-
由于 Object Storage 基本上不支持 POSIX,因此沒(méi)有使用 fio,而是采用了針對(duì) nubes Object Storage 性能優(yōu)化的其他方法,僅測(cè)量 read(1 job), write(1 job) 項(xiàng)目;
-
JuiceFS 設(shè)置中,塊大小設(shè)置為 16MB,其他選項(xiàng)使用默認(rèn)值;
-
沒(méi)有使用 JuiceFS 緩存,僅進(jìn)行了讀寫(xiě)新數(shù)據(jù)的測(cè)試;
-
對(duì)于 Alluxio,由于在執(zhí)行 fio 時(shí)出現(xiàn)“fio: posix_fallocate fails: Not supported”等錯(cuò)誤而導(dǎo)致失敗,因此在測(cè)試中被排除了。
測(cè)試結(jié)果如下:
-
在讀取方面,與單獨(dú)的 nubes 相比,JuiceFS+nubes 和 JuiceFS+hdfs 的性能更好,并且隨著并發(fā)數(shù)量的增加而提升。這可能是因?yàn)橥ㄟ^(guò) Chunk 進(jìn)行的并發(fā)讀取更為有利;
-
在寫(xiě)入方面,與單獨(dú)的 nubes 相比,JuiceFS+nubes 和 JuiceFS+hdfs 的性能相似或略低。并發(fā)數(shù)量增加時(shí),性能會(huì)降低。這可能是由于多個(gè) Slice 帶來(lái)的負(fù)擔(dān)所致。
文件創(chuàng)建
此次測(cè)試比較了創(chuàng)建 1 萬(wàn)個(gè)小文件所需的時(shí)間。測(cè)量使用 nubes 作為數(shù)據(jù)存儲(chǔ)時(shí)處理元數(shù)據(jù)的性能,并與 JuiceFS 進(jìn)行比較。
-
元數(shù)據(jù)引擎使用 Redis;
-
測(cè)量了在 10 個(gè)進(jìn)程中使用 cp 命令復(fù)制 100 字節(jié)文件 1 萬(wàn)個(gè)時(shí)的每秒文件創(chuàng)建數(shù);
-
由于 Object Storage 基本上不支持 POSIX,因此沒(méi)有使用 cp,而是采用了針對(duì) nubes Object Storage 性能優(yōu)化的其他方法來(lái)測(cè)量 nubes 項(xiàng);
-
也測(cè)量了設(shè)置了 JuiceFS 的 writeback 選項(xiàng)的情況。此選項(xiàng)首先在本地進(jìn)行數(shù)據(jù)更新,然后異步保存到數(shù)據(jù)存儲(chǔ)。更多詳細(xì)信息,請(qǐng)參考?client-write-cache。
測(cè)試結(jié)果如下:
-
nubes 和 juicefs+nubes 之間沒(méi)有顯著差異。這意味著使用 nubes 作為數(shù)據(jù)存儲(chǔ)的 JuiceFS 不會(huì)導(dǎo)致性能下降;
-
與 HDFS 配合使用時(shí), JuiceFS+hdfs 和 alluxio 似乎與 HDFS 的元數(shù)據(jù)處理性能,即 NameNode 的性能趨于一致;
-
使用 writeback 選項(xiàng)可實(shí)現(xiàn)數(shù)十倍的性能提升。然而,啟用 writeback 選項(xiàng)可能導(dǎo)致數(shù)據(jù)丟失,因此適用于臨時(shí)數(shù)據(jù)的場(chǎng)景。
測(cè)試結(jié)論
JuiceFS 的性能基本上取決于存儲(chǔ)數(shù)據(jù)設(shè)備的性能。它能夠支持 POSIX 兼容性且無(wú)性能損失、還能支持并發(fā)訪問(wèn)等功能。
在某些工作負(fù)載和使用情況下,JuiceFS 的性能有時(shí)甚至可能優(yōu)于數(shù)據(jù)存儲(chǔ)設(shè)備的原始性能。盡管本文未進(jìn)行測(cè)試,但讀取緩存數(shù)據(jù)時(shí),因?yàn)槭菑谋镜卮疟P(pán)讀取,因此有可能提高性能。寫(xiě)入臨時(shí)數(shù)據(jù)時(shí),應(yīng)用 writeback 選項(xiàng)也可以提升性能。
JuiceFS 支持多種可根據(jù)工作負(fù)載進(jìn)行調(diào)整的緩存選項(xiàng)。更多詳細(xì)信息,請(qǐng)參考?cache。
06 小結(jié)
企業(yè)內(nèi)部存儲(chǔ) + JuiceFS
在 AiSuite 中,我們利用公司內(nèi)部支持的 HDFS 和 nubes 對(duì)象存儲(chǔ)來(lái)構(gòu)建 JuiceFS。這樣既能為 AI 工作負(fù)載提供適合的存儲(chǔ),又能減輕運(yùn)維負(fù)擔(dān)。對(duì)于前文中評(píng)估的企業(yè)內(nèi)部存儲(chǔ),可以總結(jié)如下:
在 AiSuite 中,相比于 HDFS,更推薦使用 nubes Object Storage 用作數(shù)據(jù)存儲(chǔ)。這是因?yàn)樵?HDFS 中,如果文件數(shù)量眾多,會(huì)對(duì)管理 HDFS 元數(shù)據(jù)的 NameNode 造成負(fù)擔(dān)。而 JuiceFS 會(huì)將文件分割成小的 Block 來(lái)存儲(chǔ),從而在 HDFS 中產(chǎn)生大量文件。即使是最大可設(shè)置的 Block 大小 16MB,為了存儲(chǔ) 1TB 數(shù)據(jù),也需要?jiǎng)?chuàng)建超過(guò) 62,500 個(gè)文件。雖然考慮過(guò)將最大 Block 大小提升至 64MB,但 Block 變大可能會(huì)導(dǎo)致效率低下。更多詳細(xì)信息,請(qǐng)參考?Increase the maximum of blockSize to 64MB。
優(yōu)勢(shì)
在 AI 平臺(tái) AiSuite 中,我們?cè)u(píng)估了 JuiceFS 作為 AI 工作負(fù)載的存儲(chǔ)解決方案的可行性。JuiceFS 具有以下多種優(yōu)勢(shì):
-
可以使用大容量、可共享(ReadWriteMany, ReadOnlyMany)卷;
-
高性能(緩存),可以替代 hostPath、local-path。可以輕松實(shí)現(xiàn)有狀態(tài)應(yīng)用的云原生轉(zhuǎn)換;
-
在 AI 分布式學(xué)習(xí)中,可以作為共享的工作區(qū)、checkpoint、日志存儲(chǔ);
-
能夠處理 AI 學(xué)習(xí)過(guò)程中所需的大量小文件(HDFS/Alluxio 的替代品);
-
可利用企業(yè)內(nèi)部的 HDFS、nubes Object Storage 存儲(chǔ),降低運(yùn)維負(fù)擔(dān);
-
通過(guò)用戶(hù)各自的數(shù)據(jù)存儲(chǔ)和元數(shù)據(jù)引擎運(yùn)行,互不影響;
-
支持多種數(shù)據(jù)存儲(chǔ)和元數(shù)據(jù)引擎,適用于大多數(shù) k8s 環(huán)境;
-
可以替代高成本的共享存儲(chǔ),如 AWS EFS、Google filestore、DDN exascaler。
通過(guò)使用 JuiceFS,能夠?qū)⑵髽I(yè)內(nèi)部傳統(tǒng)的存儲(chǔ)轉(zhuǎn)換為具有高性能和多功能的、適合 AI 工作負(fù)載的存儲(chǔ)。JuiceFS 支持多種存儲(chǔ)和多種數(shù)據(jù)庫(kù)。這篇文章主要介紹了在 NAVER 內(nèi)部的 on-premise 環(huán)境中的應(yīng)用案例,但它也可以應(yīng)用于 AWS、Google Cloud 等公共云環(huán)境。希望這篇文章能對(duì)面臨類(lèi)似問(wèn)題的用戶(hù)提供幫助。
希望這篇內(nèi)容能夠?qū)δ阌幸恍椭绻衅渌蓡?wèn)歡迎加入 JuiceFS 社區(qū)與大家共同交流。
總結(jié)
以上是生活随笔為你收集整理的韩国国民搜索 NAVER:为 AI 平台引入存储方案 JuiceFS的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 多余的铭文可以干什么
- 下一篇: 轻松搞定:《元梦之星》如何退出队伍