通过 FUSE 的 POSIX API

Alluxio 的 POSIX API 允许您将 Alluxio 命名空间挂载为大多数类 Unix 操作系统上的标准文件系统。此功能通常称为“Alluxio FUSE”,让您可以使用标准命令行工具(lscatmkdir)和现有应用程序与 Alluxio 中的数据进行交互,而无需任何代码更改。

与 S3FS 等特定的文件系统包装器不同,Alluxio FUSE 作为 Alluxio 支持的许多存储系统的通用缓存和数据编排层,非常适合在 AI/ML 模型训练和服务等工作负载中加速 I/O。

基于用户空间文件系统 (FUSE)项目,挂载的文件系统提供了大多数基本操作,但由于 Alluxio 的分布式特性,它并非完全符合 POSIX 标准。有关详细信息,请参阅POSIX 兼容性部分。

何时使用 FUSE

FUSE 接口对于传统应用程序和现代 AI/ML 工作负载尤其强大。常见用例包括:

  • AI/ML 模型训练:在使用 PyTorch 或 TensorFlow 等框架训练模型时,您可以直接从挂载的 FUSE 路径读取数据集。这简化了数据访问,并利用 Alluxio 的缓存来显著加快训练作业。

  • 模型服务:对于需要快速加载模型的推理服务器,FUSE 提供了对存储在 Alluxio 中的模型的低延迟访问。

  • 遗留应用程序:期望标准文件系统的应用程序可以指向 FUSE 挂载点,以从 Alluxio 读取和写入数据,而无需修改。

  • 交互式数据探索:数据科学家和工程师可以使用 shell 命令(lscathead)来探索和与 Alluxio 中的数据进行交互,就像本地文件系统一样。

在 Kubernetes 上开始使用 FUSE

部署 Alluxio FUSE 的最常见方法是在 Kubernetes 集群上与您的应用程序一起部署。

先决条件

确保您的 Kubernetes 环境中有一个正在运行的 Alluxio 集群。有关说明,请参阅在 Kubernetes 上安装 Alluxio。

方法 1:使用 CSI(推荐)

容器存储接口 (CSI) 是在 Kubernetes 中使用 Alluxio FUSE 的标准推荐方法。Alluxio Operator 在安装集群时会自动配置一个名为 alluxio-cluster-fuse 的 PersistentVolumeClaim (PVC)。

要使用它,请将此 PVC 挂载到您的应用程序 pod 中。Operator 将处理底层 PersistentVolume (PV) 的创建和绑定。

示例 Pod 配置:

将以下配置保存到名为 fuse-pod.yaml 的文件中:

apiVersion: v1
kind: Pod
metadata:
  name: fuse-test-0
  namespace: alx-ns
  labels:
    app: alluxio
spec:
  containers:
    - image: ubuntu:22.04
      imagePullPolicy: IfNotPresent
      name: fuse-test
      command: ["sleep", "infinity"]
      volumeMounts:
        - mountPath: /data
          name: alluxio-pvc
          mountPropagation: HostToContainer
  volumes:
    - name: alluxio-pvc
      persistentVolumeClaim:
        claimName: alluxio-cluster-fuse

然后,使用 kubectl apply -f fuse-pod.yaml 创建 pod。

关键细节:

  • 共享 FUSE 进程:同一 Kubernetes 节点上的多个 pod 可以使用相同的 PVC,并将共享一个 Alluxio FUSE 进程以提高效率。

  • mountPropagation: HostToContainer:此设置至关重要。它确保如果 FUSE 进程崩溃,挂载点可以自动恢复并重新传播到您的容器。

挂载后,您可以像与 Alluxio 命名空间的根目录一样与 /data 目录进行交互。

示例用法:

# Connect to the test pod
$ kubectl -n alx-ns exec -it fuse-test-0 -- bash

# List the contents of the mounted directory
root@fuse-test-0:/$ ls /data/
s3

# Write a file and read it back
root@fuse-test-0:/$ echo "hello, world!" >/data/s3/message.txt
root@fuse-test-0:/$ cat /data/s3/message.txt
hello, world!

# Verify the file exists in Alluxio from another pod
$ kubectl -n alx-ns exec -it alluxio-cluster-coordinator-0 -- alluxio fs ls /s3/message.txt
             14                 06-27-2024 07:54:40:000 FILE /message.txt

方法 2:使用 DaemonSet

如果您的 Kubernetes 版本或环境不支持 CSI,您可以使用 DaemonSet 部署 FUSE。此方法在每个节点(或您选择的节点子集)上运行一个 FUSE pod。

  1. 配置 DaemonSet: 在部署 Alluxio 集群之前,修改您的 alluxio-cluster.yaml 以使用 daemonSet 类型并为挂载指定一个主机路径。

    apiVersion: k8s-operator.alluxio.com/v1
    kind: AlluxioCluster
    spec:
      fuse:
        type: daemonSet
        hostPathForMount: /mnt/alluxio/fuse # 如果未指定,将使用 /mnt/alluxio/fuse
        nodeSelector:
          alluxio.com/selected-for-fuse: true

    这将在所有带有标签 alluxio.com/selected-for-fuse: true 的节点上部署 FUSE pod。

  2. 在您的应用程序 Pod 中挂载: 在您的应用程序 pod 中,挂载 FUSE DaemonSet 公开文件系统的主机路径。

    apiVersion: v1
    kind: Pod
    metadata:
      name: fuse-test-0
      namespace: alx-ns
      labels:
        app: alluxio
    spec:
      containers:
        - image: ubuntu:22.04
          imagePullPolicy: IfNotPresent
          name: fuse-test
          command: ["sleep", "infinity"]
          volumeMounts:
            - mountPath: /mnt/alluxio
              name: alluxio-fuse-mount
              mountPropagation: HostToContainer
      volumes:
        - name: alluxio-fuse-mount
          hostPath:
            path: /mnt/alluxio
            type: Directory

    与 CSI 方法类似,mountPropagation 对于自动恢复至关重要。

高级配置

启用高级写入操作

默认情况下,Alluxio FUSE 支持标准的顺序写入。对于更高级的用例,您可以在 Alluxio 配置(alluxio-site.properties 或通过 Helm chart 值)中启用以下功能:

  • 追加和随机写入:要允许应用程序修改现有文件(例如,用于日志记录或数据库),请设置以下属性。请注意,这可能会对性能产生影响。

    alluxio.user.fuse.random.access.file.stream.enabled=true
  • 并发写入:要允许多个客户端同时写入同一文件,请设置以下属性。启用后,行为是“最后写入者获胜”。

    alluxio.user.fuse.concurrent.write.enabled=true

隔离数据访问

默认情况下,FUSE 挂载提供对整个 Alluxio 命名空间的访问。对于多租户环境,您可能希望将用户的访问限制在特定的子目录中。

使用 subPath(仅限 CSI)

您可以使用 subPath 字段将 Alluxio 命名空间中的特定子目录挂载到您的 pod 中。这是数据隔离的最简单方法。

# ... pod spec ...
      volumeMounts:
        - mountPath: /data
          name: alluxio-pvc
          mountPropagation: HostToContainer
          subPath: s3/path/to/files
# ...

在此示例中,容器内的 /data 目录直接映射到 Alluxio 中的 /s3/path/to/files

注意:不建议将 subPath 与 DaemonSet 方法一起使用,因为它会破坏自动恢复机制。

使用单独的 PVC(仅限 CSI)

为了在无法控制用户 pod 规范的情况下实现更强大的隔离,您可以创建一个专用的 StorageClassPersistentVolumeClaim,并将其预先绑定到特定的 Alluxio 路径。

  1. 创建自定义 StorageClassPVC 将以下内容保存到名为 custom-sc-pvc.yaml 的文件中:

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: default-alluxio-s3
      namespace: alx-ns
    parameters:
      alluxioClusterName: alluxio-cluster
      alluxioClusterNamespace: alx-ns
      mountPath: /s3/path/to/files
    provisioner: alluxio
    volumeBindingMode: WaitForFirstConsumer
    ---
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: alluxio-csi-s3
      namespace: alx-ns
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 1Mi
      storageClassName: default-alluxio-s3

    现在,应用配置:

    kubectl apply -f custom-sc-pvc.yaml
  2. 挂载新的 PVC: 用户现在可以挂载 alluxio-csi-s3 PVC,他们的访问将自动限定在 /s3/path/to/files

从另一个命名空间访问 FUSE

如果您的应用程序在与 Alluxio 集群不同的命名空间中运行,您必须在应用程序的命名空间中创建相应的 PVC。

  1. 在您的命名空间中创建 PVC: storageClassName 必须指向由 operator 在 Alluxio 命名空间中创建的 FUSE StorageClass(例如,alx-ns-alluxio-cluster-fuse)。将以下内容保存到名为 csi-pvc.yaml 的文件中:

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: alluxio-fuse
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 1Mi
      storageClassName: alx-ns-alluxio-cluster-fuse
  2. 应用 PVC:

    kubectl create -f csi-pvc.yaml -n <my-namespace>

自定义 FUSE 挂载选项

您可以通过在 AlluxioCluster YAML 中提供挂载选项来调整 FUSE 性能。这些选项直接传递给底层的 FUSE 驱动程序。有关完整列表,请参阅 FUSE 文档

示例配置:

fuse:
  mountOptions:
    - allow_other
    - kernel_cache
    - entry_timeout=60
    - attr_timeout=60
    - max_idle_threads=128
    - max_background=128

常用调整选项:

挂载选项
默认值
调整建议
描述

kernel_cache

启用

允许内核缓存文件数据,这可以显著提高读取性能。仅当底层文件未在外部(即 Alluxio 之外)修改时才使用此选项。

auto_cache

在裸机上启用

类似于 kernel_cache,但如果文件的修改时间或大小发生变化,缓存将失效。

attr_timeout=N

1.0

60

内核缓存文件和目录属性(如权限和大小)的秒数。增加此值可减少元数据开销。

entry_timeout=N

1.0

60

缓存文件名查找的秒数。增加此值可加快路径解析。

max_background=N

12

128

FUSE 内核驱动程序允许提交的最大未完成后台请求数。

max_idle_threads=N

10

128

FUSE 守护进程的最大空闲线程数。增加此值可以防止在重负载下频繁创建/销毁线程带来的性能开销。

自定义资源限制

您可以调整分配给 FUSE pod 及其 JVM 的 CPU 和内存资源。有关更多详细信息,请参阅高级集群配置。

apiVersion: k8s-operator.alluxio.com/v1
kind: AlluxioCluster
spec:
  fuse:
    resources:
      limits:
        cpu: "12"
        memory: "36Gi"
      requests:
        cpu: "1"
        memory: "32Gi"
    jvmOptions:
      - "-Xmx22g"
      - "-Xms22g"
      - "-XX:MaxDirectMemorySize=10g"

POSIX 兼容性

虽然支持大多数标准文件系统操作,但 Alluxio FUSE 不提供完全的 POSIX 兼容性。以下是支持和不支持的操作的摘要。

文件操作

注意:某些写入操作(例如,追加、随机和并发写入)受支持但默认禁用。有关如何启用它们的说明,请参阅启用高级写入操作

支持
不支持
  • 创建和删除文件

  • 重命名文件

  • 顺序、随机和并发读取

  • 顺序、追加、随机和并发写入

  • 截断或覆盖文件

  • 符号链接 (ln -s)

  • 获取文件状态 (stat)

  • 硬链接 (ln)

  • 文件锁定 (flock)

  • 更改所有权 (chown) 或权限 (chmod)

  • 更改访问/修改时间 (utimens)

  • 扩展属性 (chattr、粘滞位、xattr)

目录操作

支持
不支持
  • 创建和删除目录

  • 重命名目录

  • 列出目录内容 (ls)

  • 获取目录状态 (stat)

没有主要的不支持操作。

其他限制

  • 特殊文件:不支持设备文件、管道和 FIFO。

  • 路径名:避免在文件或目录名中使用特殊字符(?\)或模式(./../)。

Last updated