# 通过 FUSE 的 POSIX API

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

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

<figure><img src="/files/axrxhmcaAC21IbqlqXUs" alt=""><figcaption></figcaption></figure>

基于[用户空间文件系统 (FUSE)](https://en.wikipedia.org/wiki/Filesystem_in_Userspace)项目，挂载的文件系统提供了大多数基本操作，但由于 Alluxio 的分布式特性，它并非完全符合 POSIX 标准。有关详细信息，请参阅[POSIX 兼容性](#posix-jian-rong-xing)部分。

## 何时使用 FUSE

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

* **AI/ML 模型训练**：在使用 PyTorch 或 TensorFlow 等框架训练模型时，您可以直接从挂载的 FUSE 路径读取数据集。这简化了数据访问，并利用 Alluxio 的缓存来显著加快训练作业。
* **模型服务**：对于需要快速加载模型的推理服务器，FUSE 提供了对存储在 Alluxio 中的模型的低延迟访问。
* **遗留应用程序**：期望标准文件系统的应用程序可以指向 FUSE 挂载点，以从 Alluxio 读取和写入数据，而无需修改。
* **交互式数据探索**：数据科学家和工程师可以使用 shell 命令（`ls`、`cat`、`head`）来探索和与 Alluxio 中的数据进行交互，就像本地文件系统一样。

## 在 Kubernetes 上开始使用 FUSE

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

### 先决条件

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

### 方法 1：使用 CSI（推荐）

[容器存储接口 (CSI)](https://github.com/container-storage-interface/spec/blob/master/spec.md) 是在 Kubernetes 中使用 Alluxio FUSE 的标准推荐方法。Alluxio Operator 在安装集群时会自动配置一个名为 `alluxio-cluster-fuse` 的 PersistentVolumeClaim (PVC)。

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

**示例 Pod 配置：**

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

```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` 目录进行交互。

**示例用法：**

```shell
# 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` 类型并为挂载指定一个主机路径。

   ```yaml
   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 公开文件系统的主机路径。

   ```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: /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 值）中启用以下功能：

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

  ```properties
  alluxio.user.fuse.random.access.file.stream.enabled=true
  ```

### 启用符号链接

默认情况下，符号链接 (symlinks) 处于禁用状态。要启用它们，您需要在 Alluxio 配置（`alluxio-site.properties` 或通过 Helm chart 值）中设置以下属性：

```properties
alluxio.user.fuse.symlink.enabled=true
```

### 隔离数据访问

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

#### 使用 `subPath`（仅限 CSI）

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

```yaml
# ... 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 规范的情况下实现更强大的隔离，您可以创建一个专用的 `StorageClass` 和 `PersistentVolumeClaim`，并将其预先绑定到特定的 Alluxio 路径。

1. **创建自定义 `StorageClass` 和 `PVC`：** 将以下内容保存到名为 `custom-sc-pvc.yaml` 的文件中：

   ```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
   ```

   现在，应用配置：

   ```shell
   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` 的文件中：

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

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

### 自定义 FUSE 挂载选项

您可以通过在 `AlluxioCluster` YAML 中提供挂载选项来调整 FUSE 性能。这些选项直接传递给底层的 FUSE 驱动程序。有关完整列表，请参阅 [FUSE 文档](http://man7.org/linux/man-pages/man8/mount.fuse3.8.html)。

**示例配置：**

```yaml
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 和内存资源。有关更多详细信息，请参阅高级集群配置。

```yaml
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 兼容性。以下是支持和不支持的操作的摘要。

### 文件操作

| 支持                                                                                                                                                                    | 不支持                                                                                                                                                                                                                                              |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| <ul><li>创建和删除文件</li><li>重命名文件</li><li>顺序、随机和并发读取</li><li>顺序、追加、随机和并发写入</li><li>截断或覆盖文件</li><li>符号链接 (<code>ln -s</code>)</li><li>获取文件状态 (<code>stat</code>)</li></ul> | <ul><li>硬链接 (<code>ln</code>)</li><li>文件锁定 (<code>flock</code>)</li><li>更改所有权 (<code>chown</code>) 或权限 (<code>chmod</code>)</li><li>更改访问/修改时间 (<code>utimens</code>)</li><li>扩展属性 (<code>chattr</code>、粘滞位、xattr)</li><li>对同一文件的原子并发写入</li></ul> |

> **注意**：某些功能（如高级写入和符号链接）支持但默认禁用。有关如何启用它们的说明，请参阅以下部分：
>
> * [启用高级写入操作](#qi-yong-gao-ji-xie-ru-cao-zuo)
> * [启用符号链接](#qi-yong-fu-hao-lian-jie)

### 目录操作

| 支持                                                                                                          | 不支持         |
| ----------------------------------------------------------------------------------------------------------- | ----------- |
| <ul><li>创建和删除目录</li><li>重命名目录</li><li>列出目录内容 (<code>ls</code>)</li><li>获取目录状态 (<code>stat</code>)</li></ul> | 没有主要的不支持操作。 |

### 其他限制

* **特殊文件**：不支持设备文件、管道和 FIFO。
* **路径名**：避免在文件或目录名中使用特殊字符（`?`、`\`）或模式（`./`、`../`）。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://documentation.alluxio.io/ee-ai-cn/ai-3.7/data-access/fuse-based-posix-api.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
