Why: Checklist B6 needs a repeatable database-only baseline that cannot reach production ports or instances. Evidence: run_pgbench.sh --self-check passed (help, unknown arg, foreign name, busy port, SIGINT cleanup). Timed runs are recorded separately. Impact: New load-test entry and README note. No product or release-gate change. Refs: docs/release-multi-instance.md B6 Co-authored-by: Cursor <cursoragent@cursor.com>
4.5 KiB
4.5 KiB
协作存储压测套件(U7 / B5 / C2)
方案 §3 负载合同 / §5 U7 的业务压测入口。只打隔离栈(自建 PG 实例 + mock 模式 backend),绝不打生产服务;模拟模型(mock)用于容量基线,真实 模型的全链路验证按方案另行小流量执行。
组成
| 文件 | 职责 |
|---|---|
run_load.sh |
编排入口:起隔离栈 → 可选 seed → 引导账号 → k6 → SSE 探针 → 不变量对账 → 回收 |
seed/ |
B5 大数据量种子(PG COPY:messages/events/knowledge;tiny / contract) |
k6/collab_api.js |
混合读写负载;双实例时 BASE_URLS VU 粘滞 + 跨实例读 + 热点会话 409 |
sse_probe/ |
SSE 持久事件可见延迟探针(Go);双实例时对 A/B 各跑一份 |
results/<ts>/ |
原始输出:k6-summary.json、sse-probe-a.json(及 -b)、seed-manifest.json、invariants.txt |
快速开始
# 冒烟(~2 分钟,无需 k6——缺失时自动跳过 k6 段并给出安装指引)
tests/load/collaboration/run_load.sh --profile smoke
# B5 tiny seed + 单实例冒烟(接线验证,秒级灌库)
tests/load/collaboration/run_load.sh --profile smoke --seed tiny
# C2 双实例冒烟(共享 PG/artifacts;VU 分摊两址)
tests/load/collaboration/run_load.sh --profile smoke --seed tiny --instances 2
# 阶梯(10→30→100 VU,~12 分钟;k6: brew install k6)
tests/load/collaboration/run_load.sh --profile ladder --users 30
# 长稳(60 分钟 / 2 小时混合)
tests/load/collaboration/run_load.sh --profile sustained60m
tests/load/collaboration/run_load.sh --profile sustained2h
# 负载合同满量 seed(约 100 万消息 + 10 万知识;数分钟与数 GB 磁盘,视机器)
tests/load/collaboration/run_load.sh --seed contract --profile smoke --skip-k6 --skip-probe --keep
# 或只跑 seed 二进制(库须已迁移且 seed_u* 已 CLI 建号):
# .build/seed --dsn "$APP_DSN" --profile contract --manifest /tmp/seed-manifest.json
# 复用已有隔离 PG;保留栈便于复查
tests/load/collaboration/run_load.sh --dsn 'postgresql://…/agent' --keep
--seed 档位
| profile | 用户 | 项目/用户 | 会话/项目 | messages(+events) | knowledge | 用途 |
|---|---|---|---|---|---|---|
none |
— | — | — | 0 | 0 | 默认;空库压测 |
tiny |
3 | 2 | 2 | 1 000 | 1 000 | 接线冒烟(秒级) |
contract |
10 | 5 | 10 | 1 000 000 | 100 000 | 方案 §3 数据量档 |
- 约 10% knowledge 行
owner=''(基座共享知识语义);不写knowledge_vectors(进程内向量扫描面向数万块;100 万分块扩展档另档)。 - 交叉授权:数据集含多用户多项目 + 共享分块;EXT-8
ResourceAuthorizer矩阵 仍由检查单 A7 覆盖,本入口不注入 load-only 授权后门。 contract耗时/磁盘随机器变化;正式容量结论须绑定组件 SHA 与results/<ts>/seed-manifest.json,不预填。
--instances(C2)
| 值 | 行为 |
|---|---|
1(默认) |
单 serve:u7load-a @ --port(默认 18980) |
2 |
双 serve 共享同一 APP_DSN 与 artifacts;B @ --port-b(默认 18982,避开隔离 PG 18981) |
双实例时 k6 注入 BASE_URLS=a,b:VU 粘滞到实例、跨实例读抽样、热点会话
跨实例写计入 expected_contention(409)。非热点会话读路径仍受
P95≤300ms 阈值约束——「互相不拖累」的可机判口径。SSE 探针对 A/B 各跑一份。
阈值与口径(负载合同,待实测校准)
- 非模型普通 API:读路径 P95≤300ms、P99≤1s(k6 threshold 按
read组单列)。 - 非预期失败率≤0.1%(
http_req_failed<0.001);预期拥塞(会话忙 409 / 队列满 429)记入expected_contention,不计入失败。 - SSE 持久事件可见延迟 P95≤1s + seq 零乱序(探针退出码即断言)。
- 数据不变量零违反:events 每会话 seq 无重复(SQL 对账,违反即 exit 1)。
边界(诚实声明)
- 正式 60min/2h 窗口、双主机(C3)、
contract满量压测窗口需用户指定资源与时间; 本仓提供可复核入口,不预填容量结论。 pgbench只测数据库能力,不替代站点业务验收(方案 §5 U7)。入口是run_pgbench.sh(检查单 B6):隔离实例u7bench、端口 18995、scale 100, select-only 与 TPC-B 各跑 10/30/100 客户端。没有业务阈值;结果是参考基线。- k6 缺失时跳过 k6 段并写
k6-skipped.txt;探针与对账仍跑。