# S3 API 基准测试

## 概述

摘要

* 在 Alluxio S3 兼容 API 上运行 **COSBench** 的两组性能基线
* 运行 **COSBench** 或 **Warp** 对 Alluxio S3 兼容 API 进行基准测试
* 关键潜在性能瓶颈：HTTP 重定向、网络带宽、TCP 连接复用、内核调优

有关 Alluxio S3 API 的工作原理（请求流程、一致性哈希、重定向），请参阅 [架构概述](https://documentation.alluxio.io/ee-ai-cn/data-access/s3-api#gong-zuo-yuan-li)。

## 基线：4 节点 COSBench（AWS）

* 以下性能基线假设数据已**完全缓存在 Alluxio 中**。如果数据从底层 UFS（如 S3）提供服务，吞吐量将显著降低。
* 所有吞吐量数据均为使用 4 驱动程序 COSBench 集群对 4 工作节点 Alluxio 集群测量的**集群总吞吐量**。
* **1GB 文件** — 吞吐量受**带宽限制**。随并发数增加而扩展，直到网络饱和。
* **100KB 文件** — 吞吐量受 **IOPS 限制**。随并发数增加而扩展，直到 CPU 饱和。
* 预期在硬件限制范围内（通常每个驱动程序 64-128 个线程）可实现近线性扩展。
* **集群扩展**：总吞吐量随工作节点数量的增加近似线性扩展。

### 测试环境

以下结果是使用一个 4 驱动程序的 COSBench 集群测试一个 4 工作节点的 Alluxio 集群得出的。测试衡量了对完全缓存在 Alluxio 中的数据的读取吞吐量。

| 组件                  | 配置                                                                                                                                         |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| COSBench Controller | 1x `c5n.metal`                                                                                                                             |
| COSBench Drivers    | 4x `c5n.metal`                                                                                                                             |
| Alluxio Coordinator | 1 个节点                                                                                                                                      |
| Alluxio Workers     | 4x `i3en.metal`（每个节点 8 个 NVMe SSD）                                                                                                         |
| 负载均衡器               | 跨 4 个工作节点的 AWS ELB。参见 [负载均衡器设置指南](https://documentation.alluxio.io/ee-ai-cn/data-access/s3-api#mo-shi-a-fu-zai-jun-heng-zhong-ding-xiang)。 |

### 大文件读取吞吐量（1GB 文件）

| 每个驱动程序的并发数 | 总吞吐量       |
| ---------- | ---------- |
| 1 个线程      | 2.35 GB/s  |
| 16 个线程     | 20.44 GB/s |
| 128 个线程    | 36.94 GB/s |

### 小文件读取 IOPS（100KB 文件）

| 每个驱动程序的并发数 | 总吞吐量       | 总操作数/秒      |
| ---------- | ---------- | ----------- |
| 1 个线程      | 50.26 MB/s | 502 op/s    |
| 16 个线程     | 1.10 GB/s  | 11,302 op/s |
| 128 个线程    | 4.69 GB/s  | 46,757 op/s |

## 基线：6 节点 Warp（OCI）

在 OCI `BM.DenseIO.E5.128` 节点（100Gbps 网络，12 个 NVMe 组成 RAID 0）上的 Warp GET 测试中，Alluxio 在单节点上实现了 11.2 GiB/s 的吞吐量（平均延迟 0.3 ms，P99 延迟 0.4 ms），在 6 节点上实现了 33.3 GiB/s（平均延迟 0.6 ms，P99 延迟 0.9 ms）。请注意，Warp 不跟随指向非 AWS endpoint 的 HTTP 307 重定向，因此以上数据对应[模式 B：负载均衡 + 代理模式](https://documentation.alluxio.io/ee-ai-cn/data-access/s3-api#模式-b负载均衡-代理模式)（负载均衡器 + 代理模式）。完整结果请参阅 [Alluxio on OCI](https://blogs.oracle.com/cloud-infrastructure/post/alluxio-on-oci-submillisecond-latency-for-ai)。

## COSBench 与 Warp 对比

|            | COSBench                                          | Warp                                                                                                    |
| ---------- | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| **最适合**    | 复杂的多阶段工作负载                                        | 快速的单操作验证                                                                                                |
| **部署**     | Controller + Driver 节点                            | 单一可执行文件                                                                                                 |
| **工作负载定义** | XML 配置文件                                          | CLI 参数                                                                                                  |
| **重定向支持**  | 支持 — 需要 `alluxio.worker.s3.redirect.enabled=true` | 不支持 — 请使用[模式 B：负载均衡 + 代理模式](https://documentation.alluxio.io/ee-ai-cn/data-access/s3-api#模式-b负载均衡-代理模式) |
| **结果展示**   | Web 仪表盘                                           | 终端输出                                                                                                    |

## 使用 COSBench 进行基准测试

### 先决条件

* **操作系统**：CentOS 7（内核 3.10）或更高版本。COSBench 在 Ubuntu 上存在已知兼容性问题，不推荐使用。
* **预加载数据**：对于热读取基准测试（缓存命中），请确保测试数据集已完全加载到 Alluxio 缓存中。使用 `bin/alluxio job load --path /path --submit` 加载数据，使用 `bin/alluxio fs check-cached /path` 进行验证。

### 安装

在所有 COSBench Controller 和 Driver 节点上：

1. **下载 COSBench**：下载 [COSBench 0.4.2.c4 版](https://github.com/intel-cloud/cosbench/releases/tag/v0.4.2.c4) 并解压缩。
2. **安装依赖项**：

   ```bash
   sudo yum install nmap-ncat curl java-1.8.0-openjdk-devel -y
   ```
3. **禁用 MD5 验证**：编辑 `cosbench-start.sh` 脚本并添加以下 Java 属性以禁用 S3 GET 请求的 MD5 验证。这对于与 Alluxio S3 API 的兼容性是必需的。

   ```properties
   -Dcom.amazonaws.services.s3.disableGetObjectMD5Validation=true
   ```
4. **启动 COSBench 服务**：从 COSBench 根目录启动 Controller 和所有 Driver。

   ```bash
   sudo bash start-all.sh
   ```

### 1. 配置工作负载

创建一个 XML 文件（例如 `s3-benchmark.xml`）来定义测试工作负载。一个 COSBench 工作负载由以下几个阶段组成：

| 阶段        | 用途               |
| --------- | ---------------- |
| `init`    | 创建测试存储桶          |
| `prepare` | 写入用于测试的初始数据      |
| `main`    | 在设定的持续时间内运行读/写操作 |
| `cleanup` | 删除测试期间创建的对象      |
| `dispose` | 删除存储桶            |

**注意**：如果您正在使用 Alluxio 挂载点，则无法通过 S3 API 创建新的存储桶。您必须跳过 `init` 和 `dispose` 阶段，并使用与您的挂载配置匹配的预先存在的存储桶。

**COSBench 配置语法**：

* `r(1,10)` — **范围**：按顺序遍历 1 到 10 的项目。用于 `init`、`prepare`、`cleanup` 和 `dispose` 阶段。
* `u(1,10)` — **均匀随机**：在 1 到 10 之间随机选择一个项目。用于 `main` 阶段以模拟真实的访问模式。
* `c(64)KB` — **常量**：每个对象的固定大小为 64KB。

> **存储桶命名**：COSBench 会在 `cprefix` 后自动追加数字序号。例如，`cprefix=my-bucket;containers=r(1,1)` 创建的存储桶名称是 `my-bucket1`，而非 `my-bucket`。使用预先存在的存储桶（如 Alluxio 挂载点）时，需确保 `cprefix` 生成的名称与实际存储桶名完全一致——对于名为 `my-bucket1` 的存储桶，应使用 `cprefix=my-bucket` 配合 `containers=r(1,1)`。

#### 示例：基本读/写工作负载

**目标**：使用小数据集验证基本的 S3 读/写功能。

创建两个存储桶，向每个存储桶写入 10 个 64KB 的对象，运行一个 30 秒的测试，读写比为 80/20，然后进行清理。

> **注意**：以下 `accesskey` 和 `secretkey` 为**占位符值**。请将其替换为您的 Alluxio S3 API 凭据。

```xml
<?xml version="1.0" encoding="UTF-8" ?>
<workload name="s3-sample" description="sample benchmark for s3">
  <storage type="s3" config="accesskey=root;secretkey=dump;endpoint=http://localhost:29998;path_style_access=true" />

  <workflow>
    <workstage name="init">
      <work type="init" workers="1" config="cprefix=s3testqwer;containers=r(1,2)" />
    </workstage>

    <workstage name="prepare">
      <work type="prepare" workers="1" config="cprefix=s3testqwer;containers=r(1,2);objects=r(1,10);sizes=c(64)KB" />
    </workstage>

    <workstage name="main">
      <work name="main" workers="8" runtime="30">
        <operation type="read" ratio="80" config="cprefix=s3testqwer;containers=u(1,2);objects=u(1,10)" />
        <operation type="write" ratio="20" config="cprefix=s3testqwer;containers=u(1,2);objects=u(11,20);sizes=c(64)KB" />
      </work>
    </workstage>

    <workstage name="cleanup">
      <work type="cleanup" workers="1" config="cprefix=s3testqwer;containers=r(1,2);objects=r(1,20)" />
    </workstage>

    <workstage name="dispose">
      <work type="dispose" workers="1" config="cprefix=s3testqwer;containers=r(1,2)" />
    </workstage>
  </workflow>
</workload>
```

#### 示例：高并发读取测试

**目标**：在高并发下测量最大读取 IOPS/吞吐量。与基本示例的主要区别：使用 4 个分布式 Driver，每个 128 个线程。

准备 10,000 个小对象（100KB），使用四个 Driver，每个 Driver 有 128 个工作线程，并发读取 300 秒。

> **注意**：每个 `<work>` 块在每个 Driver 中重复出现，因为 COSBench 要求对分布式工作负载进行显式 Driver 分配。每个块从单独的 Driver 节点发送流量，以最大化总并发量。

```xml
<?xml version="1.0" encoding="UTF-8" ?>
<workload name="s3-sample" description="sample benchmark for s3">
  <storage type="s3" config="accesskey=root;secretkey=dump;endpoint=http://<ip>:29998;path_style_access=true" />
  <workflow>
    <workstage name="prepare">
      <work type="prepare" workers="100" config="cprefix=ufs;containers=r(2,2);oprefix=myobjects;osuffix=.jpg;objects=r(1,10000);sizes=c(100)KB" />
    </workstage>

    <workstage name="128">
      <work name="read" workers="128" driver="driver1" runtime="300">
        <operation type="read" ratio="100" config="cprefix=ufs;containers=r(2,2);oprefix=myobjects;osuffix=.jpg;objects=u(1,10000)" />
      </work>
      <work name="read" workers="128" driver="driver2" runtime="300">
        <operation type="read" ratio="100" config="cprefix=ufs;containers=r(2,2);oprefix=myobjects;osuffix=.jpg;objects=u(1,10000)" />
      </work>
      <work name="read" workers="128" driver="driver3" runtime="300">
        <operation type="read" ratio="100" config="cprefix=ufs;containers=r(2,2);oprefix=myobjects;osuffix=.jpg;objects=u(1,10000)" />
      </work>
      <work name="read" workers="128" driver="driver4" runtime="300">
        <operation type="read" ratio="100" config="cprefix=ufs;containers=r(2,2);oprefix=myobjects;osuffix=.jpg;objects=u(1,10000)" />
      </work>
    </workstage>
  </workflow>
</workload>
```

### 2. 提交工作负载

```shell
bash cli.sh submit conf/s3-benchmark.xml
```

### 3. 监控结果

在 COSBench Web 界面查看基准测试状态和结果，网址为 `http://<CONTROLLER_IP>:19088/controller/index.html`。

### 4. 停止 COSBench 服务

```shell
sudo bash stop-all.sh
```

## 使用 Warp 进行基准测试

[MinIO Warp](https://github.com/minio/warp) 是一款轻量级 S3 性能评估工具，用于测量 GET、PUT 和混合工作负载性能。

> **重要提示**：Warp 不跟随指向非 AWS endpoint 的 HTTP 307 重定向。确保 `alluxio.worker.s3.redirect.enabled=false`（默认值）或显式设置该参数。有关哪些客户端受影响的详细信息，请参阅[部署模式](https://documentation.alluxio.io/ee-ai-cn/data-access/s3-api#部署模式)。

### 安装

```shell
# Install via Go
go install github.com/minio/warp@latest

# Or download a binary release from GitHub
```

### 运行 Warp

确保您的 `warp` 客户端可以通过网络访问 Alluxio S3 端点。

#### PUT 吞吐量（写入）

> **Warp PUT 兼容性**：Warp 默认使用 chunked SHA-256 payload 签名方式，Alluxio S3 不支持此格式，会导致写入失败并返回 `InvalidTag` 等错误。所有 `warp put` 命令均需添加 `--disable-sha256-payload=true`。

```shell
# Upload 10KB small files
warp put --host=<ALLUXIO_WORKER_IP>:29998 \
         --bucket=warp-benchmark-bucket \
         --duration=60s \
         --obj.size=10KiB \
         --concurrent=16 \
         --disable-sha256-payload=true

# Upload 1GB large files
warp put --host=<ALLUXIO_WORKER_IP>:29998 \
         --bucket=warp-benchmark-bucket \
         --region=us-east-1 \
         --obj.size=1GiB \
         --part.size=32MiB \
         --insecure \
         --concurrent=16 \
         --duration=60s \
         --disable-http-keepalive=false \
         --disable-sha256-payload=true \
         --noclear
```

#### GET 吞吐量（读取）

```shell
# Ensure data exists first (either via warp put above, or pre-loaded directly to S3)
warp get --host=<ALLUXIO_WORKER_IP>:29998 \
         --bucket=warp-benchmark-bucket \
         --concurrent=16 \
         --obj.size=100KiB \
         --duration=1m \
         --prefix=prefix/ \
         --list-existing
```

#### 多节点 GET（分布式读取）

跨多台节点运行 warp 时，使用 `--syncstart` 确保所有节点在同一时刻开始测试。如果不使用该参数，先启动的节点会在无竞争的状态下独占带宽一段时间，导致其吞吐数据偏高，聚合结果也失去横向可比性。

```shell
# 在每台 warp 节点上同时运行，使用相同的 --syncstart 时间
warp get --host=<ALLUXIO_WORKER_IP>:29998 \
         --bucket=warp-benchmark-bucket \
         --concurrent=16 \
         --obj.size=100KiB \
         --duration=5m \
         --prefix=prefix/ \
         --list-existing \
         --syncstart=14:30  # 24 小时制本地时间 HH:MM，设置为约 60 秒后
```

每台节点会生成一个本地 `.json.zst` 结果文件，合并后获得聚合统计数据：

```shell
warp merge node1.json.zst node2.json.zst node3.json.zst
```

> 有关类似硬件条件下的预期吞吐量范围，请参阅上方的[性能基线](#基线4-节点-cosbenchaws)部分。

## 性能调优与故障排除

有关建议的 Alluxio 配置参数和 Linux 内核调优，请参阅 [S3 API — 性能](https://documentation.alluxio.io/ee-ai-cn/data-access/s3-api#性能)。

* **吞吐量比预期低约 50%** — 重定向很可能已被禁用（`alluxio.worker.s3.redirect.enabled=false`，默认值），因此跨工作节点的读取会通过中间节点代理，而不是由数据所在节点直接提供服务。若要获得完整吞吐量，请使用 Pattern A：将 `alluxio.worker.s3.redirect.enabled=true` 与支持重定向的客户端配合使用。参见[部署模式](https://documentation.alluxio.io/ee-ai-cn/data-access/s3-api#部署模式)。
* **吞吐量远低于基线** — 最可能的原因是数据未完全缓存。在测试前使用 `bin/alluxio fs check-cached` 验证文件已缓存在 Alluxio 中。
* **高并发下吞吐量仍然很低** — 网络瓶颈或负载均衡器分配不均。验证 100Gbps 连接、同可用区部署，以及负载均衡器是否将请求均匀分配到所有 Alluxio 工作节点。
* **增加并发数后无法扩展** — CPU 或连接池瓶颈。检查工作节点 CPU 使用率，确保已启用 `alluxio.worker.s3.connection.keep.alive.enabled`。
* **尾部延迟高** — TCP 端口耗尽。应用[内核调优](https://documentation.alluxio.io/ee-ai-cn/data-access/s3-api#linux-内核参数)参数（`tcp_tw_reuse`、`tcp_fin_timeout`）。
* **吞吐量在较低水平停滞** — 健康检查开销。在基准测试时禁用 `alluxio.worker.s3.redirect.health.check.enabled`。
* **Warp PUT 失败或返回 `InvalidTag`** — Warp 默认使用 chunked SHA-256 payload 签名，Alluxio S3 不支持此格式。所有 `warp put` 命令均需添加 `--disable-sha256-payload=true`。
* **Warp 返回错误** — Warp 不跟随指向非 AWS endpoint 的 HTTP 307 重定向。确保 `alluxio.worker.s3.redirect.enabled=false`（默认值）。
* **多次运行结果不一致或波动较大** — 数据未完全缓存，或存在环境干扰（跨可用区流量、共享网络）。预加载数据后在专用的同可用区环境中重新运行。
* **COSBench `init` 阶段失败** — Alluxio 挂载点不支持通过 S3 API 创建存储桶。跳过 `init`/`dispose` 阶段，使用预先存在的存储桶。

## 另请参阅

* [S3 API 设置与配置](https://documentation.alluxio.io/ee-ai-cn/data-access/s3-api) — 部署模式、端点设置、负载均衡器配置和客户端示例
* [S3 UFS 集成](https://documentation.alluxio.io/ee-ai-cn/ufs/s3) — 分片上传调优、高并发设置和 S3 区域配置
