> 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/performance/fuse-write-cache.md).

# FUSE 写入优化

{% hint style="warning" %}
此功能自 AI-3.8.15.1.6 起为实验性功能。
{% endhint %}

本指南介绍如何通过 FUSE POSIX 接口使用[写缓存](/ee-ai-cn/performance/s3-write-cache.md)后端，通过标准文件系统调用（`write()`、`open()`、`close()`）实现低延迟写入。在阅读本指南前，请确保写缓存已完成部署。

## 与 S3-API 写缓存的关系

写缓存后端（FoundationDB 元数据 + NVMe 数据 + 异步 UFS 持久化）由两种访问接口**共享**：

|                  | [S3-API 写入优化](/ee-ai-cn/performance/s3-write-cache.md) | FUSE 写入优化（本指南）                                                          |
| ---------------- | ------------------------------------------------------ | ----------------------------------------------------------------------- |
| **接口**           | S3 兼容 API（`PUT`、`GET`）                                 | POSIX 文件系统调用（`write`、`read`）                                            |
| **客户端**          | AWS CLI、boto3、s3fs、任意 S3 客户端                           | 任意 POSIX 应用、ML 框架、Shell 工具                                              |
| **写入策略**         | `WRITE_THROUGH`、`WRITE_BACK`、`TRANSIENT`               | 相同                                                                      |
| **FoundationDB** | 必需                                                     | 必需（同一 FDB 集群）                                                           |
| **额外限制**         | 无（仅 S3 语义限制）                                           | 参见[写缓存模式下的 POSIX 兼容性](#xie-huan-cun-mo-shi-xia-de-posix-jian-rong-xing) |

## 开始之前

* [ ] **写缓存已部署** — FDB 须处于运行状态，且 `alluxio.write.cache.enabled: "true"`。验证：

  ```shell
  kubectl exec -n <NAMESPACE> <CLUSTER_NAME>-coordinator-0 -- \
    alluxio conf get alluxio.write.cache.enabled
  ```

  预期输出：`true`。若非如此，请先完成 [S3-API 写入优化](/ee-ai-cn/performance/s3-write-cache.md)的部署。
* [ ] **FDB Pod 运行正常**：

  ```shell
  kubectl get pods -n <NAMESPACE> | grep fdb
  ```

  预期输出：FDB controller、log 和 storage Pod 均为 `Running`。
* [ ] **FUSE PVC 已存在**：

  ```shell
  kubectl get pvc -n <NAMESPACE> <CLUSTER_NAME>-fuse
  ```

  预期输出：PVC 存在（Pod 挂载前状态为 `Pending` 属正常现象）。

## 推荐集群配置

启用 FUSE 写缓存时，未持久化的写入数据会占用更大比例的 NVMe 容量。建议将 `alluxio-cluster.yaml` 中的 Pinned 空间比例从默认的 `0.3` 提高至 `0.5`：

```yaml
spec:
  properties:
    alluxio.write.cache.enabled: "true"
    # 从默认 0.3 提高至 0.5，以应对 FUSE 写入密集型工作负载
    alluxio.worker.page.store.pinned.file.capacity.limit.ratio: "0.5"
  fdb:
    enabled: true
```

应用配置：

```shell
# Idempotent
kubectl apply -f alluxio-cluster.yaml
```

> 请合理规划 Worker 的 NVMe 容量：在比例为 `0.5`、总缓存为 `1 TiB` 的情况下，最多 500 GiB 的空间可能被未持久化的写入数据占用。若写入吞吐持续超过持久化吞吐，空间将耗尽，Alluxio 会返回 `out-of-space` 错误。参见[缓存空间管理](/ee-ai-cn/performance/s3-write-cache.md#huan-cun-kong-jian-guan-li)。

## 部署 FUSE 客户端 Pod

Operator 在集群安装期间会创建名为 `<CLUSTER_NAME>-fuse` 的 PVC。使用 `mountPropagation: HostToContainer` 挂载，以便 FUSE 进程重启时自动恢复。

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: fuse-test-0
  namespace: <NAMESPACE>
spec:
  containers:
    - image: ubuntu:22.04
      name: fuse-test
      command: ["sleep", "infinity"]
      volumeMounts:
        - mountPath: /data
          name: alluxio-pvc
          mountPropagation: HostToContainer
  volumes:
    - name: alluxio-pvc
      persistentVolumeClaim:
        claimName: <CLUSTER_NAME>-fuse
```

```shell
# Idempotent
kubectl apply -f fuse-pod.yaml
kubectl -n <NAMESPACE> get pod fuse-test-0
```

预期输出：`STATUS = Running`，`READY = 1/1`。

更多 FUSE 部署选项（DaemonSet、Docker / 裸机），参见 [POSIX API](/ee-ai-cn/data-access/fuse-based-posix-api.md)。

## 配置写回路径

写入策略按路径配置，与 [S3-API 写入优化](/ee-ai-cn/performance/s3-write-cache.md#lu-jing-ji-pei-zhi) 中的路径级配置相同。路径指 Alluxio 命名空间（如 `/s3/checkpoints`），而非 FUSE 挂载路径（`/data/s3/checkpoints`）。

非交互式配置（适用于脚本）：

```shell
kubectl exec -i -n <NAMESPACE> <CLUSTER_NAME>-coordinator-0 -- \
  bash -c 'EDITOR="cp /dev/stdin" alluxio pathconfig edit' << 'EOF'
{
  "apiVersion": "v1.0",
  "defaultRule": {
    "description": "Global default",
    "policyMode": "WRITE_THROUGH"
  },
  "pathRules": [
    {
      "alluxioPath": "/s3/checkpoints/**",
      "description": "Low-latency checkpoint writes",
      "policyMode": "WRITE_BACK",
      "properties": { "writeReplicas": 1 }
    }
  ]
}
EOF
```

预期输出：`Update successful!`

验证指定路径是否解析为预期策略：

```shell
kubectl exec -n <NAMESPACE> <CLUSTER_NAME>-coordinator-0 -- \
  alluxio pathconfig test --path /s3/checkpoints/epoch-1/model.pt
```

预期输出：包含 `"policyMode": "WRITE_BACK"`。

## 验证 FUSE 写回

通过 FUSE 写入文件，并确认其最终持久化至 UFS：

```shell
# 通过 FUSE 写入
kubectl exec -i -n <NAMESPACE> fuse-test-0 -- \
  bash -c 'echo "hello from fuse write cache" > /data/s3/checkpoints/test.txt'

# 确认在 Alluxio 命名空间中可见
kubectl exec -i -n <NAMESPACE> <CLUSTER_NAME>-coordinator-0 -- \
  alluxio fs ls /s3/checkpoints/test.txt
```

等待异步持久化完成（最长 `alluxio.write.cache.async.file.check.period`，默认 `10min`）：

```shell
# 轮询至 PERSISTED（8 次 × 15s = 2 分钟）
for i in $(seq 1 8); do
  echo "--- Check $i/8 ---"
  NOT_PERSISTED=$(kubectl exec -i -n <NAMESPACE> <CLUSTER_NAME>-coordinator-0 -- \
    alluxio fs ls /s3/checkpoints/ 2>&1 | grep -c "NOT_PERSISTED" || true)
  if [ "${NOT_PERSISTED}" = "0" ]; then
    echo "All files PERSISTED."
    break
  fi
  echo "${NOT_PERSISTED} file(s) still pending. Waiting 15s..."
  sleep 15
done
```

预期输出：2 分钟内出现 `All files PERSISTED.`

***

## 写缓存模式下的 POSIX 兼容性

{% hint style="warning" %}
FUSE 写缓存与 S3-API 写缓存共用同一后端。因此，写缓存 FUSE 挂载在标准 FUSE 语义之上还有额外的 POSIX 限制，且对**所有写缓存策略**（`WRITE_THROUGH`、`WRITE_BACK`、`TRANSIENT`）均生效。在将工作负载迁移至写缓存 FUSE 挂载前，请务必了解以下限制。
{% endhint %}

下表汇总了任意写缓存策略（`WRITE_THROUGH`、`WRITE_BACK`、`TRANSIENT`）生效时各 POSIX 操作的支持情况。符号说明：✅ 支持 | ⚠️ 部分支持 | ❌ 不支持。

| 类别         | 操作                                    | 支持                  | 说明                             |
| ---------- | ------------------------------------- | ------------------- | ------------------------------ |
| **读取**     | `read` / `readv` / `pread` / `preadv` | ✅                   |                                |
| **写入**     | 顺序写入（新文件）                             | ✅                   | 核心使用场景                         |
|            | 覆盖写入现有文件                              | ✅                   | 通过 truncate + recreate         |
|            | 追加写入现有文件                              | ⚠️                  | 架构层面支持（MPU）                    |
|            | `fsync` / `fdatasync`                 | ✅                   | 触发异步持久化                        |
|            | `truncate`                            | ✅                   | delete + recreate              |
|            | 并发写入（同一文件）                            | ❌                   | S3 对象模型限制                      |
| **Rename** | 文件 rename                             | ✅ Atomic            | 适用于所有 S3 存储桶类型；零拷贝（仅元数据）       |
|            | 目录 rename                             | ✅ Atomic            | AI/ML checkpoint 模式的关键能力       |
| **删除**     | `unlink`                              | ✅ Default enabled   |                                |
|            | `rm -rf`                              | ✅                   | 页面在所有 Worker 上回收（15.1.3+）      |
| **目录**     | `readdir`                             | ✅ Dual-path merge   |                                |
|            | `mkdir`                               | ✅ Persisted         |                                |
|            | `rmdir`                               | ✅ Empty directories |                                |
| **元数据**    | `stat` / `getattr`                    | ✅                   |                                |
|            | 文件大小                                  | ✅                   |                                |
|            | `mtime`                               | ✅                   | 读写（`utimens`）                  |
|            | `atime` / `ctime`                     | = `mtime`           |                                |
|            | `chmod` / `chown`                     | ❌                   | S3 无 POSIX 权限模型                |
|            | `xattr`                               | ⚠️ Limited          |                                |
| **链接**     | 符号链接（`symlink` / `readlink`）          | ✅                   | Magic header 编码，目标路径最长 4096 字节 |
|            | 硬链接（`link()`）                         | ❌ `EOPNOTSUPP`      | S3 无 inode 概念                  |
| **锁**      | `flock`（建议锁）                          | ✅ 单节点               | 仅 libfuse；不支持跨节点锁定             |
|            | `fcntl` / `lockf`                     | ❌                   |                                |

### rename() 支持（15.1.6+）

自 AI-3.8.15.1.6 起，`rename()` 已完全支持——文件和目录均可重命名，操作原子，采用零拷贝纯元数据语义（无需 S3 `CopyObject + DeleteObject`）。适用于任意 S3 存储桶类型。

在 **AI-3.8.15.1.6 之前**的版本中，所有 `rename()` 操作均失败并返回 `EIO`，受影响的操作包括：

* Shell 的 `mv` 和 `rename`
* Python 的 `os.rename()`、`pathlib.Path.rename()`
* 写后重命名模式（先写入 `.tmp`，再重命名）

**Silly rename 拦截器（需手动开启）：** 当应用对已打开的文件执行 `rm` 时，Linux 内部会向 `.fuse_hidden*` 发起 `rename()`。启用拦截器可透明处理这一情况，无需触发 S3 的 `CopyObject + DeleteObject`：

```yaml
spec:
  properties:
    # CLIENT 级别：在 FUSE 客户端属性中设置
    alluxio.fuse.silly.rename.interceptor.enabled: "true"
```

默认值为 `false`。

### 覆盖写入（15.1.6+）

自 AI-3.8.15.1.6 起，支持通过 `truncate` + recreate 语义覆盖写入现有文件：Alluxio 删除现有文件并在同一路径创建新文件。不支持随机原地覆盖（`pwrite`）。

在 15.1.6 之前，文件关闭后不可再写——对现有文件重新打开以写入会返回 `EACCES`。若使用早期版本：

| 操作                                                    | errno    |
| ----------------------------------------------------- | -------- |
| `open(path, O_CREAT \| O_EXCL)` — 文件已存在               | `EEXIST` |
| `open(path, O_WRONLY)` 或 `open(path, O_RDWR)` — 文件已存在 | `EACCES` |

**影响：** 原地更新文件的应用（数据库、日志轮转、配置重写器）最适合使用 AI-3.8.15.1.6+。即使支持覆盖写入，写缓存 FUSE 挂载仍最适合一次性写入的工作负载——模型检查点、训练数据集、ETL 阶段输出。

### 不支持硬链接

`link()` 返回 `EOPNOTSUPP`。依赖硬链接的工具（`rsync --hard-links`、部分包管理器）无法通过该挂载正常工作。

### 删除时的缓存页回收（15.1.3+ 行为）

通过 FUSE `rm` 或 `rm -rf` 删除文件时，缓存页将在持有该文件副本的**所有** Worker 上回收，而不仅限于哈希环所有者 Worker。15.1.3 之前的版本中，仅所有者 Worker 回收缓存页；其他 Worker 上的孤儿页将保留至下一轮驱逐周期。

### 与 AWS Mountpoint for S3 的对比

Alluxio WriteCache（WRITE\_BACK 模式）在 POSIX 接口支持方面是 AWS Mountpoint for Amazon S3 的**严格超集**——Mountpoint 支持的每一个 POSIX 操作，Alluxio 都以相同或更高水平支持，无一例外。

Alluxio 额外提供以下 Mountpoint 不支持的 POSIX 能力：

* Atomic `rename`（文件和目录，适用于所有 S3 存储桶类型）
* `symlink` / `readlink`（符号链接）
* Persistent `mkdir`（目录在重启后保留）
* `xattr`（扩展属性）

符号说明：✅ 支持 | ⚠️ 有限 / 条件支持 | ❌ 不支持。

| 类别      | 操作                                     | Alluxio WriteCache（WRITE\_BACK 模式） | AWS Mountpoint for S3               | 说明                                         |
| ------- | -------------------------------------- | ---------------------------------- | ----------------------------------- | ------------------------------------------ |
| **读取**  | `read` / `readv` / `pread` / `preadv`  | ✅                                  | ✅                                   | 两者均完整支持所有读取变体                              |
| **写入**  | Sequential write (new file)            | ✅                                  | ✅                                   | 两者的核心使用场景                                  |
|         | Random write (`pwrite`)                | ❌                                  | ❌                                   | 两者均不支持主要写入模式下的随机写入                         |
|         | Overwrite existing file                | ✅ truncate + recreate              | ⚠️ `--allow-overwrite` + `O_TRUNC`  | —                                          |
|         | Append existing file                   | ⚠️ Architecture supports (MPU)     | ⚠️ S3 Express One Zone only         | 均有条件支持                                     |
|         | Concurrent writers (same file)         | ❌                                  | ❌                                   | S3 对象模型限制                                  |
|         | `fsync` / `fdatasync`                  | ✅ Triggers upload                  | ⚠️ Commits to S3; no further writes | —                                          |
|         | `truncate`                             | ✅ delete + recreate                | ⚠️ Requires `--allow-overwrite`     | —                                          |
| **重命名** | Single file rename                     | ✅ Atomic                           | ⚠️ S3 Express One Zone only         | **Alluxio 适用于任意 S3 存储桶**                   |
|         | File rename with overwrite             | ✅                                  | ⚠️ S3 XOZ + `--allow-overwrite`     | —                                          |
|         | Directory rename                       | ✅ Atomic                           | ❌                                   | **Alluxio 优势**——AI/ML checkpoint 模式的关键能力   |
|         | Zero-copy rename                       | ✅ Metadata-only, no data copy      | ❌ S3 rename = copy + delete         | 关键架构优势                                     |
| **删除**  | `unlink`                               | ✅ Default enabled                  | ⚠️ Requires `--allow-delete`        | —                                          |
|         | Recursive delete (`rm -rf`)            | ✅                                  | ✅ File-by-file                      | —                                          |
| **目录**  | `readdir`                              | ✅ Dual-path merge                  | ✅                                   | —                                          |
|         | `mkdir`                                | ✅ Persisted                        | ⚠️ Local only, not persisted to S3  | **Alluxio**：真实目录语义                         |
|         | `rmdir`                                | ✅ Empty directories                | ⚠️ Only `mkdir`-created dirs        | —                                          |
| **元数据** | `stat` / `getattr`                     | ✅                                  | ✅ Limited                           | —                                          |
|         | File size                              | ✅                                  | ✅                                   | —                                          |
|         | `mtime`                                | ✅ Read/write (`utimens`)           | ✅ Read-only                         | Alluxio 支持写入                               |
|         | `atime` / `ctime`                      | = `mtime`                          | = `mtime`                           | —                                          |
|         | `chmod` / `chown`                      | ❌                                  | ❌                                   | S3 无 POSIX 权限模型                            |
|         | `xattr`                                | ⚠️ Limited                         | ❌                                   | —                                          |
| **链接**  | Symbolic link (`symlink` / `readlink`) | ✅                                  | ❌                                   | **Alluxio**：magic header 编码，目标路径最长 4096 字节 |
|         | Hard link                              | ❌ `EOPNOTSUPP`                     | ❌                                   | S3 无 inode 概念                              |
| **锁**   | `flock` (advisory)                     | ✅ Single-node (libfuse)            | ✅ Single-node (libfuse)             | 两者均不支持跨节点锁定                                |
|         | `fcntl` locking                        | ❌                                  | ❌                                   | —                                          |
|         | `lockf`                                | ❌                                  | ❌                                   | —                                          |
| **其他**  | `mmap` shared write                    | ❌                                  | ❌                                   | 需要页缓存语义                                    |
|         | Sparse files (file holes)              | ❌                                  | ❌                                   | 与顺序写入模型冲突                                  |

**一致性模型**

| 场景         | Alluxio WriteCache（WRITE\_BACK 模式） | AWS Mountpoint for S3 |
| ---------- | ---------------------------------- | --------------------- |
| 写后读（本地）    | 关闭后**立即可从写缓冲区读取**                  | 关闭后可读（须等待 S3 上传完成）    |
| S3 可见性     | 异步持久化（关闭后数秒至数分钟）                   | 关闭后立即在 S3 可见          |
| 多实例一致性     | **分布式元数据**（强一致性）                   | 无跨实例协调                |
| `stat` 新鲜度 | **强一致性**                           | 并发修改时可能滞后约 1 秒        |
| 目录列表一致性    | **强一致性**                           | 强一致性（S3 ListObjects）  |
| 关闭时的持久性    | 数据在 Worker NVMe 缓存中（多副本）；异步写入 S3   | 数据在 S3（同步上传）          |
| 节点故障       | **多副本保护** — 触发提前 S3 持久化            | 未关闭的写入数据将丢失           |

Alluxio 提供更快的本地读后写（无需 S3 往返）以及通过其分布式元数据层实现的强跨实例元数据一致性。Mountpoint 提供更强的关闭时 S3 持久性（同步上传）。Alluxio 通过多副本写入弥补这一差距——若某个 Worker 故障，其他 Worker 上的副本将保留数据并触发提前 S3 持久化。

***

## 监控异步持久化

两条 CLI 命令（15.1.3+ 可用）可用于检查持久化操作的实时状态，无需等待 `alluxio fs ls`：

```shell
# 列出指定 Worker 上所有待处理或进行中的文件
kubectl exec -i -n <NAMESPACE> <CLUSTER_NAME>-worker-0 -- \
  alluxio async-persist list

# 按 Worker ID 过滤
kubectl exec -i -n <NAMESPACE> <CLUSTER_NAME>-worker-0 -- \
  alluxio async-persist list --worker <WORKER_ID>

# 查询指定路径的持久化状态和重试次数
kubectl exec -i -n <NAMESPACE> <CLUSTER_NAME>-coordinator-0 -- \
  alluxio async-persist stat --path /s3/checkpoints/epoch-1/model.pt
```

当 `alluxio fs ls` 显示文件长期处于 `NOT_PERSISTED` 状态时，可使用 `async-persist stat` 判断问题出在队列还是上传阶段。

## 关键配置

| 配置项                                                          | 默认值     | 描述                                                      |
| ------------------------------------------------------------ | ------- | ------------------------------------------------------- |
| `alluxio.write.cache.enabled`                                | `false` | 启用写缓存（与 S3 API 共享）。                                     |
| `alluxio.worker.page.store.pinned.file.capacity.limit.ratio` | `0.3`   | NVMe 容量中用于未持久化写入数据的最大比例。FUSE 写入密集型工作负载建议提高至 `0.5`。      |
| `alluxio.write.cache.async.file.check.period`                | `10min` | 孤儿检测扫描周期。设置过短会增加 FDB 负载。                                |
| `alluxio.write.cache.async.check.orphan.timeout`             | `1h`    | 超过此时间仍未提交的写入将被视为已放弃并清理。                                 |
| `alluxio.fuse.silly.rename.interceptor.enabled`              | `false` | CLIENT 级别。拦截 `.fuse_hidden*` 重命名/删除操作，透明处理已打开文件的 `rm`。  |
| `alluxio.worker.mark.writing.files.duration`                 | `10min` | 若文件处于写入状态但在该时长内未收到新数据，Worker 将其视为悬空写入并纳入清理。每次写入都会重置计时器。 |

## 故障排查

### 目录删除返回 DEADLINE\_EXCEEDED

对 `WRITE_BACK` 路径执行 `alluxio fs rm -R` 或 `rm -rf` 时可能出现：

```
io.grpc.StatusRuntimeException: DEADLINE_EXCEEDED: CallOptions deadline exceeded after ~5s
```

{% hint style="danger" %}
尽管出现该错误，底层文件**可能已在超时前从 UFS 删除**。请勿假设数据仍然存在。
{% endhint %}

**恢复步骤：**

1. 直接验证 UFS 状态：

   ```shell
   aws s3 ls s3://<BUCKET>/<path>/ --recursive | head -20
   ```
2. 若 S3 中文件已不存在，则数据层删除已成功。重新执行 `alluxio fs rm -R` 将确认并返回 `Path does not exist`。
3. Pagestore 磁盘空间不会立即收缩 — 孤儿页将在下一轮驱逐周期中被回收。

***

### 文件长期处于 NOT\_PERSISTED

```shell
kubectl exec -i -n <NAMESPACE> <CLUSTER_NAME>-coordinator-0 -- \
  alluxio fs ls /s3/checkpoints/
```

若文件在 `alluxio.write.cache.async.file.check.period` 后仍处于 `NOT_PERSISTED` 状态：

1. 检查异步持久化队列：

   ```shell
   kubectl exec -i -n <NAMESPACE> <CLUSTER_NAME>-worker-0 -- \
     alluxio async-persist list
   ```
2. 检查指定文件状态：

   ```shell
   kubectl exec -i -n <NAMESPACE> <CLUSTER_NAME>-coordinator-0 -- \
     alluxio async-persist stat --path /s3/checkpoints/<filename>
   ```
3. 检查 Worker 日志中的上传错误：

   ```shell
   kubectl logs -n <NAMESPACE> <CLUSTER_NAME>-worker-0 --tail=100 | \
     grep -i "persist\|upload\|flush"
   ```
4. 若 UFS 不可达，重试将进入指数退避（最长 `alluxio.worker.write.cache.async.persist.retry.max.interval`，默认 `1h`）。请从 Worker Pod 验证 UFS 连通性。

***

### rename() 意外返回 EIO

在任意写缓存策略生效时，此为预期行为（参见 [rename() 支持（15.1.6+）](#rename-zhi-chi-15-1-6)）。若应用依赖 rename：

* 将受影响路径切换为 `NO_CACHE` 策略，完全绕过该路径的写缓存。
* 若 rename 由已打开文件的 `rm` 触发，启用 `alluxio.fuse.silly.rename.interceptor.enabled: "true"`。

***

### FUSE Pod OOM 或挂载断开

这些问题与写缓存无关。参见 [FUSE 故障排除](/ee-ai-cn/data-access/fuse-based-posix-api.md#gu-zhang-pai-chu)。

## 参考资源

* [S3-API 写入优化](/ee-ai-cn/performance/s3-write-cache.md) — 通过 S3 API 使用写缓存；部署写缓存请先完成此步骤
* [POSIX API](/ee-ai-cn/data-access/fuse-based-posix-api.md) — FUSE 部署详情、挂载选项、读缓存模式
* [S3 API 基准测试](/ee-ai-cn/benchmark/s3-api.md) — S3 侧写入吞吐基线
* [POSIX 性能基准测试](/ee-ai-cn/benchmark/benchmarking-posix-performance.md) — FUSE 侧吞吐基线
