4. etcd 压测工具:etcd-benchmark 与 go-stress-testing
在构建云原生日志平台时,etcd 作为 Loki 的元数据存储后端,其读写性能直接影响日志查询的响应速度和告警规则的触发延迟。本章将系统介绍两款核心压测工具——etcd-benchmark 与 go-stress-testing,并编写压测脚本模拟高负载写入与读取场景,为后续的 Loki 指标告警分层提供数据基础。
实战目标:通过本节省略的压测脚本,你可以在 5 分钟内对 etcd 集群发起 10 万级 key 写入与读取压力,并实时观测 QPS、延迟 P99、错误率等关键指标。
4.1 工具选型对比
| 特性 | etcd-benchmark | go-stress-testing |
|---|---|---|
| 维护方 | etcd 官方 | 社区开源(Go 语言) |
| 协议支持 | gRPC / HTTP | HTTP / TCP / WebSocket |
| 核心场景 | etcd 集群原生压测 | 通用 API 压力测试 |
| 指标输出 | QPS、延迟分布、错误数 | TPS、响应时间、并发数 |
| 脚本化难度 | 低(命令行参数驱动) | 中(需编写 Go 脚本或配置文件) |
| 推荐场景 | etcd 写入/读取基准测试 | 模拟 Loki 查询网关对 etcd 的访问模式 |
选型建议:etcd-benchmark 适合做 etcd 集群的极限性能摸底;go-stress-testing 更适合模拟真实业务流量,尤其是 Loki 查询组件对 etcd 的混合读写模式。
4.2 etcd-benchmark 实战
4.2.1 安装与基础参数
# 从 etcd 源码编译(推荐)
git clone https://github.com/etcd-io/etcd.git
cd etcd/tools/benchmark
go build -o benchmark .
# 或直接使用预编译二进制
wget https://github.com/etcd-io/etcd/releases/download/v3.5.15/etcd-v3.5.15-linux-amd64.tar.gz
tar -xzf etcd-v3.5.15-linux-amd64.tar.gz
cd etcd-v3.5.15-linux-amd64
./benchmark --help
4.2.2 高负载写入脚本
#!/bin/bash
# etcd_bench_write.sh - 模拟 10 万 key 高并发写入
ENDPOINTS="https://10.0.1.10:2379,https://10.0.1.11:2379,https://10.0.1.12:2379"
TOTAL_KEYS=100000
CONCURRENCY=64
KEY_SIZE=64
VAL_SIZE=256
./benchmark put \
--endpoints=$ENDPOINTS \
--total=$TOTAL_KEYS \
--conns=$CONCURRENCY \
--clients=$CONCURRENCY \
--key-size=$KEY_SIZE \
--val-size=$VAL_SIZE \
--rate=5000 \
--target-leader \
--progress-bar=true
4.2.3 高负载读取脚本
#!/bin/bash
# etcd_bench_read.sh - 模拟 10 万 key 随机读取
ENDPOINTS="https://10.0.1.10:2379,https://10.0.1.11:2379,https://10.0.1.12:2379"
TOTAL_KEYS=100000
CONCURRENCY=128
./benchmark range \
--endpoints=$ENDPOINTS \
--total=$TOTAL_KEYS \
--conns=$CONCURRENCY \
--clients=$CONCURRENCY \
--consistency=l \
--rate=10000 \
--progress-bar=true
注意:生产环境压测前务必确认 etcd 集群的
--quota-backend-bytes 和 --max-request-bytes 配置,避免压测导致集群 OOM 或请求被拒绝。
4.3 go-stress-testing 实战
4.3.1 安装与配置
# 安装 go-stress-testing
go install github.com/link1st/go-stress-testing@latest
# 验证安装
go-stress-testing -h
4.3.2 编写压测配置文件
# stress_config.yaml
concurrency: 100
total: 50000
timeout: 30s
keepalive: true
requests:
- method: PUT
url: "https://10.0.1.10:2379/v3/kv/put"
headers:
Content-Type: "application/json"
body: '{"key":"dGVzdC1rZXk=","value":"dGVzdC12YWx1ZQ=="}'
- method: POST
url: "https://10.0.1.10:2379/v3/kv/range"
headers:
Content-Type: "application/json"
body: '{"key":"dGVzdC1rZXk=","range_end":""}'
4.3.3 启动混合读写压测
# 启动混合读写压测(70% 写入 + 30% 读取)
go-stress-testing \
-c 100 \
-n 100000 \
-u https://10.0.1.10:2379/v3/kv/put \
-d 5m \
-m 1 \
-t 4 \
-p stress_config.yaml
4.4 压测架构与数据流
4.5 压测结果关键指标解读
| 指标名称 | 含义 | 健康阈值 | 告警触发值 |
|---|---|---|---|
| QPS | 每秒完成的请求数 | > 5000 | < 2000 |
| P99 延迟 | 99% 请求的响应时间 | < 50ms | > 200ms |
| 错误率 | 失败请求占比 | < 0.1% | > 1% |
| 吞吐量 | 每秒写入/读取的数据量 | > 50 MB/s | < 10 MB/s |
实战技巧:使用
etcd-benchmark 的 --rate 参数可以控制请求速率,避免瞬间打满集群导致雪崩。建议从 1000 QPS 起步,每 30 秒增加 500 QPS,直到观察到 P99 延迟超过 100ms 为止。
4.6 压测脚本集成到 CI/CD
# .gitlab-ci.yml 片段 - 集成 etcd 压测到流水线
etcd-stress-test:
stage: performance
script:
- chmod +x etcd_bench_write.sh
- ./etcd_bench_write.sh
- chmod +x etcd_bench_read.sh
- ./etcd_bench_read.sh
- go-stress-testing -c 50 -n 20000 -u https://etcd-cluster:2379/v3/kv/range -d 2m
artifacts:
paths:
- benchmark_results/
expire_in: 1 week
only:
- main
4.7 常见问题与避坑指南
- 连接数耗尽:etcd 默认最大连接数为 1000,压测时并发数超过此值会导致连接拒绝。建议在压测前调整
--max-request-bytes和--max-concurrent-streams。 - 磁盘 I/O 瓶颈:etcd 使用 Raft 协议,写入操作需要持久化到磁盘。使用 SSD 并确保
--wal-dir和--data-dir在不同磁盘上。 - 网络延迟影响:跨机房压测时,网络延迟会显著增加 P99 延迟。建议在 etcd 集群同机房内执行压测。
- 压测数据清理:压测结束后,使用
etcdctl del "" --from-key清理测试数据,避免影响后续监控。
最佳实践:将压测脚本与 Loki 的
LogQL 查询结合,在压测过程中实时查询 etcd 的写入延迟分布,快速定位性能瓶颈。