3. etcd 压测工具选型与部署:benchmark、etcdctl check perf、ghz 与自定义脚本

在跨集群调度沙盘中,etcd 作为 Kubernetes 控制面的状态存储核心,其性能直接决定调度延迟与集群稳定性。本章聚焦四类压测工具的选型逻辑、部署配置与适用场景,帮助你在沙盘环境中精准评估 etcd 的读写吞吐、延迟分布与限速行为。

选型原则: 优先使用官方工具建立基线,再用 gRPC 级工具模拟真实 workload,最后用自定义脚本覆盖边界场景。不要在生产集群直接运行压测,始终在沙盘隔离环境中执行。

3.1 工具对比与选型矩阵

工具 协议层 核心能力 输出指标 推荐场景
benchmark etcd v3 gRPC PUT/GET 吞吐、延迟分布、连接数控制 Ops/sec, P99/P999 延迟 快速基线测试、限速验证
etcdctl check perf etcd v3 API 端到端健康检查、延迟直方图 平均延迟、通过/失败状态 日常巡检、部署后验证
ghz gRPC 原生 自定义 protobuf 请求、并发模型、元数据注入 RPS, 延迟分布, 错误码 模拟真实客户端、watch 场景
自定义脚本 (Python/Go) etcd clientv3 事务、租约、watch、多 key 模式 自定义指标、业务级延迟 复杂工作负载、压力模型复现

3.2 benchmark 工具部署与配置

benchmark 是 etcd 官方提供的压测二进制,位于 etcd 仓库的 tools/benchmark 目录。推荐在沙盘的控制节点上直接编译或使用预编译镜像。

3.2.1 编译与部署

# 在沙盘控制节点编译
git clone https://github.com/etcd-io/etcd.git --branch v3.5.15
cd etcd/tools/benchmark
go build -o benchmark .

# 验证部署
./benchmark --help

3.2.2 典型压测命令

# 10 并发、10000 请求的 PUT 压测
./benchmark put \
  --endpoints=https://10.0.1.10:2379,https://10.0.1.11:2379 \
  --conns=10 \
  --clients=10 \
  --total=10000 \
  --key-size=64 \
  --val-size=256 \
  --cert=/etc/etcd/pki/etcd.pem \
  --key=/etc/etcd/pki/etcd-key.pem \
  --cacert=/etc/etcd/pki/ca.pem

# 输出示例
# 10000 requests finished in 2.345s
# Average:  0.234ms
# P99:      1.023ms
# P999:     2.456ms
关键参数说明:
  • --conns:底层 gRPC 连接数,建议与 etcd 节点数一致或略高。
  • --clients:并发客户端数,模拟实际 apiserver 行为。
  • --key-size / --val-size:模拟真实 Kubernetes 资源对象大小(如 Pod 约 2KB)。
  • 沙盘中建议先以 --total=5000 做预热,再执行正式压测。

3.3 etcdctl check perf 部署与配置

etcdctl check perf 是 etcdctl 内置的子命令,无需额外安装,适合快速验证集群健康状态。

3.3.1 基本用法

# 默认 60 秒压测
etcdctl check perf \
  --endpoints=https://10.0.1.10:2379 \
  --cert=/etc/etcd/pki/etcd.pem \
  --key=/etc/etcd/pki/etcd-key.pem \
  --cacert=/etc/etcd/pki/ca.pem

# 输出示例
# 60.0s: Average: 0.45ms | P99: 2.1ms | Throughput: 12500 ops/s
# FAIL: P99 latency 2.1ms exceeds threshold 1.0ms

3.3.2 自定义阈值与时长

# 设置 P99 阈值为 5ms,压测时长 120 秒
etcdctl check perf \
  --endpoints=https://10.0.1.10:2379 \
  --duration=120s \
  --p99-threshold=5ms \
  --cert=/etc/etcd/pki/etcd.pem \
  --key=/etc/etcd/pki/etcd-key.pem \
  --cacert=/etc/etcd/pki/ca.pem
注意: etcdctl check perf 会创建大量临时 key(前缀为 check-perf-),压测后需手动清理。沙盘中建议在独立租约空间运行,避免干扰业务数据。

3.4 ghz(gRPC 压测)部署与配置

ghz 是通用的 gRPC 压测工具,支持自定义 protobuf 消息、元数据注入和并发模型。对于 etcd 的 watch、事务等复杂操作,ghz 比 benchmark 更灵活。

3.4.1 部署方式

# 方式一:Go 安装
go install github.com/bojand/ghz/cmd/ghz@latest

# 方式二:Docker 运行(推荐沙盘使用)
docker run --rm -v $(pwd):/data ghzio/ghz:0.120.0 \
  --config /data/etcd-put.json

3.4.2 配置文件示例(etcd-put.json)

{
  "proto": "/data/etcd.proto",
  "call": "etcdserverpb.KV.Put",
  "total": 5000,
  "concurrency": 20,
  "metadata": {
    "authorization": "Bearer <>"
  },
  "data": {
    "key": "aW5jcmVtZW50YWw=",
    "value": "dGVzdF92YWx1ZQ=="
  },
  "insecure": false,
  "cacert": "/data/ca.pem",
  "cert": "/data/client.pem",
  "key": "/data/client-key.pem"
}

3.4.3 运行与输出

ghz --config /data/etcd-put.json \
  --endpoints https://10.0.1.10:2379

# 输出摘要
# Summary:
#   Count:        5000
#   Total:        3.12 s
#   Slowest:      45.23 ms
#   Fastest:      0.12 ms
#   Average:      1.56 ms
#   Requests/sec: 1602.56
#   Error Distribution:
#     [4] Unavailable: 2
ghz 优势: 支持 --data-file 传入 CSV/JSON 数据源,可模拟不同 key 分布;支持 --stream 模式测试 watch 流,适合评估 etcd 的推送能力。

3.5 自定义压测脚本(Python/Go)

当标准工具无法覆盖业务级场景(如事务、租约续期、多 key 原子操作)时,需要编写自定义脚本。以下给出 Python 和 Go 的典型模板。

3.5.1 Python 脚本(使用 etcd3gw)

import etcd3gw
import time
import threading

endpoints = ["https://10.0.1.10:2379"]
client = etcd3gw.client(
    host=endpoints[0],
    cert=("/etc/etcd/pki/client.pem", "/etc/etcd/pki/client-key.pem"),
    ca_cert="/etc/etcd/pki/ca.pem"
)

def put_worker(worker_id, count):
    for i in range(count):
        key = f"/test/worker-{worker_id}/key-{i}"
        value = f"value-{i}" * 32  # 模拟 256B 值
        start = time.time()
        client.put(key, value)
        elapsed = time.time() - start
        if elapsed > 0.1:  # 记录超过 100ms 的慢请求
            print(f"SLOW: worker={worker_id}, key={key}, latency={elapsed:.3f}s")

threads = []
for w in range(10):  # 10 个并发 worker
    t = threading.Thread(target=put_worker, args=(w, 1000))
    threads.append(t)
    t.start()

for t in threads:
    t.join()
print("Custom Python benchmark completed.")

3.5.2 Go 脚本(使用 clientv3)

package main

import (
    "context"
    "fmt"
    "sync"
    "time"
    clientv3 "go.etcd.io/etcd/client/v3"
)

func main() {
    cli, err := clientv3.New(clientv3.Config{
        Endpoints:   []string{"https://10.0.1.10:2379"},
        DialTimeout: 5 * time.Second,
        TLS:         loadTLSConfig(),
    })
    if err != nil {
        panic(err)
    }
    defer cli.Close()

    var wg sync.WaitGroup
    totalOps := 10000
    concurrency := 20
    opsPerWorker := totalOps / concurrency

    for w := 0; w < concurrency; w++ {
        wg.Add(1)
        go func(workerID int) {
            defer wg.Done()
            for i := 0; i < opsPerWorker; i++ {
                ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
                key := fmt.Sprintf("/bench/go-%d/key-%d", workerID, i)
                _, err := cli.Put(ctx, key, "bench-value")
                cancel()
                if err != nil {
                    fmt.Printf("ERROR: worker=%d, key=%s, err=%v\n", workerID, key, err)
                }
            }
        }(w)
    }
    wg.Wait()
    fmt.Println("Go benchmark completed.")
}
自定义脚本最佳实践:
  • 始终设置 context.WithTimeout,避免 goroutine 泄漏。
  • 记录每个请求的延迟分布,输出 P50/P90/P99 直方图。
  • 在沙盘中先运行小规模(1000 ops)验证脚本正确性,再放大到生产级压力。
  • 使用 sync.WaitGroup 或 asyncio 控制并发,避免无限制创建协程。

3.6 工具部署架构总览

下图展示了四种压测工具在沙盘环境中的部署位置与数据流关系。所有压测客户端均运行在沙盘控制节点或独立压测 Pod 中,通过 TLS 与 etcd 集群通信。

etcd 压测工具部署架构 压测客户端节点 benchmark 二进制 etcdctl check perf ghz (gRPC 压测) 自定义脚本 Python / Go clientv3 etcd 集群(沙盘) etcd-0 10.0.1.10:2379 etcd-1 10.0.1.11:2379 etcd-2 10.0.1.12:2379 压测数据流说明 • 实线:benchmark / etcdctl / ghz 直接 gRPC 调用 • 虚线:自定义脚本通过 clientv3 库发起请求 • 所有流量经 TLS 加密,沙盘内网隔离

3.7 压测执行流程与注意事项

  1. 环境准备: 确认沙盘 etcd 集群健康(etcdctl endpoint health),记录基线延迟。
  2. 基线测试: 使用 benchmark 执行 1000 次 PUT/GET,记录 P99 延迟与吞吐。
  3. 压力递增: 以 10、50、100、200 并发逐步增加负载,观察延迟拐点。
  4. 混合场景: 使用 ghz 或自定义脚本模拟 70% PUT + 20% GET + 10% 事务的混合 workload。
  5. 限速验证: 在沙盘中配置 --max-request-bytes 或 --quota-backend-bytes,验证限速行为。
  6. 数据清理: 压测后删除测试 key(如 etcdctl del /test --prefix),恢复沙盘状态。
沙盘安全红线:
  • 禁止在沙盘 etcd 的 --data-dir 目录直接写入或删除文件。
  • 压测并发数不要超过沙盘 CPU 核心数的 4 倍,避免宿主机 OOM。
  • 每次压测前记录 etcd 的 --quota-backend-bytes 当前值,防止磁盘空间写满。

3.8 工具选型决策树

根据压测目标快速选择工具:

压测目标 推荐工具 理由
快速验证集群健康 etcdctl check perf 零配置,内置阈值判断
吞吐量基线测试 benchmark 官方优化,输出标准指标
gRPC 协议级压测 ghz 支持自定义 protobuf 和元数据
复杂业务场景复现 自定义脚本 (Go) 完全控制请求逻辑与并发模型
watch 流性能评估 ghz + 自定义脚本 ghz 支持 stream,脚本可定制事件处理