> For the complete documentation index, see [llms.txt](https://documentation.alluxio.io/ee-ai-cn/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://documentation.alluxio.io/ee-ai-cn/data-access/fuse-based-posix-api.md).

# POSIX API

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

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

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

## 何时使用 FUSE

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

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

## 先决条件

* [ ] **Alluxio 集群正在运行且可达**，承载 FUSE 的节点或 Pod 能访问到。没有的话先按 [在 Kubernetes 上安装](/ee-ai-cn/start/installing-on-kubernetes.md) 或 [Docker 安装](/ee-ai-cn/start/installing-on-docker.md) 部署。
* [ ] **`/dev/fuse` 设备可用**——Docker / Bare-Metal 下是主机，Kubernetes 下是承载 FUSE Pod 的节点。大多数现代 Linux 发行版默认就有，可用 `ls -l /dev/fuse` 检查。

下面 [Quick Start](#quick-start) 的每个子小节列出了部署方式特有的额外先决条件。

## Quick Start

支持三种部署方式。选择最符合你环境的那一个：

* [**方法 1：Kubernetes + CSI**](#fang-fa-1-kubernetes-csi-tui-jian) —— Kubernetes 集群下的标准推荐方式。需要 CSI 驱动（Alluxio Operator 默认部署）。
* [**方法 2：Kubernetes + DaemonSet**](#fang-fa-2-kubernetes-daemonset) —— CSI 不可用或已禁用（`alluxio-csi.enabled: false`）时使用。
* [**方法 3：Docker / Bare-Metal**](#fang-fa-3-docker-baremetal) —— 任何 Linux 主机上的独立 Docker 容器。

### 方法 1：Kubernetes + CSI（推荐）

方式特有的先决条件：

* [ ] **Alluxio 集群就绪**：

  ```shell
  kubectl -n alx-ns get alluxiocluster
  ```

  预期结果：`CLUSTERPHASE` = `Ready`。
* [ ] **CSI 驱动已部署**（Alluxio Operator 默认部署）：

  ```shell
  kubectl -n alluxio-operator get pod -l app=alluxio-csi-nodeplugin
  ```

  预期结果：每个节点上的 CSI nodeplugin pod 状态为 `Running`。如果在 Operator 安装时禁用了 CSI（`alluxio-csi.enabled: false`），请改用 [方法 2：DaemonSet](#fang-fa-2-kubernetes-daemonset)。
* [ ] **FUSE PVC 存在**：

  ```shell
  kubectl -n alx-ns get pvc alluxio-cluster-fuse
  ```

  预期结果：PVC 存在（在 pod 使用之前它将处于 `Pending` 状态——这是正常的）。

[容器存储接口 (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
```

创建 pod：

```shell
# Idempotent
kubectl apply -f fuse-pod.yaml
```

验证 pod 正在运行且 FUSE 挂载可访问：

```shell
kubectl -n alx-ns get pod fuse-test-0
```

预期结果：`STATUS` = `Running`，`READY` = `1/1`。

关键细节：

* **共享 FUSE 进程**：同一 Kubernetes 节点上的多个 pod 可以使用相同的 PVC，并将共享一个 Alluxio FUSE 进程以提高效率。
* **`mountPropagation: HostToContainer`**：此设置至关重要。它确保如果 FUSE 进程崩溃，挂载点可以自动恢复并重新传播到您的容器。

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

### 方法 2：Kubernetes + 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。首先标记节点：

   ```shell
   kubectl label nodes <node-name> alluxio.com/selected-for-fuse=true
   ```
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` 对于自动恢复至关重要。
3. **验证：** 部署后，确认 DaemonSet pod 正在运行且挂载可访问：

   ```shell
   kubectl -n alx-ns get pod -l app=alluxio-fuse
   ```

   预期结果：每个标记节点上的 FUSE pod 状态为 `Running`。

### 方法 3：Docker / Bare-Metal

在没有 Kubernetes 的主机上，Alluxio FUSE 客户端以 host-network 模式的独立 Docker 容器运行。参考部署是每个 client 主机运行一个 FUSE 容器，指向 [Docker 安装](/ee-ai-cn/start/installing-on-docker.md) 里起好的 Alluxio。

先创建主机挂载点（镜像里 alluxio 用户 UID=1000，所以 owner 要匹配），再起容器：

```shell
sudo mkdir -p /mnt/alluxio/fuse
sudo chown 1000:1000 /mnt/alluxio/fuse

sudo docker run -d --name alluxio-fuse --net=host --restart=always \
  --device /dev/fuse --cap-add SYS_ADMIN --security-opt apparmor=unconfined \
  -e ALLUXIO_JAVA_OPTS="<JAVA_OPTS>" \
  -v /mnt/alluxio:/mnt/alluxio:rshared \
  alluxio/alluxio-enterprise:AI-3.9-16.0.0 \
  fuse -o allow_other -- /mnt/alluxio/fuse
```

* `--device /dev/fuse` + `--cap-add SYS_ADMIN` 授予容器挂 FUSE 需要的权限；`--security-opt apparmor=unconfined` 用于默认 AppArmor profile 会阻挡 FUSE 的发行版。
* `-v /mnt/alluxio:/mnt/alluxio:rshared` 用 recursive shared mount propagation，让 host 能看到容器内的 FUSE 挂载。
* `<JAVA_OPTS>` 填入用于发现集群的 etcd endpoint 以及 JVM 堆 / direct memory 大小——见 [自定义资源限制](#zi-ding-yi-zi-yuan-xian-zhi)。

**✅ 验证** 挂载已生效：

```shell
ls /mnt/alluxio/fuse/
```

会列出已注册的 UFS 挂载。返回 `Transport endpoint is not connected` 说明容器已退出——查 `sudo docker logs alluxio-fuse`。

### 验证端到端访问

不管用的是哪种部署方式，都可以通过 FUSE 走一轮读写往返，然后用 Alluxio 直接 `ls` 确认同一个文件可见，来验证数据通道正确。下面示例假设 FUSE 挂载点是 `/data`（Kubernetes）或 `/mnt/alluxio/fuse`（Docker / Bare-Metal）。

{% tabs %}
{% tab title="Kubernetes (Operator)" %}

```shell
# 从应用 pod 通过 FUSE 读写
kubectl -n alx-ns exec -it fuse-test-0 -- bash -c 'echo "hello, world!" > /data/s3/message.txt'
kubectl -n alx-ns exec -it fuse-test-0 -- cat /data/s3/message.txt

# 从 Alluxio 直接验证文件可见
kubectl -n alx-ns exec -i alluxio-cluster-coordinator-0 -- alluxio fs ls /s3/message.txt
```

{% endtab %}

{% tab title="Docker / Bare-Metal" %}

```shell
# 通过 FUSE 读写
echo "hello, world!" | sudo tee /mnt/alluxio/fuse/s3/message.txt
cat /mnt/alluxio/fuse/s3/message.txt

# 从 Alluxio 直接验证文件可见
docker exec alluxio-coordinator alluxio fs ls /s3/message.txt
```

{% endtab %}
{% endtabs %}

**✅ 成功标志：** `cat` 返回 `hello, world!`；`alluxio fs ls` 显示相同大小的文件——说明 FUSE 写入真的走到了 Alluxio。

## 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-zhui-jia-he-sui-ji-xie-ru)
> * [启用符号链接](#qi-yong-fu-hao-lian-jie)

### 目录操作

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

### 其他限制

* **特殊文件**：不支持设备文件、管道和 FIFO。
* **路径名**：避免在文件或目录名中使用特殊字符（`?`、`\`）或模式（`./`、`../`）。
* **容量报告**：`df`、`statvfs` 等调用不反映 UFS 后端的真实容量。做容量规划时把 FUSE 挂载点视为无限大。
* **元数据新鲜度**：文件和目录元数据在内核里按 `attr_timeout` / `entry_timeout` 秒缓存（默认 60）。FUSE client 运行期间若有外部进程直接改 UFS，改动可能最多延迟这个窗口才被 FUSE 看到。若需要亚分钟级一致性，调小这两个 timeout——见 [自定义 FUSE 挂载选项](#zi-ding-yi-fuse-gua-zai-xuan-xiang)。

## 高级配置

### 启用追加和随机写入

要启用**追加和随机写入**操作，请在您的 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
```

### 启用并行 `getattr` 操作

默认情况下，FUSE 内核模块会串行处理同一目录下的 `lookup` 和 `readdir` 操作。为了提高需要高并发元数据操作的工作负载（例如对同一目录下的许多文件进行 `getattr`）的性能，您可以启用并行目录操作。

要启用此功能，请在您的 Alluxio 配置（`alluxio-site.properties`）中设置以下属性：

```properties
alluxio.fuse.parallel.dirops.enabled=true
```

> **注意**：该功能目前建议仅用于**只读**工作负载。

### 隔离数据访问

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

#### 使用 Ephemeral CSI Volume（推荐）

使用 ephemeral CSI volume 并通过 `mountPath` volume 属性来限定访问的子目录。此方式避免了 `subPath` 方案中难以自动恢复的问题，且无需创建单独的 `StorageClass` 或 `PVC` 资源。

```yaml
# ... pod spec ...
      volumeMounts:
        - name: alluxio-fuse
          mountPath: /data
          mountPropagation: HostToContainer
  volumes:
    - name: alluxio-fuse
      csi:
        driver: alluxio
        volumeAttributes:
          alluxioClusterName: alluxio-cluster
          alluxioClusterNamespace: alx-ns
          mountPath: s3/path/to/files
# ...
```

多个子目录可以共享同一个 FUSE 实例，只需定义多个具有不同 `mountPath` 值的 volume 即可。

#### 使用 `subPath`（已弃用） <a href="#subpath-deprecated" id="subpath-deprecated"></a>

> **已弃用**：`subPath` 方式会破坏自动恢复机制，且难以自动恢复。请改用 ephemeral CSI volume。

您可以使用 `subPath` 字段将 Alluxio 命名空间中的特定子目录挂载到您的 pod 中。

```yaml
# ... pod spec ...
      volumeMounts:
        - mountPath: /data
          name: alluxio-pvc
          mountPropagation: HostToContainer
          subPath: 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>
   ```

   验证：

   ```shell
   kubectl -n <my-namespace> get pvc alluxio-fuse
   ```

   预期结果：PVC 存在。

### 自定义 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
```

**常用调整选项：**

| 挂载选项                 | FUSE 内核默认值 | Alluxio Operator 默认值 | 描述                                                                                 |
| -------------------- | ---------- | -------------------- | ---------------------------------------------------------------------------------- |
| `kernel_cache`       | 禁用         | 启用                   | 允许内核缓存文件数据，可显著提高读取性能。仅当底层文件不会在 Alluxio 之外被修改时使用。                                   |
| `auto_cache`         | 禁用         | 禁用                   | 类似于 `kernel_cache`，但当文件修改时间或大小发生变化时缓存自动失效。对于有可变数据的裸机部署，建议优先使用此选项而非 `kernel_cache`。 |
| `attr_timeout=N`     | 1.0        | 60                   | 内核缓存文件和目录属性（权限、大小）的秒数。增加此值可减少重复 `stat` 调用的元数据开销。                                   |
| `entry_timeout=N`    | 1.0        | 60                   | 缓存文件名查找的秒数。增加此值可加快频繁重复打开文件的工作负载的路径解析速度。                                            |
| `max_background=N`   | 12         | 128                  | FUSE 内核驱动程序允许排队的最大后台请求数。对于高 I/O 并发工作负载，建议增大此值。                                     |
| `max_idle_threads=N` | 10         | 128                  | FUSE 守护进程的最大空闲线程数。增加此值可防止在高并发负载下频繁创建/销毁线程带来的性能开销。                                  |
| `ro`                 | 禁用         | 禁用                   | 以只读方式挂载 FUSE 文件系统。用于不应通过挂载点修改的数据集。                                                 |

> 对于读取密集型 AI/ML 工作负载，请参阅[文件读取优化](/ee-ai-cn/performance/file-reading.md)，了解超出 FUSE 挂载选项的 Alluxio 级别调优。

> 在 bare-metal 客户端主机上驱动数百个并发线程时，把 `max_idle_threads` 和 `max_background` 从默认 128 提到 `256`。

### 自定义资源限制

您可以调整分配给 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"
```

**内存限制公式：**

```
memory limit ≥ -Xmx + -XX:MaxDirectMemorySize + 2–4 GiB（JVM 开销）
```

对于上述配置（`-Xmx22g`，`-XX:MaxDirectMemorySize=10g`）：最小限制为 22 + 10 + 2 = 34 GiB，示例中设置为 36 GiB。

> 如果省略了 `-XX:MaxDirectMemorySize`，JVM 会将其默认为与 `-Xmx` 相同的值，因此容器限制通常需要设置为 `-Xmx` 的 2.5 倍或更多。

**Profile 参考：**

| Profile         | `-Xmx` | `-XX:MaxDirectMemorySize` | 内存限制    | 适用场景                             |
| --------------- | ------ | ------------------------- | ------- | -------------------------------- |
| Evaluation      | 8g     | 4g                        | 16 GiB  | 开发/测试、小集群                        |
| Standard        | 22g    | 10g                       | 36 GiB  | 生产 Kubernetes Pod（多数工作负载的默认）     |
| High throughput | 48g    | 64g                       | 120 GiB | Bare-metal、NIC 带宽大、hot-read 工作负载 |

## 性能

### 判断卡在哪一层

吞吐低于预期时，看症状定位：

| 症状                                            | 可能的瓶颈                 | 怎么做                                                                                         |
| --------------------------------------------- | --------------------- | ------------------------------------------------------------------------------------------- |
| FUSE 容器 CPU 接近 `100% × core 数`（`top`、`nstat`） | FUSE 侧已饱和             | 加一个 FUSE client 节点，或调 mount options——见 [自定义 FUSE 挂载选项](#zi-ding-yi-fuse-gua-zai-xuan-xiang) |
| FUSE CPU 没满，但 latency 高                       | Worker 或 UFS 不够 warm  | 参见 [读取性能缓慢](#du-qu-xing-neng-huan-man) 里的逐步诊断（含缓存指标检查）                                      |
| 两者都不是——低 CPU、低 latency、低吞吐                    | Client 主机（CPU、NIC、内核） | 跑 `top`、`nstat`、对 worker 做 `iperf3`                                                         |

### 给 FUSE 容器做 Profiling

要从运行中的 FUSE 容器抓 CPU flamegraph，`docker run` 需要在 `SYS_ADMIN` 之外再加一个 `--cap-add SYS_PTRACE`。然后用 [async-profiler](https://github.com/async-profiler/async-profiler)（或任何 JVM profiler）附到容器内的 FUSE JVM 上，通过 `docker cp` 把生成的 HTML 拷出来分析。

## 故障排除

### FUSE 挂载显示 "Transport endpoint is not connected"

**症状**：访问挂载路径返回 `Transport endpoint is not connected`。

**原因**：FUSE 进程崩溃或被重新启动，且挂载未恢复。

**解决方案**：

{% tabs %}
{% tab title="Kubernetes" %}

1. 验证应用程序 pod 规范中设置了 `mountPropagation: HostToContainer`。没有它，自动恢复无法工作。
2. 检查 FUSE pod 是否正在运行：

   ```shell
   kubectl -n alx-ns get pod -l app=alluxio-fuse
   ```
3. 如果 FUSE pod 正在运行但挂载已过期，请删除并重新创建应用程序 pod：

   ```shell
   kubectl -n alx-ns delete pod fuse-test-0
   kubectl apply -f fuse-pod.yaml
   ```

{% endtab %}

{% tab title="Docker / Bare-Metal" %}
容器退出后，host 上的 FUSE 挂载会残留成 stale 状态。先 unmount 再重启容器：

```shell
sudo fusermount3 -u /mnt/alluxio/fuse   # 或：sudo umount -l /mnt/alluxio/fuse
sudo docker restart alluxio-fuse
```

先 `sudo docker logs alluxio-fuse` 看容器最初退出的原因。
{% endtab %}
{% endtabs %}

### FUSE 进程因 OOM 退出

**症状**：FUSE 反复崩溃——Kubernetes 上表现为 `CrashLoopBackOff` / `Exit Code 137` / `OOMKilled`；Docker 上容器停止，`docker logs` 里有 `OutOfMemoryError` 或 cgroup 的 SIGKILL。

**原因**：容器内存限制对于配置的 JVM 堆和直接内存来说太低。

**解决方案**：确保满足内存公式：

```
memory limit ≥ -Xmx + -XX:MaxDirectMemorySize + 2–4 GiB
```

查看崩溃前的 FUSE 日志：

{% tabs %}
{% tab title="Kubernetes" %}

```shell
kubectl -n alx-ns logs <fuse-pod-name> --previous | tail -50
```

{% endtab %}

{% tab title="Docker / Bare-Metal" %}

```shell
sudo docker logs --tail 50 alluxio-fuse
```

{% endtab %}
{% endtabs %}

查找 `OutOfMemoryError` 以确定是增加 `-Xmx` 还是 `-XX:MaxDirectMemorySize`。请参阅[自定义资源限制](#zi-ding-yi-zi-yuan-xian-zhi)。

### 应用程序 pod 卡在 ContainerCreating 状态

**症状**：应用程序 pod 在请求 FUSE PVC 后仍处于 `ContainerCreating` 状态。

**原因**：CSI 驱动未安装，或 FUSE PVC 不存在。

**解决方案**：

1. 检查 pod 上的事件：

   ```shell
   kubectl -n alx-ns describe pod <pod-name>
   ```
2. 如果事件提到 PVC 未找到，请验证 PVC 是否存在：

   ```shell
   kubectl -n alx-ns get pvc alluxio-cluster-fuse
   ```
3. 如果缺少 CSI nodeplugin，请验证 Operator 是否在启用 CSI 的情况下安装（默认启用）。如果需要，请在不使用 `alluxio-csi.enabled: false` 的情况下重新安装 Operator。

### FUSE 挂载上出现权限被拒绝

**症状**：访问挂载时出现 `ls: cannot access '/data': Permission denied`。

**原因**：FUSE 挂载未包含 `allow_other` 选项，该选项将访问限制为挂载它的用户。

**解决方案**：在 `alluxio-cluster.yaml` 的 FUSE 挂载选项中添加 `allow_other`：

```yaml
fuse:
  mountOptions:
    - allow_other
```

然后重新创建 Alluxio 集群以使更改生效。

有关细粒度的访问控制，请参阅[为 FUSE 启用授权](https://github.com/TachyonNexus/documentation/blob/AI-3.9-16.0.x/docs-ai/cn/administration/security/enabling-authorization-fuse.md)。

### 读取性能缓慢

**症状**：通过 FUSE 读取文件明显慢于预期。

**诊断**：

1. 检查数据是否已缓存在 Alluxio 中：

   ```shell
   kubectl -n alx-ns exec -i alluxio-cluster-coordinator-0 -- alluxio fs ls /s3/path/to/file
   ```

   如果文件显示 0% 缓存，首次读取将会较慢，因为它需要从底层存储获取数据。
2. 检查 FUSE 挂载选项——确保设置了 `kernel_cache` 或 `auto_cache` 以及增大的 `attr_timeout`/`entry_timeout` 值。请参阅[自定义 FUSE 挂载选项](#zi-ding-yi-fuse-gua-zai-xuan-xiang)。
3. 对于 AI/ML 训练工作负载，在开始训练前预加载数据：

   ```shell
   kubectl -n alx-ns exec -i alluxio-cluster-coordinator-0 -- alluxio job load --path /s3/path/to/dataset --submit
   ```
4. 如果症状是尾延迟（P99）飙高而非平均吞吐，还需要排查 worker 侧的 JVM GC 暂停和负载下的 UFS 回退读——检查 worker 日志中的 UFS 读取条目；若确认是 GC 暂停，调优 GC 参数。

有关全面的读取性能调优，请参阅[文件读取优化](/ee-ai-cn/performance/file-reading.md)。有关基准测试，请参阅[基准测试 POSIX 性能](/ee-ai-cn/benchmark/benchmarking-posix-performance.md)。

## 清理

{% tabs %}
{% tab title="Kubernetes" %}
删除 setup 过程中创建的测试 pod 和任何自定义 PVC：

```shell
# 删除测试 pod
kubectl -n alx-ns delete pod fuse-test-0

# 删除自定义 PVC（如果已创建）
kubectl -n alx-ns delete -f custom-sc-pvc.yaml

# 删除跨命名空间 PVC（如果已创建）
kubectl -n <my-namespace> delete -f csi-pvc.yaml
```

> `alluxio-cluster-fuse` PVC 由 Alluxio Operator 管理，在删除集群时会自动清理。请勿手动删除它。
> {% endtab %}

{% tab title="Docker / Bare-Metal" %}
停止并删除 FUSE 容器：

```shell
sudo docker stop alluxio-fuse
sudo docker rm alluxio-fuse
```

容器被删除后，`/mnt/alluxio/fuse` 的 FUSE 挂载随之失效；主机上的目录本身保留。
{% endtab %}
{% endtabs %}

## 参见

* [FUSE 非中断迁移](https://github.com/TachyonNexus/documentation/blob/AI-3.9-16.0.x/docs-ai/cn/data-access/fuse/fuse-non-disruptive-migration.md) —— 在不停止运行中的负载的情况下跨集群迁移 FUSE 挂载。
* [POSIX 基准测试](/ee-ai-cn/benchmark/benchmarking-posix-performance.md) —— 测量 FUSE 吞吐并对基线做调优。
* [模型加载优化](/ee-ai-cn/performance/model-loading.md) —— FUSE 挂载之上的 AI/ML 读取调优。
* [文件读取优化](/ee-ai-cn/performance/file-reading.md) —— 适用于 FUSE 负载的通用读取路径调优。
