使用strmvol存储卷优化OSS小文件读取性能

在容器化场景中,传统方案常采用基于FUSE的文件系统(如ossfs)挂载对象存储数据。但对于小文件读取密集型场景(例如AI训练集加载、时序日志分析等需要快速遍历百万级小文件的业务场景),传统方案难以满足高吞吐与低延迟需求。此时,推荐采用虚拟块设备方案,通过strmvol存储卷直接挂载对象存储数据,优化小文件读取性能。

注意事项

strmvol存储卷

  • 目前仅支持以内网方式访问OSS数据,即仅支持使用内网Endpoint。

  • 虚拟块设备初始化时需要构建全量的文件元信息索引,该阶段需要占用节点部分资源,业务Pod会处于ContainerCreating状态。所需资源与时间与OSS Bucket挂载路径下文件数量紧密相关。

    • 在选择OSS Bucket挂载路径时应按照最小原则。

      如业务A访问OSS Bucket/app/a/下的内容,业务B访问/app/b/下的内容时,建议为A、B业务分别创建挂载目标路径为/app/a//app/b/的存储卷。

    • 初始化期间所需时间及资源开销,请参见元数据索引构建

  • 虚拟块设备在节点上挂载期间(除初始化阶段)占用的资源开销受PV上的相关配置限制,请保留足够的节点资源。

  • 单块虚拟块设备容量为16 TiB,即挂载的OSS路径下最多可存储16 TiB数据。

集群和节点要求

  • 集群类型为ACK托管集群ProACK专有集群,且集群版本为1.20及以上,存储插件类型为CSI。

  • 节点内核版本≥4.19,资源规格建议4C8G及以上。

  • 支持的节点OS:Alibaba Cloud Linux 3、Alibaba Cloud Linux 2、CentOS 7。为使用erofs操作系统优化数据访问性能,推荐使用Alibaba Cloud Linux 3。

    说明

    CentOS 7AliyunLinux 2目前已停止维护(EOL),具体请参见【产品变更】停止维护Alibaba Cloud Linux 2、CentOS 7的公告

  • 暂不支持为调度到虚拟节点上的Serverless Pod挂载strmvol存储卷。

准备工作

步骤一:部署strmvol-csi-driver

使用strmvol存储卷需要部署单独的CSI驱动(strmvol-csi-driver组件)。部署后,该CSI驱动与ACK组件管理中维护的csi-provisionercsi-plugin组件相互独立,不会产生冲突。

  1. 登录容器服务管理控制台,在左侧导航栏,选择市场 > 应用市场

  2. 应用市场页面,搜索strmvol-csi-driver,然后单击对应的卡片。

  3. 在应用详情页面,单击右上角的一键部署

  4. 在弹出面板中完成基本信息和参数配置,单击确定

步骤二:配置OSS访问权限

  1. 创建RAM用户并授权。

    1. 创建RAM用户,如已创建可跳过。具体操作,请参见创建RAM用户

    2. 创建如下OSS访问的自定义权限策略。具体操作,请参见创建自定义权限策略

      以下只读和读写权限策略请根据使用需求选择,并替换mybucket为您实际创建的Bucket名称。

      • OSS只读权限策略

        展开查看OSS只读权限策略内容

        {
            "Statement": [
                {
                    "Action": [
                        "oss:Get*",
                        "oss:List*"
                    ],
                    "Effect": "Allow",
                    "Resource": [
                        "acs:oss:*:*:mybucket",
                        "acs:oss:*:*:mybucket/*"
                    ]
                }
            ],
            "Version": "1"
        }
      • OSS读写权限

        展开查看OSS读写权限策略内容

        {
            "Statement": [
                {
                    "Action": "oss:*",
                    "Effect": "Allow",
                    "Resource": [
                        "acs:oss:*:*:mybucket",
                        "acs:oss:*:*:mybucket/*"
                    ]
                }
            ],
            "Version": "1"
        }
    3. (可选)若您使用KMS托管的指定CMK ID加密OSS Object,还需要为该RAM用户配置KMS权限。具体操作,请参见加密操作

    4. RAM用户添加OSS权限。具体操作,请参见RAM用户授权

    5. RAM用户创建AccessKey。具体操作,请参见获取AccessKey

  2. 创建存放鉴权信息的Secret,用于访问OSS数据。

    命令示例如下,请替换akIdakSecret为实际使用的AccessKey。

    kubectl create -n default secret generic strmvol-secret --from-literal='akId=xxxxxx' --from-literal='akSecret=xxxxxx'

挂载strmvol存储卷

步骤一:创建strmvol存储卷

使用strmvol静态卷

  1. 创建PV。

    1. 修改以下YAML,保存为strmvol-pv.yaml。

      apiVersion: v1
      kind: PersistentVolume
      metadata:
        name: pv-strmvol
      spec:
        capacity:
        # 挂载的OSS挂载点下最高可存储16 TiB数据。
          storage: 20Gi
        # 仅支持ReadOnlyMany访问模式。
        accessModes:
          - ReadOnlyMany
        # 为避免删除远端数据,目前仅支持Retain。 
        persistentVolumeReclaimPolicy: Retain
        csi:
          driver: strmvolplugin.csi.alibabacloud.com
          volumeHandle: pv-strmvol
          # 使用准备工作中创建的secret。
          nodeStageSecretRef:
            name: strmvol-secret
            namespace: default
          volumeAttributes:
            bucket: cnfs-oss-test
            path: /subpath
            # strmvol存储卷仅支持以内网访问OSS数据。
            url: oss-cn-hangzhou-internal.aliyuncs.com
            umask: "000"
            directMode: "false"
            resourceLimit: "2c4g"
      • nodeStageSecretRef参数说明

        参数

        是否必选

        说明

        name

        必选

        存储AccessKey信息的Secret名称。

        namespace

        必选

        存储AccessKey信息的Secret所在的命名空间。

      • volumeAttributes参数说明

        参数

        是否必选

        说明

        bucket

        必选

        需要挂载的OSS Bucket。

        path

        可选

        OSS Bucket挂载路径表示挂载时相对Bucket根文件的目录结构。

        重要

        挂载路径的选择应按照最小够用原则。

        url

        必选

        挂载OSS的内网Endpoint。EndpointOSS控制台Bucket概览页为准,常见内网格式如下:

        http://oss-{{regionName}}-internal.aliyuncs.comhttps://oss-{{regionName}}-internal.aliyuncs.com

        重要

        vpc100-oss-{{regionName}}.aliyuncs.com的内网访问端口格式已废弃,请及时切换。

        umask

        可选

        挂载虚拟块设备后文件系统默认权限的掩码。

        如若您期望文件系统的默认权限为755,则umask应配置为022。

        directMode

        可选

        是否开启direct模式。

        • "true":开启direct模式时,关闭预取与数据本地缓存,适合小文件随机读场景,如训练集的随机批量读取。

        • "false":默认关闭direct模式,适合小文件顺序读、大文件等通用场景。若您的业务没有明显数据读取特性,请保持direct模式关闭。

        resourceLimit

        可选

        挂载虚拟块设备后能使用节点的最大资源限制。

        "2c4g"表示该虚拟块设备最多能占用节点的2 vCPU、4GiB内存资源。

        说明
        • 内存主要用于数据预取与本地缓存。开启direct模式时,所需内存量会明显低于预设值。

        • 对非Alibaba Cloud Linux 3操作系统,数据读取性能上限趋近,因此不推荐使用过高配置。具体请参见数据读取性能测试

    2. 创建PV。

      kubectl create -f strmvol-pv.yaml
    3. 确认PV状态。

      kubectl get pv pv-strmvol

      预期返回如下:

      NAME         CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   VOLUMEATTRIBUTESCLASS   REASON   AGE
      pv-strmvol   20Gi       ROX            Retain           Available                          <unset>                          18s
  2. 创建PVC。

    1. 修改以下YAML,保存为strmvol-pvc-static.yaml。

      kind: PersistentVolumeClaim
      apiVersion: v1
      metadata:
        name: pvc-strmvol
        namespace: default
      spec:
        # 以下配置需要与PV一致
        accessModes:
          - ReadOnlyMany
        resources:
          requests:
            storage: 20Gi
        volumeName: pv-strmvol
    2. 创建PVC。

      kubectl create -f strmvol-pvc-static.yaml
    3. 确认PVC状态。

      kubectl get pvc pvc-strmvol

      预期返回如下,可以看到PVC已绑定PV。

      NAME            STATUS   VOLUME       CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
      pvc-strmvol-2   Bound    pv-strmvol   20Gi       ROX                           <unset>                 16s

使用strmvol动态卷

  1. 创建StorageClass。

    1. 修改以下YAML,保存为strmvol-sc.yaml。

      apiVersion: storage.k8s.io/v1
      kind: StorageClass
      metadata:
        name: strmvol-test
      parameters:
        # 使用准备工作中创建的secret。
        csi.storage.k8s.io/node-stage-secret-name: strmvol-secret  
        csi.storage.k8s.io/node-stage-secret-namespace: default
        bucket: cnfs-oss-test 
        path: /subpath
        # strmvol存储卷仅支持以内网访问OSS数据。
        url: oss-cn-hangzhou-internal.aliyuncs.com 
        umask: "000"
        directMode: "false"
        resourceLimit: "2c4g"
      provisioner: strmvolplugin.csi.alibabacloud.com
      # 为避免删除远端数据,目前仅支持Retain 
      reclaimPolicy: Retain
      volumeBindingMode: Immediate

      parameters中的相关参数说明如下:

      • 配置Secret

        参数

        是否必选

        说明

        csi.storage.k8s.io/node-stage-secret-name

        必选

        存储AccessKey信息的Secret名称。

        csi.storage.k8s.io/node-stage-secret-namespace

        必选

        存储AccessKey信息的Secret所在的命名空间。

      • 配置存储卷

        参数

        是否必选

        说明

        bucket

        必选

        需要挂载的OSS Bucket。

        path

        可选

        OSS Bucket挂载路径表示挂载时相对Bucket根文件的目录结构。

        重要

        挂载路径的选择应按照最小够用原则。

        url

        必选

        挂载OSS的内网Endpoint。EndpointOSS控制台Bucket概览页为准,常见内网格式如下:

        http://oss-{{regionName}}-internal.aliyuncs.comhttps://oss-{{regionName}}-internal.aliyuncs.com

        重要

        vpc100-oss-{{regionName}}.aliyuncs.com的内网访问端口格式已废弃,请及时切换。

        umask

        可选

        挂载虚拟块设备后文件系统默认权限的掩码。

        如若您期望文件系统的默认权限为755,则umask应配置为022。

        directMode

        可选

        是否开启direct模式。

        • "true":开启direct模式时,关闭预取与数据本地缓存,适合小文件随机读场景,如训练集的随机批量读取。

        • "false":默认关闭direct模式,适合小文件顺序读、大文件等通用场景。若您的业务没有明显数据读取特性,请保持direct模式关闭。

        resourceLimit

        可选

        挂载虚拟块设备后能使用节点的最大资源限制。

        "2c4g"表示该虚拟块设备最多能占用节点的2 vCPU、4GiB内存资源。

        说明
        • 内存主要用于数据预取与本地缓存。开启direct模式时,所需内存量会明显低于预设值。

        • 对非Alibaba Cloud Linux 3操作系统,数据读取性能上限趋近,因此不推荐使用过高配置。具体请参见数据读取性能测试

    2. 创建StorageClass。

      kubectl create -f strmvol-sc.yaml
  2. 创建PVC。

    1. 修改以下YAML,保存为strmvol-pvc-dynamic.yaml。

      kind: PersistentVolumeClaim
      apiVersion: v1
      metadata:
        name: pvc-strmvol
        namespace: default
      spec:
        # 仅支持ReadOnlyMany访问模式
        accessModes:
          - ReadOnlyMany
        # 指定StorageClass
        storageClassName: strmvol-test
        resources:
          requests:
            # 挂载的OSS挂载点下最高可存储16 TiB数据
            storage: 20Gi
    2. 创建PVC。

      kubectl create -f strmvol-pvc-dynamic.yaml
    3. 确认PVC状态。

      kubectl get pvc pvc-strmvol

      预期返回如下,可以看到PVC已绑定CSI自动创建的PV。

      NAME          STATUS   VOLUME                                         CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
      pvc-strmvol   Bound    strmvol-d8d1d22a-e1d7-4caa-b875-54f378dec769   20Gi       ROX            strmvol-test   <unset>                 3m

步骤二:创建应用并挂载strmvol存储卷

  1. 使用以下YAML,创建strmvol-test.yaml。

    以下YAML示例可以创建包含1PodStatefulSet,Pod通过名为pvc-strmvolPVC申请存储资源,挂载路径为/data

    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: strmvol-test
      namespace: default
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: strmvol-test
      template:
        metadata:
          labels:
            app: strmvol-test
        spec:
          containers:
          - name: nginx
            image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6
            ports:
            - containerPort: 80
            volumeMounts:
            - name: pvc-strmvol
              mountPath: /data
          volumes:
            - name: pvc-strmvol
              persistentVolumeClaim:
                claimName: pvc-strmvol
  2. 创建StatefulSet并挂载strmvol存储卷。

    kubectl create -f strmvol-test.yaml
  3. 查看StatefulSetPod的部署情况。

    kubectl get pod -l app=strmvol-test

    预期返回:

    NAME             READY   STATUS    RESTARTS   AGE
    strmvol-test-0   1/1     Running   0          14s
  4. 验证挂载点类型为块设备,且应用能正常访问OSS数据。

    kubectl exec -it strmvol-test-0 -- sh -c "df /data && ls /data"

    预期返回:

    Filesystem     1K-blocks  Used Available Use% Mounted on
    /dev/ublkb1        24812 24812         0 100% /data
    <data in OSS mountpath>

相关文档

strmvol客户端性能压测