使用EFC加速NAS或CPFS文件訪問
Fluid是一個開源的Kubernetes原生的分布式數(shù)據(jù)集編排和加速引擎,主要服務(wù)于云原生場景下的數(shù)據(jù)密集型應(yīng)用。Fluid支持管理和調(diào)度EFCRuntime,實(shí)現(xiàn)數(shù)據(jù)集的可見性、彈性伸縮和數(shù)據(jù)訪問加速等能力。本文介紹如何使用Fluid EFCRuntime加速NAS或CPFS文件訪問。
前提條件
已確保ECS的操作系統(tǒng)為Alibaba Cloud Linux 2,內(nèi)核版本為v4.19.91-23及以上版本。
已創(chuàng)建ACK Pro版集群,且集群的Kubernetes版本不低于1.18。具體操作,請參見創(chuàng)建ACK Pro版集群。
已開通阿里云文件存儲NAS或CPFS服務(wù),并在已創(chuàng)建的ACK Pro集群節(jié)點(diǎn)可正常掛載訪問的通用容量型、通用性能型NAS或CPFS實(shí)例。具體操作,請參見NAS入門概述或CPFS入門概述。
說明對于AI訓(xùn)練場景,建議您根據(jù)吞吐性能選擇文件存儲規(guī)格。更多信息,請參見選型指導(dǎo)。
已配置kubectl,并可以正常連接ACK Pro版集群。具體操作,請參見獲取集群KubeConfig并通過kubectl工具連接集群。
EFC介紹
EFC彈性文件客戶端(Elastic File Client)是阿里云文件存儲團(tuán)隊(duì)開發(fā)的基于FUSE的用戶態(tài)POSIX客戶端。它可以替代傳統(tǒng)的內(nèi)核態(tài)NFS客戶端,提供多鏈接訪問、元數(shù)據(jù)緩存、分布式數(shù)據(jù)緩存等加速能力,并結(jié)合阿里云Prometheus監(jiān)控提供端側(cè)性能監(jiān)控能力。相比于內(nèi)核態(tài)NFS v3、v4.x客戶端和其他基于開源FUSE的客戶端,EFC有以下優(yōu)勢:
強(qiáng)一致的語義:EFC通過強(qiáng)一致的分布式鎖機(jī)制實(shí)現(xiàn)文件和目錄的強(qiáng)一致;文件寫入可以立即被其他客戶端讀取;新文件創(chuàng)建出來后,就可以立即讓所有的其他客戶端同步訪問到,便于您在多節(jié)點(diǎn)間管理數(shù)據(jù)。
端上單機(jī)讀寫緩存能力:優(yōu)化了FUSE的緩存邏輯,利用計(jì)算節(jié)點(diǎn)上的少量內(nèi)存,提供了更好的小文件讀寫性能。相比于傳統(tǒng)的NFS客戶端,性能提升了50%以上。
分布式只讀緩存能力:除了端上讀寫緩存,EFC提供分布式只讀緩存的能力,利用多節(jié)點(diǎn)的內(nèi)存建立緩存池,并隨計(jì)算規(guī)模免運(yùn)維自動擴(kuò)展。
小文件預(yù)取能力:EFC會針對性地預(yù)取熱目錄下的熱數(shù)據(jù),節(jié)省拉取數(shù)據(jù)的開銷。
熱升級和Failover能力:EFC支持秒級Failover特性,實(shí)現(xiàn)了對業(yè)務(wù)無影響的客戶端版本的熱升級能力。
使用Fluid EFCRuntime加速NAS或CPFS文件訪問
Fluid通過EFCRuntime的Kubernetes自定義資源對接EFC,幫助用戶實(shí)現(xiàn)數(shù)據(jù)集的可見性、彈性伸縮等能力。
使用限制
EFCRuntime具有以下限制:
暫不支持DataLoad緩存預(yù)熱功能,只支持第一次讀取數(shù)據(jù)時(shí)放入緩存的功能。
暫不支持Dataset資源對象上的緩存狀態(tài)信息透出。
僅支持在華北3(張家口)、華北2(北京)、華南3(廣州)、華南1(深圳)、華東2(上海)地域使用。
原理介紹
如下圖所示,通過將NAS或CPFS中的數(shù)據(jù)緩存到本地,實(shí)現(xiàn)對文件訪問速度的提升。其工作原理如下:
您可以通過定義Dataset CRD資源對象和EFCRuntime CRD資源對象,分別指定NAS或CPFS的數(shù)據(jù)源信息。
Fluid Controllers組件根據(jù)數(shù)據(jù)源信息,在集群中創(chuàng)建EFC Cache Worker組件和EFC FUSE組件。
用戶創(chuàng)建應(yīng)用Pod時(shí),可以通過指定PVC(PersistentVolumeClaim)的方式掛載到EFC FUSE客戶端暴露的文件系統(tǒng)掛載點(diǎn)。
當(dāng)用戶訪問文件時(shí),EFC FUSE客戶端會將請求轉(zhuǎn)發(fā)給EFC Cache Worker,后者會判斷數(shù)據(jù)是否已經(jīng)被緩存到本地,如果有緩存就直接返回;否則從NAS或CPFS中獲取數(shù)據(jù),并緩存到本地,即通過EFC緩存訪問NAS或CPFS文件存儲中的數(shù)據(jù),獲得緩存加速效果。
Dataset:由Fluid定義的一種Kubernetes CRD。它描述了邏輯上相關(guān)的一組數(shù)據(jù)的集合,會被上層運(yùn)算引擎使用。
EFCRuntime:支撐Dataset訪問加速能力的一種Runtime類型實(shí)現(xiàn),其背后使用的緩存引擎為EFC。EFC緩存引擎包括EFC Cache Worker組件和EFC FUSE組件。
EFC Cache Worker組件:通過一致性哈希提供緩存能力的服務(wù)端組件,根據(jù)不同的數(shù)據(jù)訪問需求可選擇關(guān)閉該組件。關(guān)閉該組件后,EFC將關(guān)閉分布式只讀緩存功能。其他特性不受影響。
EFC FUSE組件:以POSIX協(xié)議標(biāo)準(zhǔn)暴露數(shù)據(jù)訪問接口的EFC客戶端組件。
操作流程
步驟一:安裝ack-fluid組件
安裝云原生AI套件和ack-fluid組件,且確保組件為0.9.10及以上版本。
若您已安裝開源Fluid,請卸載后再部署ack-fluid組件。
未安裝云原生AI套件
您可以在安裝云原生AI套件時(shí)開啟Fluid數(shù)據(jù)加速。具體操作,請參見安裝云原生AI套件。
已安裝云原生AI套件
登錄容器服務(wù)管理控制臺,在左側(cè)導(dǎo)航欄選擇集群。
在集群列表頁面,單擊目標(biāo)集群名稱,然后在左側(cè)導(dǎo)航欄,選擇 。
在云原生AI套件頁面,單擊ack-fluid右側(cè)操作列下的部署。
在安裝組件對話框,單擊確定。
ack-fluid組件版本較低
登錄容器服務(wù)管理控制臺,在左側(cè)導(dǎo)航欄選擇集群。
在集群列表頁面,單擊目標(biāo)集群名稱,然后在左側(cè)導(dǎo)航欄,選擇 。
在云原生AI套件頁面,單擊ack-fluid右側(cè)操作列下的升級。
在升級組件對話框,單擊確定。
步驟二:在NAS或CPFS中創(chuàng)建待訪問的數(shù)據(jù)
NAS和CPFS都是存儲大規(guī)模數(shù)據(jù)的技術(shù),它們具有不同的技術(shù)架構(gòu)和數(shù)據(jù)管理方式,您可以根據(jù)具體場景來選擇合適的技術(shù)方案。
在NAS中創(chuàng)建待訪問的數(shù)據(jù)
如果您的NAS中已有合適的數(shù)據(jù)文件,可以跳過此步驟。
掛載NAS文件系統(tǒng)至任意一臺ECS。具體操作,請參見一鍵掛載NAS NFS協(xié)議文件系統(tǒng)。
執(zhí)行以下命令,查找文件掛載點(diǎn)。
findmnt /mnt
預(yù)期輸出:
TARGET SOURCE FSTYPE OPTIONS /mnt/nfs xxxxxxxxxxx-xxxxx.cn-beijing.nas.aliyuncs.com:/ nfs rw,relatime,vers=3,rsize=1048576,wsize=1048576,namlen=255,hard,nolock,no
執(zhí)行以下命令,在NAS文件存儲掛載點(diǎn)目錄下創(chuàng)建一個大小為10G的文件。
dd if=/dev/zero of=/mnt/nfs/allzero-demo count=1024 bs=10M
預(yù)期輸出:
1024+0 records in 1024+0 records out 10737418240 bytes (11 GB) copied, 50.9437 s, 211 MB/s
在CPFS中創(chuàng)建待訪問的數(shù)據(jù)
如果您的CPFS中已有合適的數(shù)據(jù)文件,可以跳過此步驟。
掛載CPFS文件系統(tǒng)至任意一臺ECS。具體操作,請參見CPFS-NFS客戶端掛載文件系統(tǒng)(推薦)。
執(zhí)行以下命令,查找文件掛載點(diǎn)。
findmnt /mnt/cpfs
預(yù)期輸出:
TARGET SOURCE FSTYPE OPTIONS /mnt/cpfs xxxxxxxxxxx-xxxxx.cn-beijing.cpfs.aliyuncs.com:/ nfs rw,relatime,vers=3,rsize=1048576,wsize=1048576,namlen=255,hard,nolock,noresvport,proto=tcp,port=30000,timeo=600,retrans=2,sec=sys
執(zhí)行以下命令,在CPFS文件存儲掛載點(diǎn)目錄下創(chuàng)建一個大小為10G的文件。
dd if=/dev/zero of=/mnt/cpfs/allzero-demo count=1024 bs=10M
預(yù)期輸出:
1024+0 records in 1024+0 records out 10737418240 bytes (11 GB) copied, 50.9437 s, 211 MB/s
步驟三:創(chuàng)建Fluid Dataset和EFCRuntime
創(chuàng)建dataset.yaml文件,代碼示例如下。
NAS代碼示例
apiVersion: data.fluid.io/v1alpha1 kind: Dataset metadata: name: efc-demo spec: mounts: - mountPoint: "nfs://<nas_url>:<nas_dir>" name: efc path: "/" --- apiVersion: data.fluid.io/v1alpha1 kind: EFCRuntime metadata: name: efc-demo spec: replicas: 3 master: networkMode: ContainerNetwork worker: networkMode: ContainerNetwork fuse: networkMode: ContainerNetwork tieredstore: levels: - mediumtype: MEM path: /dev/shm quota: 15Gi
CPFS代碼示例
apiVersion: data.fluid.io/v1alpha1 kind: Dataset metadata: name: efc-demo spec: mounts: - mountPoint: "cpfs://file-system-id.region.cpfs.aliyuncs.com:/share/path" name: efc path: "/mnt" --- apiVersion: data.fluid.io/v1alpha1 kind: EFCRuntime metadata: name: efc-demo spec: replicas: 3 master: networkMode: ContainerNetwork worker: networkMode: ContainerNetwork fuse: networkMode: ContainerNetwork tieredstore: levels: - mediumtype: MEM path: /dev/shm quota: 15Gi
dataset.yaml文件中包含Dataset和EFCRuntime。
Dataset:描述NAS或CPFS文件存儲的相關(guān)信息,例如NAS或CPFS文件存儲URL,需掛載的子目錄等。
EFCRuntime:啟動一個EFC緩存系統(tǒng)來提供緩存服務(wù)。在EFCRuntime中描述EFC緩存系統(tǒng)Worker組件副本數(shù),以及每個Worker組件最大的緩存容量等。
參數(shù)
說明
mountPoint
NAS的格式為
nfs://<nas_url>:<nas_dir>
,字段解析如下。nas_url:掛載NAS文件系統(tǒng)的掛載地址。
登錄NAS控制臺,在左側(cè)導(dǎo)航欄選擇文件系統(tǒng)>文件系統(tǒng)列表。在文件系統(tǒng)列表頁面,單擊目標(biāo)文件系統(tǒng)右側(cè)的管理,單擊掛載使用,獲取掛載地址。更多信息,請參見管理掛載點(diǎn)。
nas_dir:所需掛載的子路徑。如果無特殊要求,可以使用根目錄。例如
efc://xxxxxxxxxxx-xxxxx.cn-beijing.nas.aliyuncs.com:/
表示掛載一個NAS存儲系統(tǒng)的根目錄。
CPFS的格式為
cpfs://file-system-id.region.cpfs.aliyuncs.com:/share/path
,字段解析如下。以
cpfs://
為前綴,表示文件系統(tǒng)為CPFS。file-system-id.region.cpfs.aliyuncs.com:/share/path
表示<掛載地址>:<CPFS文件系統(tǒng)目錄> <當(dāng)前服務(wù)器上待掛載的本地路徑>,請根據(jù)實(shí)際情況替換。更多信息,請參考步驟二:使用CPFS-NFS客戶端掛載文件系統(tǒng)。
replicas
創(chuàng)建EFC緩存系統(tǒng)的Worker組件副本數(shù)。可以根據(jù)計(jì)算節(jié)點(diǎn)內(nèi)存配置和數(shù)據(jù)集大小進(jìn)行調(diào)整。建議quota和replicas乘積大于所需緩存的數(shù)據(jù)集總大小。
networkMode
取值ContainerNetwork和HostNetwork。在ACK環(huán)境中建議設(shè)置為ContainerNetwork,使用容器網(wǎng)絡(luò)不會有額外的性能損失。
mediumtype
緩存類型。只支持HDD、SSD和MEM。其中MEM代表內(nèi)存。在AI訓(xùn)練場景中,建議使用MEM。當(dāng)使用MEM時(shí),path所指定的緩存數(shù)據(jù)存儲目錄需要設(shè)置為內(nèi)存文件系統(tǒng)(例如tmpfs)。
path
EFC緩存系統(tǒng)Worker的緩存數(shù)據(jù)存儲目錄。建議使用/dev/shm。
quota
單個Worker組件提供的最大緩存容量。可以根據(jù)計(jì)算節(jié)點(diǎn)內(nèi)存配置和數(shù)據(jù)集大小進(jìn)行調(diào)整。建議quota和replicas乘積大于所需緩存的數(shù)據(jù)集總大小。
執(zhí)行以下命令,創(chuàng)建EFCRuntime和Dataset。
kubectl create -f dataset.yaml
執(zhí)行以下命令,查看Dataset的部署情況。
kubectl get dataset efc-demo
預(yù)期輸出:
NAME UFS TOTAL SIZE CACHED CACHE CAPACITY CACHED PERCENTAGE PHASE AGE efc-demo Bound 24m
Dataset處于Bound狀態(tài),表明EFC緩存系統(tǒng)已在集群內(nèi)正常啟動,應(yīng)用Pod可正常訪問Dataset中定義的數(shù)據(jù)。
執(zhí)行以下命令,查看EFCRuntime的部署情況。
kubectl get efcruntime
預(yù)期輸出:
NAME MASTER PHASE WORKER PHASE FUSE PHASE AGE efc-demo Ready Ready Ready 27m
預(yù)期輸出表明EFC緩存系統(tǒng)的Master組件、Worker組件以及FUSE組件都處于就緒狀態(tài)。
執(zhí)行以下命令,查看PVC和PV的創(chuàng)建情況。
在Dataset以及對應(yīng)的EFC緩存系統(tǒng)準(zhǔn)備就緒后,F(xiàn)luid將會自動創(chuàng)建PVC和PV。
kubectl get pv,pvc
預(yù)期輸出:
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE persistentvolume/default-efc-demo 100Gi ROX Retain Bound default/efc-demo fluid 94m NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE persistentvolumeclaim/efc-demo Bound default-efc-demo 100Gi ROX fluid 94m
步驟四:創(chuàng)建應(yīng)用容器訪問數(shù)據(jù)
您可以通過創(chuàng)建應(yīng)用容器來使用EFC加速服務(wù)。下述示例將創(chuàng)建兩個應(yīng)用容器,在兩個不同的節(jié)點(diǎn)上多次訪問同一存儲于NAS或CPFS文件系統(tǒng)中的數(shù)據(jù),通過比較訪問時(shí)間來展示EFCRuntime的加速效果。
創(chuàng)建app.yaml,代碼示例如下。
以下內(nèi)容描述了一個名為efc-app的StatefulSet資源對象,它包含兩個Pod,每個Pod都將使用Fluid自動創(chuàng)建的efc-demo PVC掛載到容器內(nèi)的/data目錄。
apiVersion: apps/v1 kind: StatefulSet metadata: name: efc-app labels: app: nginx spec: serviceName: nginx replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: registry.openanolis.cn/openanolis/nginx:1.14.1-8.6 command: ["/bin/bash"] args: ["-c", "sleep inf"] volumeMounts: - mountPath: "/data" name: data-vol volumes: - name: data-vol persistentVolumeClaim: claimName: efc-demo
執(zhí)行以下命令,創(chuàng)建名為efc-app的StatefulSet資源對象。
kubectl create -f app.yaml
執(zhí)行以下命令,查看文件大小。
kubectl exec -it efc-app-0 -- du -h /data/allzero-demo
預(yù)期輸出:
10G /data/allzero-demo
查看應(yīng)用容器文件的讀取時(shí)間。
說明讀取文件耗時(shí)和吞吐量可能隨運(yùn)行環(huán)境和測量方式而變化。本文是在一個有著三個ECS節(jié)點(diǎn)且節(jié)點(diǎn)實(shí)例規(guī)格均為ecs.g7ne.8xlarge的ACK集群中獲取的數(shù)據(jù)結(jié)果。其中,efc-demo的3個分布式緩存Worker Pod均運(yùn)行于一個ECS節(jié)點(diǎn)上,并且efc-app StatefulSet的兩個Pod分別運(yùn)行在另外兩個不同的節(jié)點(diǎn)上。數(shù)據(jù)結(jié)果不受FUSE端kernel cache影響。
執(zhí)行以下命令,查看第一個應(yīng)用容器中文件的讀取時(shí)間。
說明如果您使用自己的真實(shí)數(shù)據(jù)文件,您需要使用真實(shí)文件路徑替代以下命令中的/data/allzero-demo。
kubectl exec -it efc-app-0 -- bash -c "time cat /data/allzero-demo > /dev/null"
預(yù)期輸出:
real 0m15.792s user 0m0.023s sys 0m2.404s
預(yù)期輸出表明讀取10G文件需要15.792s,讀取速度為648 MiB/s。
執(zhí)行以下命令,在另一應(yīng)用容器中,讀取相同的10G大小文件的耗時(shí)。
說明如果您使用自己的真實(shí)數(shù)據(jù)文件,您需要使用真實(shí)文件路徑替代以下命令中的
/data/allzero-demo
。kubectl exec -it efc-app-1 -- bash -c "time cat /data/allzero-demo > /dev/null"
預(yù)期輸出:
real 0m9.970s user 0m0.012s sys 0m2.283s
預(yù)期輸出表明讀取10G文件需要9.970s,讀取速度為1034.3 MiB/s。
可以看到,沒有使用緩存時(shí),數(shù)據(jù)讀取速度為648 MiB/s;使用EFCRuntime緩存后,數(shù)據(jù)讀取速度為1034.3 MiB/s。對于相同文件,EFCRuntime提升了約2倍讀取效率。