# 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）无法使用此模式。

### 选择部署模式

```
您的客户端是否跟随指向非 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，跨 worker 代理导致集群总吞吐量约为 50%
```

### 模式 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 %}

***

## 身份验证

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` — 默认值：`false`；模式 A 需设为 `true`。`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`；推荐值：基准测试时设为 `false`。禁用重定向前的逐请求 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负载均衡-代理模式)（`alluxio.worker.s3.redirect.enabled=false`，默认值）。
* **无虚拟托管 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 配置


---

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