# 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 负载的通用读取路径调优。


---

# 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/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.
