# 测试 S3 API 性能

COSBench (Cloud Object Storage Benchmark) 是由英特尔开发的一款用于对对象存储系统进行压力测试的开源工具。由于 Alluxio 公开了一个与 S3 兼容的 REST API，您可以使用 COSBench 来衡量其在基于 S3 的工作负载下的读写性能。

本指南介绍了如何设置和运行 COSBench，以对 Alluxio 集群执行端到端的性能测试。

## 性能亮点

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

### 大文件读取吞吐量 (1GB 文件)

<table><thead><tr><th width="246.1796875">每个驱动程序的并发数</th><th>总吞吐量</th></tr></thead><tbody><tr><td>1 个线程</td><td>2.35 GB/s</td></tr><tr><td>16 个线程</td><td>20.44 GB/s</td></tr><tr><td>128 个线程</td><td>36.94 GB/s</td></tr></tbody></table>

### 小文件读取 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 |

## 测试环境

基准测试结果是使用以下环境生成的，所有实例都部署在同一个 AWS 可用区中。

* **COSBench 集群**:
  * 1 个控制器节点 (`c5n.metal`)
  * 4 个驱动程序节点 (`c5n.metal`)
* **Alluxio 集群**:
  * 1 个Coordinator节点
  * 4 个工作节点 (`i3en.metal`，每个节点有 8 个 NVMe SSD)
* **负载均衡器**:
  * 配置了一个 AWS 弹性负载均衡器 (ELB)，以在四个 Alluxio 工作节点之间均匀分配 S3 请求。

## 设置和配置

### 先决条件

* **操作系统**: 建议在 CentOS 7 或更高版本上运行 COSBench。
* **预加载数据**: 对于读取基准测试，请确保您的测试数据集已从底层 UFS 完全加载到 Alluxio 缓存中。

### COSBench 安装

在所有 COSBench 控制器和驱动程序节点上：

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 根目录启动控制器和所有驱动程序。

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

## 运行基准测试

### 1. 配置工作负载

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

* `init`: 创建测试存储桶。
* `prepare`: 写入将用于测试的初始数据。
* `main`: 主要测试阶段。在设定的持续时间内运行指定的读/写操作组合。
* `cleanup`: 删除测试期间创建的对象。
* `dispose`: 删除存储桶。

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

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

此示例显示了一个简单的工作负载，它创建两个存储桶，向每个存储桶写入 10 个 64KB 的对象，运行一个 30 秒的测试，读写比为 80/20，然后进行清理。

```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>
```

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

此示例准备 10,000 个小对象 (100KB)，然后使用四个驱动程序，每个驱动程序有 128 个工作线程，并发读取这些对象 300 秒。

```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. 提交工作负载

使用 `cli.sh` 脚本将您的工作负载 XML 文件提交给 COSBench 控制器。

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

### 3. 监控结果

您可以从 COSBench Web 界面监控基准测试作业的状态并查看结果，网址为 `http://<CONTROLLER_IP>:19088/controller/index.html`。

### 4. 停止 COSBench 服务

完成测试后，停止服务。

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


---

# 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/ai-3.7/benchmark/benchmarking-s3-api-performance.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.
