> 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/s3-api.md).

# S3 API

Alluxio 提供 S3 兼容 REST API，允许基于 Amazon S3 构建的应用无需修改代码即可读写数据。本页介绍端点配置、身份验证、负载均衡和客户端兼容性。

> **需要低延迟写入？** 如果您的工作负载要求毫秒级 `PUT` 延迟或异步持久化，请参见 [S3-API 写入优化](/ee-ai-cn/performance/s3-write-cache.md)。

## 前提条件

开始前请先完成 [Kubernetes 安装指南](/ee-ai-cn/start/installing-on-kubernetes.md)中的第 5 步（挂载存储）。S3 API 需要：

* 正在运行的 Alluxio 集群（`CLUSTERPHASE` = `Ready`）
* 至少一个 UFS 挂载点——挂载点将作为 API 暴露的 S3 存储桶

## 快速入门

本节通过三个步骤使用默认配置（代理模式，模式 B）启动一个可用的 S3 端点。绝大多数客户端——包括 AWS CLI、boto3 和 PyTorch S3 Connector——均可开箱即用。

### 第一步：启用 S3 API

将以下内容添加到 `alluxio-cluster.yaml` 的 `spec.properties` 并应用：

```yaml
spec:
  properties:
    alluxio.worker.s3.api.enabled: "true"
```

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

S3 API 在每个 worker 上通过以下端口暴露：`29998`（HTTP）和 `29996`（HTTPS，需要 [TLS](/ee-ai-cn/administration/security/securing-alluxio-with-tls.md) 配置）。

### 第二步：暴露端点

**使用负载均衡器（生产环境推荐）**

在 `alluxio-cluster.yaml` 中添加 worker service：

```yaml
spec:
  worker:
    service:
      type: LoadBalancer
```

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

等待外部 IP 分配：

```shell
kubectl -n alx-ns get svc alluxio-cluster-worker --watch
```

**✅ 成功标志：** `EXTERNAL-IP` 已填充。将该地址用作下方的 `<ENDPOINT>`。

**无负载均衡器（评估/单节点）**

使用 port-forward 直接访问 worker：

```shell
kubectl -n alx-ns port-forward pod/alluxio-cluster-worker-0 29998:29998 &
```

将 `http://localhost:29998` 用作 `<ENDPOINT>`。

### 第三步：使用 AWS CLI 验证

配置路径样式请求（必须——不支持虚拟托管样式）：

```shell
aws configure set default.s3.addressing_style path
```

使用 SIMPLE 认证（默认），任意非空凭证均可接受：

```shell
# 列出所有存储桶（Alluxio 挂载点）
AWS_ACCESS_KEY_ID=testuser AWS_SECRET_ACCESS_KEY=testpassword \
  aws s3 ls --endpoint-url http://<ENDPOINT>

# 上传测试文件
AWS_ACCESS_KEY_ID=testuser AWS_SECRET_ACCESS_KEY=testpassword \
  aws s3 cp test.txt s3://<bucket>/test.txt --endpoint-url http://<ENDPOINT>

# 下载回来
AWS_ACCESS_KEY_ID=testuser AWS_SECRET_ACCESS_KEY=testpassword \
  aws s3 cp s3://<bucket>/test.txt downloaded.txt --endpoint-url http://<ENDPOINT>
```

**快速 boto3 示例：**

```python
import boto3

s3 = boto3.client(
    "s3",
    aws_access_key_id="placeholder",
    aws_secret_access_key="placeholder",
    region_name="us-east-1",
    endpoint_url="http://<ENDPOINT>",
)

for bucket in s3.list_buckets().get("Buckets", []):
    print(bucket["Name"])
```

> **想要更高吞吐量？** 默认代理模式跨 worker 读取需经过两次网络传输，相比重定向模式吞吐量约减半。如果您的客户端能正确跟随指向非 AWS endpoint 的 HTTP 307 重定向，请参见[模式 A](#模式-a负载均衡--重定向)，可实现近似线性扩展。

***

## 部署模式

### 工作原理

每个 Alluxio worker 在端口 `29998` 上暴露 S3 端点，并通过[一致性哈希](/ee-ai-cn/how-alluxio-works.md#yi-zhi-xing-ha-xi-huan)负责命名空间的一个分片。当请求落在非数据所有者的 worker 上时，该 worker 必须将请求路由到数据所有者。有两种策略：

{% hint style="info" %}
**背景：HTTP 307 在此意味着什么。** HTTP 307 是一个重定向状态码——服务器返回一个新 URL 而不是数据。客户端随即直接向该 URL 发起新的连接。关键在于：原始 worker 上**不传输任何数据负载**：重定向响应只是一条很小的 HTTP 消息，完整的读取操作在 worker 与客户端之间直接进行，无需代理中转。唯一的代价是多了一次重定向本身的往返延迟。
{% endhint %}

* **代理模式**（`alluxio.worker.s3.redirect.enabled=false`）：接收请求的 worker 从数据所有者获取数据并流式返回给客户端。所有客户端均可正常使用。代价：跨 worker 读取需两次网络传输（约为重定向模式的 50% 吞吐量）。
* **重定向模式**（`alluxio.worker.s3.redirect.enabled=true`，默认值）：接收请求的 worker 发出 HTTP 307，引导客户端直连数据所有者——零代理开销，吞吐量随 worker 线性扩展。**约束**：AWS SDK 不跟随指向非 AWS endpoint 的 307 重定向。基于 AWS SDK 的客户端（AWS CLI、boto3、PyTorch S3 Connector）无法使用此模式。
* **节点本地代理**（S3 Proxy DaemonSet）：每个 worker 节点上运行一个 OpenResty sidecar，通过一致性哈希环直接解析数据所有者并单跳转发——无跨 worker 传输。兼具代理模式的客户端兼容性和接近重定向模式的吞吐量。

### 选择部署模式

```
您的客户端是否跟随指向非 AWS endpoint 的 HTTP 307 重定向？
├── 是 (COSBench、minio-py)
│   └── 模式 A：负载均衡 + 重定向  (alluxio.worker.s3.redirect.enabled=true)
│       最大吞吐量——客户端直连数据所有者 worker
└── 否 (AWS SDK / CLI、boto3、PyTorch S3 Connector、Warp)
    ├── 模式 B：负载均衡 + 代理模式  (alluxio.worker.s3.redirect.enabled=false)
    │   部署简单，无需额外组件——相比模式 A 吞吐量约为 50%
    └── 模式 C：节点本地 S3 Proxy DaemonSet
        接近模式 A 的吞吐量，兼容 AWS SDK——每个请求直接
        路由到数据所有者 worker，单跳完成
```

### 模式 A：负载均衡 + 重定向

适用于：COSBench、minio-py 以及任何能正确跟随指向非 AWS endpoint 的 HTTP 307 重定向的客户端。

```
┌─────────────────────────────────┐
│         S3 Clients              │
│      (minio-py, COSBench)       │
└──────────┬──────────────────────┘
           │  S3 API (HTTP)
           ▼
┌─────────────────────────────────┐
│   Load Balancer (NLB/Nginx)     │
└──────────┬──────────────────────┘
           │  分发到各 worker
           ▼
┌─────────────────────────────────────────────────┐
│  Alluxio Workers（端口 29998）                   │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐       │
│  │ Worker 1 │  │ Worker 2 │  │ Worker N │ ...   │
│  │ NVMe SSD │  │ NVMe SSD │  │ NVMe SSD │       │
│  └──────────┘  └──────────┘  └──────────┘       │
└──────────┬──────────────────────────────────────┘
           │  缓存未命中 → 从 UFS 获取
           ▼
┌─────────────────────────────────────┐
│   Underlying Storage (S3/HDFS/...)  │
└─────────────────────────────────────┘
```

工作原理：负载均衡器将请求分发到各 worker。设置 `alluxio.worker.s3.redirect.enabled=true` 后，接收请求的 worker 通过一致性哈希检查数据归属，仅在必要时发出 307——如果请求恰好落在数据所有者上，则不触发重定向。客户端直连数据所有者——**零拷贝，无代理开销**，吞吐量随 worker 线性扩展。吞吐量基线数据请参见 [S3 API 性能基准测试](/ee-ai-cn/benchmark/s3-api.md)。

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

```yaml
apiVersion: k8s-operator.alluxio.com/v1
kind: AlluxioCluster
spec:
  properties:
    alluxio.worker.s3.api.enabled: "true"
    alluxio.worker.s3.redirect.enabled: "true"
  worker:
    service:
      type: LoadBalancer
      annotations:
        service.beta.kubernetes.io/aws-load-balancer-type: nlb
        service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
```

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

等待 NLB 完成配置（AWS 上通常需要 1–2 分钟）：

```shell
kubectl -n alx-ns get svc alluxio-cluster-worker --watch
```

**✅ 成功标志：** `EXTERNAL-IP` 已填充。将该 hostname 用作 S3 端点。
{% endtab %}

{% tab title="Docker / 裸机" %}
使用 Nginx、HAProxy 或 DNS 轮询将请求分发到各 worker 节点的 `29998` 端口。
{% endtab %}
{% endtabs %}

### 模式 B：负载均衡 + 代理模式

适用于：AWS SDK (AWS CLI)、boto3、PyTorch S3 Connector (AWS CRT)、MinIO Warp——不跟随指向非 AWS endpoint 的 HTTP 307 重定向的客户端。

需显式设置 `alluxio.worker.s3.redirect.enabled=false`——默认为重定向模式，代理模式需主动开启。设置后所有客户端无需修改代码即可正常工作。

使用与模式 A 相同的负载均衡器配置，但设置 `alluxio.worker.s3.redirect.enabled=false`。负载均衡器将请求分发到各 worker，跨 worker 读取在集群内部代理转发。

**权衡**：跨 worker 读取时，数据在集群网络上传输两次（数据所有者 → 代理 worker → 客户端），集群整体吞吐量约为模式 A 的一半。

将应用的 S3 端点指向负载均衡器地址：

```
http://<LOAD_BALANCER_ADDRESS>:29998
```

{% hint style="info" %}
**单 worker 部署**：307 重定向仅在接收请求的 worker 不是数据所有者时触发。单 worker 时重定向不会触发，所有客户端无需任何配置即可正常工作。
{% endhint %}

### 模式 C：节点本地 S3 Proxy

适用于：需要接近模式 A 吞吐量的 AWS SDK 客户端（boto3、AWS CLI、PyTorch S3 Connector）。与模式 B 不同——模式 B 中任意 worker 都可能接收请求，再跨集群代理到数据所有者——S3 Proxy DaemonSet 在每个 worker 节点上运行，在转发前通过一致性哈希环直接解析正确的数据所有者。客户端连接到本地节点的 `http://127.0.0.1:8080`，无需额外的跨 worker 跳转。

```
┌───────────────────────────────────────────────┐
│  Worker 节点                                   │
│  ┌─────────────────┐   ┌───────────────────┐  │
│  │  应用 Pod        │ → │  S3 Proxy :8080   │  │
│  │ boto3 / AWS CLI │   │  哈希环查找        │  │
│  └─────────────────┘   └────────┬──────────┘  │
└───────────────────────────────┼───────────────┘
                                │ 直连数据所有者 worker
                                ▼
┌─────────────────────────────────────────────────┐
│  Alluxio Workers（端口 29998）                   │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐       │
│  │ Worker 0 │  │ Worker 1 │  │ Worker N │       │
│  └──────────┘  └──────────┘  └──────────┘       │
└─────────────────────────────────────────────────┘
```

**前提条件**：`alluxio.worker.s3.api.enabled: "true"`，且 worker 节点上端口 `8080` 未被占用。

先查找 Alluxio 命名空间中的 etcd Service 名称：

```shell
kubectl get svc -n <NAMESPACE> | grep etcd
# 例如：alluxio-cluster-etcd   ClusterIP   10.x.x.x   2379/TCP
```

将以下内容保存为 `alluxio-s3-proxy.yaml` 并应用：

```yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: alluxio-s3-proxy
  namespace: <NAMESPACE>
spec:
  selector:
    matchLabels:
      app: alluxio-s3-proxy
  template:
    metadata:
      labels:
        app: alluxio-s3-proxy
    spec:
      hostNetwork: true
      dnsPolicy: ClusterFirstWithHostNet
      nodeSelector:
        alluxio.io/worker: "enabled"
      tolerations:
        - operator: Exists
      containers:
        - name: alluxio-s3-proxy
          image: public.ecr.aws/m3q8r0k4/dodia/alluxio-s3-proxy:v1.2
          ports:
            - containerPort: 8080
              hostPort: 8080
          env:
            - name: ALLUXIO_ETCD_URLS
              value: "http://<CLUSTER_NAME>-etcd:2379"
            - name: ALLUXIO_CLUSTER_NAME
              value: "<NAMESPACE>-<CLUSTER_NAME>"
            - name: ALLUXIO_WORKER_S3_PORT
              value: "29998"
          readinessProbe:
            httpGet:
              path: /health
              port: 8080
            initialDelaySeconds: 3
            periodSeconds: 10
          resources:
            requests:
              cpu: "2"
              memory: "1Gi"
            limits:
              cpu: "16"
              memory: "4Gi"
```

```shell
kubectl apply -f alluxio-s3-proxy.yaml
```

| 变量                       | 格式                           | 示例                                 |
| ------------------------ | ---------------------------- | ---------------------------------- |
| `ALLUXIO_ETCD_URLS`      | `http://<etcd-service>:2379` | `http://alluxio-cluster-etcd:2379` |
| `ALLUXIO_CLUSTER_NAME`   | `<namespace>-<clusterName>`  | `alx-ns-alluxio-cluster`           |
| `ALLUXIO_WORKER_S3_PORT` | Worker S3 端口                 | `29998`（默认值）                       |

{% hint style="warning" %}
`ALLUXIO_CLUSTER_NAME` 必须遵循 `<namespace>-<clusterName>` 格式。例如，命名空间 `alx-ns` 中名为 `alluxio-cluster` 的集群，对应值为 `alx-ns-alluxio-cluster`。格式不正确将导致所有代理请求失败。
{% endhint %}

**✅ 验证：**

```shell
# 确认 Proxy Pod 运行在 worker 节点上
kubectl get pod -n <NAMESPACE> -l app=alluxio-s3-proxy -o wide

# 从同节点的 Pod 执行健康检查
kubectl exec -n <NAMESPACE> <POD_ON_WORKER_NODE> -- curl -s http://127.0.0.1:8080/health
# 预期输出：OK

# 通过 Proxy 列出 bucket
kubectl exec -n <NAMESPACE> <POD_ON_WORKER_NODE> -- \
  env AWS_ACCESS_KEY_ID=testuser AWS_SECRET_ACCESS_KEY=testpassword \
  aws s3 ls --endpoint-url http://127.0.0.1:8080
```

***

## 身份验证

Alluxio 的 S3 API 支持两种身份验证方式：

**SIMPLE（默认）** — Alluxio 解析 [AWS Signature V4](https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-auth-using-authorization-header.html) `Authorization` 标头以提取用户名，但**不验证签名**。

* **Access Key**：执行操作时使用的 Alluxio 用户名。如果省略，操作将以启动 worker 进程的用户身份执行。
* **Secret Key**：任意非空值。客户端需要它来生成签名，但 Alluxio 会忽略此值。

**OIDC** — 如需使用 OpenID Connect 令牌进行集中身份管理，请参阅[身份验证](/ee-ai-cn/administration/security/enabling-authentication.md)指南。

***

## 性能

### 关键 Alluxio 参数

以下参数控制 S3 API 性能。建议在高吞吐量工作负载中使用推荐值。

* `alluxio.worker.s3.redirect.enabled` — 默认值：`true`（重定向模式，即模式 A）；代理模式（模式 B）需设为 `false`。`false` 时所有跨 worker 读取均走代理，增加额外网络跳转，吞吐量约为重定向模式的一半。仅在客户端能正确跟随指向非 AWS endpoint 的 HTTP 307 重定向时才保持启用（参见[部署模式](#部署模式)）。
* `alluxio.worker.s3.connection.keep.alive.enabled` — 默认值：`false`；推荐值：`true`。跨请求复用 TCP 连接，减少握手开销，提高高并发下的吞吐量。
* `alluxio.worker.s3.connection.idle.max.time` — 默认值：`0sec`。Keep-alive 连接的空闲超时时间；`0` 表示无超时。
* `alluxio.worker.s3.access.logging.enabled` — 默认值：`false`；推荐值：生产环境中设为 `true`。设为 `false` 时仅记录失败请求；设为 `true` 时记录所有请求。用于审计和调试；基准测试时建议禁用以避免 I/O 开销。
* `alluxio.worker.s3.only.https.access` — 默认值：`false`。启用后，拒绝非 HTTPS 请求。
* `alluxio.worker.s3.redirect.health.check.enabled` — 默认值：`true`；建议保持启用，基准测试时同样如此。启用后，重定向目标会经过实时哈希环和 worker 可用性监控过滤，从而跳过已下线或正在重启的 worker——整个选择过程是纯内存计算，不产生任何逐请求 RPC。禁用后，重定向退回固定哈希所有者且不做存活性检查，在集群成员信息刷新之前，客户端可能被重定向到已下线的 worker。注意：在更早的版本中，该开关控制的是逐请求的健康检查 RPC，这也是早期调优建议在基准测试时将其关闭的原因；该建议不适用于本版本。

### Linux 内核参数

对于高 TCP 连接频率的高强度 S3 基准测试，调优内核参数可改善连接复用并降低延迟。

```shell
sysctl -w net.ipv4.tcp_tw_reuse=1
sysctl -w net.ipv4.tcp_fin_timeout=30

# Only on older kernels (e.g., CentOS 7 / kernel 3.10):
sysctl -w net.ipv4.tcp_tw_recycle=1
```

| 参数                         | 作用                                                                                                           |
| -------------------------- | ------------------------------------------------------------------------------------------------------------ |
| `net.ipv4.tcp_tw_reuse`    | 复用处于 `TIME_WAIT` 状态的套接字，防止高频请求下的端口耗尽。                                                                        |
| `net.ipv4.tcp_tw_recycle`  | 加速 `TIME_WAIT` 清理。**在 Linux 4.12+ 中已移除**——此参数仅存在于旧版内核（如使用 kernel 3.10 的 CentOS 7）。在新版内核上此 sysctl 键不存在，命令将失败。 |
| `net.ipv4.tcp_fin_timeout` | 缩短空闲连接关闭时间，更快释放资源。默认值：60s，推荐值：30s。                                                                           |

> **警告**：修改内核参数可能影响系统稳定性。在应用这些设置前请确保您了解其含义，尤其是在生产环境中。
>
> **NAT 兼容性**：在 `tcp_tw_recycle` 可用的旧版内核上，启用该参数可能导致 NAT 设备后的客户端出现连接失败（时间戳验证问题）。请勿在 NAT 环境中使用。

## 高级功能

### MultiPartUpload (MPU)

对于直通到底层存储的大对象上传，以下参数控制分片上传行为：

| 参数                                                    | 默认值     | 推荐值             | 描述                                      |
| ----------------------------------------------------- | ------- | --------------- | --------------------------------------- |
| `alluxio.underfs.object.store.multipart.upload.async` | `false` | `true`          | 启用到 UFS 的异步分片上传，提高写入吞吐量。                |
| `alluxio.underfs.s3.upload.threads.max`               | `20`    | 高吞吐量场景下设为 `256` | 每个 worker 用于 S3 UFS 写入的最大并发上传线程数。       |
| `alluxio.underfs.s3.multipart.upload.buffer.number`   | `64`    | 高吞吐量场景下设为 `256` | 分片上传缓冲区数量，应与 `upload.threads.max` 同步增加。 |

默认情况下，分片上传为**直通**模式——每个分片直接上传到底层存储，在 `CompleteMultipartUpload` 时在底层存储提交对象。Alluxio 不在本地缓冲分片数据。

如需先将分片写入 Alluxio 缓存层再异步持久化到底层存储，请参阅 [S3-API 写入优化](/ee-ai-cn/performance/s3-write-cache.md)。

### 标签和元数据

* **启用标签**：需要为 UFS 启用扩展属性支持：

  ```properties
  alluxio.underfs.xattr.change.enabled=true
  ```
* **标签限制**：根据 [S3 标签限制](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-tagging.html)，用户自定义标签限制为每个对象/存储桶 10 个。可通过 `alluxio.worker.s3.tagging.restrictions.enabled=false` 禁用。
* **元数据大小**：根据 [S3 元数据限制](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingMetadata.html)，用户自定义元数据限制为 2KB。可通过 `alluxio.worker.s3.header.metadata.max.size` 调整。

## 限制

在采用 Alluxio 的 S3 API 之前，请注意以下限制：

* **仅支持路径样式** — 不支持虚拟托管样式请求（`http://<bucket>.<endpoint>/...`）。所有客户端必须使用路径样式（`http://<endpoint>/<bucket>/<key>`）。
* **存储桶**：仅 Alluxio 命名空间中的顶级目录被视为 S3 存储桶。根目录（`/`）不是存储桶。为保留现有的 S3 URI，请使用存储桶名称作为挂载路径：

  ```
  alluxio mount add --path /<bucket-name> --ufs-uri s3://<bucket-name>/
  ```
* **无版本控制或锁定**：多个客户端同时写入同一对象时，最后写入者获胜。
* **不支持的字符**：对象键不得包含 `?`、`\`、`./` 或 `../`；`//` 可能导致未定义行为。对于**分片上传（MPU）**，受实现方式限制，对象键仅支持字母、数字、空格以及字符 `_ . : / = + - @`，不支持该字符集以外的字符，例如 `&`、`#`、`%`、`!`、`^`、`*`、`|`、`<`、`>`、`(`、`)`、`[`、`]`、`{`、`}`、`"`、`'` 和 `~`。
* **文件夹对象**：子目录在 `ListObjects(V2)` 响应中作为 0 字节文件夹对象返回，与 AWS S3 控制台行为一致。
* **无原子性**：GetObject 和 PutObject 中不支持 `If-Match` 和 `If-None-Match` 标头。
* **签名不被验证** — Alluxio 从 `Authorization` 标头提取用户名，但不验证加密签名。Secret Key 可以是任意非空字符串。
* **AWS SDK 客户端无法使用重定向模式** — AWS SDK (AWS CLI)、boto3 以及 PyTorch S3 Connector (AWS CRT) 不跟随指向非 AWS endpoint 的 HTTP 307 重定向。请使用[模式 B](#模式-b负载均衡-代理模式)（通过 worker 代理，部署简单）或[模式 C](#模式-c节点本地-s3-proxy)（节点本地 Proxy DaemonSet，接近模式 A 的吞吐量）。
* **无虚拟托管 DNS** — 不存在 `<bucket>.endpoint` 的 DNS 通配符解析；这是仅支持路径样式的必然结果。

## 支持的 S3 操作

下表列出了支持的 S3 API 操作。有关详细用法，请参阅[官方 S3 API 文档](https://docs.aws.amazon.com/AmazonS3/latest/API/API_Operations.html)。

| S3 API 操作                                                                                                   | 支持的标头                                                                                                       | 支持的查询参数                                                                                 |
| ----------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| [AbortMultipartUpload](https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html)       | N/A                                                                                                         | N/A                                                                                     |
| [CompleteMultipartUpload](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html) | N/A                                                                                                         | N/A                                                                                     |
| [CopyObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html)                           | `Content-Type`, `x-amz-copy-source`, `x-amz-metadata-directive`, `x-amz-tagging-directive`, `x-amz-tagging` | N/A                                                                                     |
| [CreateMultipartUpload](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html)     | N/A                                                                                                         | N/A                                                                                     |
| [DeleteBucketTagging](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketTagging.html)         | N/A                                                                                                         | N/A                                                                                     |
| [DeleteObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html)                       | N/A                                                                                                         | N/A                                                                                     |
| [DeleteObjects](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjects.html)                     | N/A                                                                                                         | N/A                                                                                     |
| [DeleteObjectTagging](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjectTagging.html)         | N/A                                                                                                         | N/A                                                                                     |
| [GetBucketTagging](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketTagging.html)               | N/A                                                                                                         | N/A                                                                                     |
| [GetObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html)                             | `Range`                                                                                                     | N/A                                                                                     |
| [GetObjectTagging](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectTagging.html)               | N/A                                                                                                         | N/A                                                                                     |
| [HeadBucket](https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadBucket.html)                           | N/A                                                                                                         | N/A                                                                                     |
| [HeadObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html)                           | N/A                                                                                                         | N/A                                                                                     |
| [ListBuckets](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBuckets.html)                         | N/A                                                                                                         | N/A                                                                                     |
| [ListMultipartUploads](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html)       | N/A                                                                                                         | N/A                                                                                     |
| [ListObjects](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjects.html)                         | N/A                                                                                                         | `delimiter`, `encoding-type`, `marker`, `max-keys`, `prefix`                            |
| [ListObjectsV2](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html)                     | N/A                                                                                                         | `continuation-token`, `delimiter`, `encoding-type`, `max-keys`, `prefix`, `start-after` |
| [ListParts](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html)                             | N/A                                                                                                         | N/A                                                                                     |
| [PutBucketTagging](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketTagging.html)               | N/A                                                                                                         | N/A                                                                                     |
| [PutObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html)                             | `Content-Length`, `Content-MD5`, `Content-Type`, `x-amz-tagging`                                            | N/A                                                                                     |
| [PutObjectTagging](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObjectTagging.html)               | N/A                                                                                                         | N/A                                                                                     |
| [UploadPart](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html)                           | `Content-Length`, `Content-MD5`                                                                             | N/A                                                                                     |

## 用法示例

### minio-py — 模式 A（支持重定向）

[minio-py](https://minio-py.min.io/) 是能正确跟随 HTTP 307 重定向到非 AWS 端点的 Python SDK。使用负载均衡器端点。

```python
from minio import Minio

client = Minio(
    "<LOAD_BALANCER_ADDRESS>",   # host:port, no http:// prefix
    access_key="testuser",       # Alluxio username (or any value)
    secret_key="testpassword",   # Ignored by Alluxio
    secure=False,                # Set True if using HTTPS
)

# List buckets (Alluxio mount points)
for bucket in client.list_buckets():
    print(bucket.name)

# Download an object
response = client.get_object("<bucket>", "<object-key>")
data = response.read()
response.close()
response.release_conn()

# Upload an object
client.put_object("<bucket>", "<object-key>", data=open("file.txt", "rb"), length=-1, part_size=10*1024*1024)
```

安装方式：`pip install minio`

### boto3 — 模式 B（代理模式）

boto3 不跟随指向非 AWS endpoint 的 HTTP 307 重定向。请使用模式 B（代理模式）配合负载均衡器端点。

```python
import boto3

s3 = boto3.client(
    "s3",
    aws_access_key_id="placeholder",      # Alluxio username (or any value)
    aws_secret_access_key="placeholder",   # Ignored by Alluxio
    region_name="us-east-1",
    endpoint_url="http://<LOAD_BALANCER_ADDRESS>:29998",
)

# List buckets (Alluxio mount points)
response = s3.list_buckets()
for bucket in response.get("Buckets", []):
    print(f" - {bucket['Name']}")
```

安装方式：`pip install boto3`

### PyTorch S3 Connector — 模式 B（代理模式）

PyTorch S3 Connector 基于 AWS CRT 构建，不跟随指向非 AWS endpoint 的 HTTP 307 重定向。请使用模式 B（代理模式）配合负载均衡器端点。

```python
from s3torchconnector import S3IterableDataset, S3ClientConfig

s3_client_config = S3ClientConfig(force_path_style=True)

dataset = S3IterableDataset.from_prefix(
    "s3://s3-mount",                                    # Alluxio mount point
    region="us-east-1",
    endpoint="http://<LOAD_BALANCER_ADDRESS>:29998",
    s3client_config=s3_client_config,
)

for item in dataset:
    content = item.read()
    print(f"{item.key}: {len(content)} bytes")
```

安装方式：

```shell
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu
pip install s3torchconnector
```

## 故障排查

### AWS CLI、boto3 或 PyTorch 返回错误或数据异常

**症状**：操作报连接错误，或返回意外结果。

**原因**：这些客户端基于 AWS SDK（或 AWS CRT）构建，不跟随指向非 AWS endpoint 的 HTTP 307 重定向，需使用[模式 B：负载均衡 + 代理模式](#模式-b负载均衡-代理模式)。详见[部署模式](#部署模式)中的配置步骤。

### `NoSuchBucket` 错误，但存储桶在 S3 中存在

**症状**：`aws s3 ls s3://<bucket>` 或 `GetObject` 返回 `NoSuchBucket`。

**原因**：在 Alluxio 的 S3 API 中，存储桶是 **Alluxio 挂载点名称**，而非 UFS 存储桶名称。S3 请求中的存储桶名称必须与 Alluxio 中的挂载路径一致（例如 `/s3` 对应存储桶名 `s3`），而非底层 S3 存储桶名称。

**诊断**：列出 Alluxio 实际暴露的存储桶名称：

```shell
AWS_ACCESS_KEY_ID=testuser AWS_SECRET_ACCESS_KEY=testpassword \
  aws s3 ls --endpoint-url http://<ENDPOINT>
```

在后续请求中使用输出中显示的名称，而非 UFS 存储桶名称。

### 29998 端口连接被拒绝

**症状**：`aws s3 ls` 返回 `Could not connect to the endpoint URL`。

**原因**：worker 上未启用 S3 API，或 worker service 不可达。

**解决方案**：

1. 确认 S3 API 已启用：

   ```shell
   kubectl -n alx-ns exec -i alluxio-cluster-worker-0 -- alluxio conf get alluxio.worker.s3.api.enabled
   ```

   预期输出：`true`。若不是，请将 `alluxio.worker.s3.api.enabled: "true"` 添加到 `alluxio-cluster.yaml` 的 `spec.properties` 并应用。
2. 如果在 Kubernetes 上未配置负载均衡器，请使用 port-forward：

   ```shell
   kubectl -n alx-ns port-forward pod/alluxio-cluster-worker-0 29998:29998 &
   ```

### `InvalidAccessKeyId` 或签名错误

**原因**：Alluxio 的 SIMPLE 认证模式不验证签名，但 `Authorization` 标头仍需存在且格式正确。部分客户端在未配置凭证时会省略该标头。

**解决方案**：传入任意非空的 access key 和 secret key。使用 AWS CLI：

```shell
AWS_ACCESS_KEY_ID=testuser AWS_SECRET_ACCESS_KEY=testpassword \
  aws s3 ls --endpoint-url http://<ENDPOINT>
```

## 另请参阅

* [S3-API 写入优化](/ee-ai-cn/performance/s3-write-cache.md) — 低延迟写入与异步持久化（需要 FoundationDB）
* [S3 API 性能基准测试](/ee-ai-cn/benchmark/s3-api.md) — 参考基线、工具选型（COSBench / Warp / httpbench）和 Linux 内核调优
* [S3 UFS 集成](/ee-ai-cn/ufs/s3.md) — 分片上传调优、高并发设置和 S3 region 配置
