EFC提供了分布式缓存等能力以提升文件存储NAS的访问性能,同时支持高并发和大规模数据集的并行访问,适用于数据密集型和高并发访问的容器化应用场景(例如大数据分析、AI训练与推理等)。相比使用默认的NFS协议挂载NAS,使用EFC挂载NAS可以加速文件访问,提升读写性能。本文介绍如何通过CNFS使用EFC客户端挂载NAS文件系统。
EFC介绍
EFC弹性文件客户端(Elastic File Client)是阿里云提供的基于FUSE的用户态POSIX客户端。它可以替代传统的内核态NFS客户端,提供多链接访问、元数据缓存、分布式数据缓存等加速能力,并结合阿里云Prometheus监控提供端侧性能监控能力。
相比于内核态NFS客户端和其他基于开源FUSE的客户端,EFC客户端具有以下优势:
数据一致性保证:通过强一致的分布式锁机制实现文件和目录的强一致;文件写入可以立即被其他客户端读取;新文件创建出来后,就可以立即让所有的其他客户端同步访问到,便于您在多节点间管理数据。
单节点读写缓存能力:优化了FUSE的缓存逻辑,利用计算节点上的少量内存缓存数据,提供了更好的小文件读写性能。相比于传统的NFS客户端,性能提升了50%以上。
分布式只读缓存能力:支持基于多节点的内存构建分布式缓存池,可以随计算规模自动扩展且免运维。
小文件预取能力:可以自动识别并预取热目录和热文件,节省拉取数据的开销。
热升级和Failover能力:客户端版本更新无需重启应用,客户端异常时支持自动切换,业务无感知。
前提条件
集群中已安装cnfs-nas-daemon组件,并在csi-plugin组件的FeatureGate中增加
AlinasMountProxy=true
以启用cnfs-nas-daemon。具体操作,请参见管理cnfs-nas-daemon组件。节点操作系统为Alibaba Cloud Linux 3或ContainerOS,内核版本为5.10.134-17.2及以上。
重要当节点操作系统或内核版本不满足要求时,系统将自动切换为NFS协议进行挂载。
(可选)部署CNFS-EFC分布式缓存
如需使用EFC的分布式缓存能力,需要先部署CNFS-EFC分布式缓存插件。
在集群中创建并部署csi-plugin的ConfigMap,用于部署CNFS-EFC分布式缓存插件。
ConfigMap部署完成后,会根据已配置的ConfigMap自动部署缓存的DaemonSet以及Service。
将以下内容保存为csi-configmap.yaml。
以下YAML示例用于部署分布式缓存的DaemonSet,DaemonSet会在带有
cache=true
标签的节点上创建Pod,每个Pod包含3个容器,挂载了15 GiB的tmpfs卷(基于内存)。您可以根据实际需求修改参数配置。apiVersion: v1 kind: ConfigMap metadata: name: csi-plugin namespace: kube-system data: nas-efc-cache: | enable=true container-number=3 volume-type=memory volume-size=15Gi node-selector: | cache=true
参数
说明
nfs-efc-cache
enable
配置为
true
,开启分布式缓存。container-number
缓存的DaemonSet中每个Pod包含的容器数量,当缓存出现性能瓶颈时,可以增加容器数量。
volume-type
缓存Pod挂载的EmptyDir卷所使用的存储介质。
disk
:磁盘。memory
:内存。
重要使用磁盘或内存时,会使用节点的数据盘和内存资源,请确保不影响业务运行。
volume-size
缓存Pod中Volume的大小。单位:GiB。
node-selector
缓存的DaemonSet通过Label进行调度。如果不配置,则所有节点都会部署DaemonSet。
部署ConfigMap。
kubectl apply -f csi-configmap.yaml
确认分布式缓存的DaemonSet是否启动。
kubectl get ds/cnfs-cache-ds -n kube-system -o wide
返回示例如下,本示例的集群中有2个带有
cache=true
标签的节点,对应DaemonSet中的2个Pod均处于可用状态,说明分布式缓存的DaemonSet已经启动完成。NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE CONTAINERS IMAGES SELECTOR cnfs-cache-ds 2 2 2 2 2 cache=true 13m alinas-dadi-container,alinas-dadi-container1,alinas-dadi-container2 registry-cn-hangzhou.ack.aliyuncs.com/acs/nas-cache:20220420,registry-cn-hangzhou.ack.aliyuncs.com/acs/nas-cache:20220420,registry-cn-hangzhou.ack.aliyuncs.com/acs/nas-cache:20220420 app=cnfs-cache-ds
确认分布式缓存的Service是否实现服务发现。
kubectl get ep cnfs-cache-ds-service -n kube-system -o wide
返回示例如下,Service已经发现后端缓存Pod对应的Endpoints。
NAME ENDPOINTS AGE cnfs-cache-ds-service 192.168.3.217:6500,192.168.5.247:6500,192.168.3.217:6502 + 3 more... 2d3h
配置CNFS使用EFC客户端挂载NAS
创建CNFS,指定使用EFC客户端。
将以下内容保存为cnfs-efc.yaml。
说明示例以使用CNFS配置已有NAS文件系统为例,演示如何开启EFC客户端。如果使用CNFS新建NAS文件系统,也可以通过在ContainerNetworkFileSystem资源的
parameters
添加useClient: EFCClient
的方式来开启EFC客户端。关于如何使用CNFS创建NAS文件系统,请参见通过CNFS管理NAS文件系统(推荐)。apiVersion: storage.alibabacloud.com/v1beta1 kind: ContainerNetworkFileSystem metadata: name: cnfs-efc-test spec: description: "cnfs" type: nas reclaimPolicy: Retain parameters: server: 17f7e4****-h****.cn-beijing.nas.aliyuncs.com useClient: EFCClient
参数
说明
description
文件系统的描述。
type
需要创建的存储卷类型。
reclaimPolicy
回收策略,目前仅支持
Retain
策略,删除CNFS时并不会删除NAS文件系统。parameters
server
NAS挂载点的地址。挂载点需满足以下要求:
挂载点的VPC必须和集群中Pod使用的VPC一致,否则会导致挂载失败。
挂载点的交换机建议和集群中Pod使用的交换机一致,性能相对更优。
挂载点的状态为可用。
如果已有挂载点不满足要求,可创建新的挂载点。更多信息,请参见管理挂载点。
useClient
配置为
EFCClient
,表示开启EFC客户端。创建CNFS。
kubectl create -f cnfs-efc.yaml
使用CNFS创建对应的存储卷。
kubectl create -f cnfs-pv-pvc.yaml
cnfs-pv-pvc.yaml的内容示例如下。如果集群中已部署CNFS-EFC分布式缓存,您可以通过
mountOptions
配置EFC开启缓存和预读能力;若未部署,请删除示例中的mountOptions
配置。apiVersion: v1 kind: PersistentVolume metadata: name: efc-pv spec: accessModes: - ReadWriteMany capacity: storage: 50Gi claimRef: name: efc-pvc namespace: default csi: driver: nasplugin.csi.alibabacloud.com volumeAttributes: containerNetworkFileSystem: cnfs-efc-test path: / volumeHandle: efc-pv mountOptions: - g_tier_EnableClusterCache=true # 挂载时,分布式缓存使用缓存配置。 - g_tier_EnableClusterCachePrefetch=true # 挂载时,分布式缓存开启预读功能。 volumeMode: Filesystem --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: efc-pvc namespace: default spec: accessModes: - ReadWriteMany resources: requests: storage: 50Gi storageClassName: "" volumeMode: Filesystem volumeName: efc-pv
创建工作负载并挂载NAS
创建Deployment并挂载NAS。
kubectl create -f cnfs-deployment.yaml
cnfs-deployment.yaml的内容示例如下:
apiVersion: apps/v1 kind: Deployment metadata: name: efc-test namespace: default spec: replicas: 1 selector: matchLabels: app: efc-test template: metadata: labels: app: efc-test spec: containers: - command: - sh - -c - | sleep infinity image: alibaba-cloud-linux-3-registry.cn-hangzhou.cr.aliyuncs.com/alinux3/alinux3:latest name: test volumeMounts: - mountPath: /mnt name: pvc volumes: - name: pvc persistentVolumeClaim: claimName: efc-pvc
查看Deployment中Pod的部署情况。
kubectl get pod -l app=efc-test
预期返回:
NAME READY STATUS RESTARTS AGE efc-test-f545b86d6-spr7p 1/1 Running 0 29m
等待Pod Running后,在Pod中查看EFC挂载点。
kubectl exec <pod-name> -- mount -t fuse.aliyun-alinas-efc
预期返回:
bindroot-3889a-8TzEY5mc:3d2804****-w****.cn-shanghai.nas.aliyuncs.com:/ on /mnt type fuse.aliyun-alinas-efc (rw,relatime,user_id=0,group_id=0,default_permissions,allow_other,max_read=1048576)