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

# httpbench 基准测试

`httpbench` 是一个专门打造的约 50 行 Go 小工具，用于测量 Alluxio S3 API 的读取吞吐。当你需要**单 worker 隔离**（比如针对某个 worker 做 CPU profiling，或测量单张 NIC），或者集群运行在 **redirect 模式**——[Warp](/ee-ai-cn/benchmark/s3-api/warp.md) 在这种集群上完全不能用——此时应选用 httpbench。与 warp 相比：透明跟随 HTTP 307（Go 默认）、接受显式 URL 列表而非枚举 bucket、不做 SigV4 签名、不发 chunked SHA-256 payload。

关于何时选用 httpbench 而非 [COSBench](/ee-ai-cn/benchmark/s3-api/cosbench.md) 或 [Warp](/ee-ai-cn/benchmark/s3-api/warp.md)，参见[基准测试工具选型](/ee-ai-cn/benchmark/s3-api.md#ji-zhun-ce-shi-gong-ju-xuan-xing)。6 × c5n.18xlarge 集群的参考吞吐数据见 [6 节点 httpbench（AWS）](/ee-ai-cn/benchmark/s3-api.md#id-6-jie-dian-httpbench-aws)。

## 先决条件

* 客户端主机上安装 Go 1.21+。
* 客户端能通过网络访问 Alluxio worker 的 S3 API 端口（默认 29998）。
* 测试数据已完全缓存。使用 `bin/alluxio job load --path <path> --submit` 预加载，使用 `bin/alluxio fs check-cached <path>` 验证。

## 安装

把工具源码保存为 `httpbench.go`：

```go
package main

import (
    "flag"
    "fmt"
    "io"
    "net/http"
    "sync"
    "sync/atomic"
    "time"
)

func main() {
    conc := flag.Int("c", 16, "concurrency (parallel workers)")
    dur := flag.Duration("d", 30*time.Second, "duration")
    flag.Parse()
    urls := flag.Args()
    if len(urls) == 0 {
        fmt.Println("usage: httpbench -c CONC -d DUR URL1 URL2 ...")
        return
    }
    tr := &http.Transport{
        MaxIdleConns:        *conc * 2,
        MaxIdleConnsPerHost: *conc * 2,
        MaxConnsPerHost:     *conc * 2,
        IdleConnTimeout:     60 * time.Second,
        DisableCompression:  true,
        ForceAttemptHTTP2:   false,
    }
    client := &http.Client{Transport: tr, Timeout: 5 * time.Minute}

    var totalBytes, totalReqs int64
    var wg sync.WaitGroup
    deadline := time.Now().Add(*dur)
    t0 := time.Now()

    for i := 0; i < *conc; i++ {
        wg.Add(1)
        go func(gid int) {
            defer wg.Done()
            j := gid
            for time.Now().Before(deadline) {
                url := urls[j%len(urls)]
                j++
                resp, err := client.Get(url)
                if err != nil {
                    continue
                }
                n, _ := io.Copy(io.Discard, resp.Body)
                resp.Body.Close()
                if resp.StatusCode >= 200 && resp.StatusCode < 300 {
                    atomic.AddInt64(&totalBytes, n)
                    atomic.AddInt64(&totalReqs, 1)
                }
            }
        }(i)
    }
    wg.Wait()
    elapsed := time.Since(t0).Seconds()
    fmt.Printf("Reqs: %d  Bytes: %.2f GB  Time: %.2fs\n",
        totalReqs, float64(totalBytes)/1e9, elapsed)
    fmt.Printf("→ %.2f GB/s  (%.1f Gbps)\n",
        float64(totalBytes)/elapsed/1e9, float64(totalBytes)*8/elapsed/1e9)
}
```

构建一次：

```shell
go build -o httpbench httpbench.go
```

构建 `文件 → 拥有 worker` 映射。下面三种场景都会复用这张表，每个 bucket 只需构建一次。对任何 worker 发起 1 字节 Range GET：本地拥有的返回 `206`，否则返回 `307`（`Location` 指向真实 owner）：

```shell
for f in $(kubectl -n alx-ns exec -i alluxio-cluster-coordinator-0 -- \
             alluxio fs ls /mybucket | awk '{print $NF}'); do
  name=$(basename "$f")
  resp=$(curl -s --range 0-0 -o /dev/null \
              -w "%{http_code}|%{redirect_url}" \
              "http://any-worker:29998/mybucket/$name")
  code=${resp%%|*}
  redir=${resp#*|}
  if [ "$code" = "206" ]; then
    echo "any-worker|$name"
  else
    owner=$(echo "$redir" | sed 's|http://||' | cut -d: -f1)
    echo "$owner|$name"
  fi
done > file_owners.txt
```

## 使用

### 场景：模式 1 —— 单 worker，仅本地 key

将一个 worker 的 S3 API 吞吐从跨 worker 路由中隔离出来。适合单独 CPU profiling 某个 worker，或测量单张 NIC。

用 worker 只打它本地的 key：

```shell
# 提取 worker-1 对应的 URL
grep "^worker-1|" file_owners.txt \
  | awk -F'|' '{print "http://worker-1:29998/mybucket/"$2}' \
  > worker-1-urls.txt

# 开测
./httpbench -c 32 -d 30s $(cat worker-1-urls.txt)
```

示例输出：

```console
Reqs: 224  Bytes: 390.86 GB  Time: 35.03s
→ 11.16 GB/s  (89.3 Gbps)
```

### 场景：模式 2 —— 单客户端，通过 redirect 访问整个 bucket

单个客户端把整个 bucket 的读取都打到同一个入口 worker。对于不属于该 worker 的 key 会触发 307；Go 的 client 透明跟随，并对真实 owner 复用 keep-alive 连接。

```shell
# 所有 URL 都指向同一个入口 worker——Alluxio 对不属于自己的内容自动 redirect
for name in $(awk -F'|' '{print $2}' file_owners.txt); do
  echo "http://worker-1:29998/mybucket/$name"
done > all-via-worker-1.txt

./httpbench -c 64 -d 30s $(cat all-via-worker-1.txt)
```

瓶颈在客户端 NIC，而非 Alluxio 集群——100 Gbps 网卡下约 11 GB/s，与模式 1 相当。关于对象大小相关的行为，参见 [307 重定向开销：大对象 vs 小对象](/ee-ai-cn/benchmark/s3-api.md#id-307-zhong-ding-xiang-kai-xiao-da-dui-xiang-vs-xiao-dui-xiang)。

### 场景：模式 3 —— N 客户端 × N worker 成对聚合

每个客户端只访问与自己配对的 worker 本地拥有的 key。这种模式对应分布式推理集群从 Alluxio 加载模型分片的真实场景。

把 `httpbench` 和对应 worker 的 URL 列表部署到 N 个客户端，然后让 N 个客户端同时起跑：

```shell
# 统一启动时间
START=$(date -d '+60 seconds' +%s)

for i in 1 2 3 4 5 6; do
  ssh client-$i "
    while [ \$(date +%s) -lt $START ]; do sleep 0.1; done
    ./httpbench -c 32 -d 30s \$(cat worker-$i-urls.txt)
  " > client-$i.out 2>&1 &
done
wait

# 聚合
awk '/GB\/s/ { sum += $2 } END { print sum, "GB/s aggregate" }' client-*.out
```

6 × c5n.18xlarge（100 Gbps NIC、数据全部缓存）上的预期聚合吞吐：**约 68 GB/s**，与每对 11.4 GB/s 近线性扩展。对照 [6 节点 httpbench（AWS）](/ee-ai-cn/benchmark/s3-api.md#id-6-jie-dian-httpbench-aws)。

## 故障排除

* **模式 2 与模式 1 吞吐几乎一致（大对象）** — 1 GiB+ 对象的预期行为，握手开销摊薄到接近于零。参见 [307 重定向开销：大对象 vs 小对象](/ee-ai-cn/benchmark/s3-api.md#id-307-zhong-ding-xiang-kai-xiao-da-dui-xiang-vs-xiao-dui-xiang)。
* **吞吐远低于 iperf3 上限的 95%** — 最可能的原因是数据未完全缓存，或命中了 AWS ENA 单 TCP 流上限（C=1 在 ENA 上被限制在约 5 Gbps，无论网卡多大）。把 `-c` 提到 32 及以上，并用 `bin/alluxio fs check-cached` 验证缓存。

跨工具的通用故障排查（内核调优、健康检查开销、尾延迟），参见 hub 页的[性能调优与故障排除](/ee-ai-cn/benchmark/s3-api.md#xing-neng-diao-you-yu-gu-zhang-pai-chu)。

## 另请参阅

* [S3 API 基准测试](/ee-ai-cn/benchmark/s3-api.md) — 概述、参考基线、工具选型、跨工具故障排查
* [COSBench 基准测试](/ee-ai-cn/benchmark/s3-api/cosbench.md) — 适合复杂的多阶段工作负载
* [Warp 基准测试](/ee-ai-cn/benchmark/s3-api/warp.md) — 适合快速 bucket 级测试，但与 redirect 模式不兼容
* [S3 API 设置与配置](/ee-ai-cn/data-access/s3-api.md) — 部署模式、redirect 行为、负载均衡器配置
