一个真实场景
测试计划写好了,5000 并发,23 分钟,写接口。
你打开数据库,准备造点测试数据。
用户数据?”先插 1 万条吧,应该够用了。”
订单数据?”找个 Python 脚本循环 INSERT,跑一晚上。”
优惠券?”这个不重要,后面再说。”
缓存呢?”压测的时候自然会热起来。”
到了周五下午,压测跑了 10 分钟,问题来了:
- 用户数据只造了 1 万条,5000 并发跑 10 分钟后,所有账号全部用完,后面请求全报”用户不存在”
- 订单表多了 50 万条脏数据,开发周一早上发现测试环境被你用乱了
- 缓存没预热,前 5 分钟全是冷启动,P95 虚高 4 倍
- 数据分布一模一样,所有用户都是同一天注册,完全模拟不了真实场景
- 重复跑了一次造数脚本,又多了 50 万条重复数据
业务方问:”数据准备得怎么样了?”
你只能回答:”还差一点,我再跑一遍脚本……”
还差一点。还差一点。
这个场景的问题,不是”不会造数据”,而是造数据本身就没有工程化方法。
perf-data-builder 是什么
perf-data-builder 是性能测试 7 个 Skill 中的第 3 个,定位是压测数据构造。
它不是帮你写 INSERT 语句,而是帮你回答一系列工程化问题:
- 这次压测需要造多少条数据?有公式,不用拍脑袋
- 造的数据会不会污染日常测试环境?有隔离标记,精准清理
- 数据分布真实吗?幂律/正态/对数正态,自动匹配业务特征
- 写接口压测后怎么清理脏数据?强制输出清理脚本,四种模式可选
- 分布式压测,多台机器怎么分数据?自动分片,避免热点 Key
- 缓存和 DB 数据不同步怎么办?DB 造完自动预热缓存
简单说:输入压测计划(或几个参数),输出一套可直接用于压测的、带清理脚本的、工程化的数据包。
能解决什么问题
问题一:数据量算不准,凭感觉造
以前:
开发说”你先造点数据”,你凭感觉插 1 万条。
压测跑了 5 分钟,数据耗尽,后面全报错。
你再加 1 万条,又耗尽了。来回补了 3 次,一下午过去了。
现在:
P03 内置了标准数据量计算公式,自动从上游 perf-test-planner 读取并发数和时长,套用公式:
| 接口类型 | 公式 | 说明 |
|---|---|---|
| 读接口 | Data = C x T x 60 x 1.5 | 系数 1.5 = 安全冗余,防止热点 100% 命中 |
| 写接口 | Data = C x T x 60 x 2 | 系数 2 = 幂等校验 + 清理前留存余量 |
京东订单案例:
- C = 6000(含超压),T = 23 分钟,写接口
- Data = 6000 x 23 x 60 x 2 = 16,560,000 条
- 实际准备:2000 万条(含 20% 余量)
不用拍脑袋,公式算出来是多少就造多少。
问题二:写接口脏数据污染测试环境
以前:
订单提交是写接口,你用 5000 并发无限循环压。
10 分钟后测试账号全部用完,后面的请求全报”用户不存在”。
订单表多了几万条脏数据,开发周一早上发现测试环境被你用乱了。
你:”我周末再清理一下……”
现在:
P03 强制给所有压测数据加统一业务标记字段:
perf_tag = 'perf_{plan_id}_{YYYYMMDD}'
例:perf_tag = 'perf_jd-order-perf-20260611_20260611'
环境隔离策略:
| 环境类型 | 隔离策略 |
|---|---|
| 测试环境 | 独立表前缀 perf_xxx 或独立 schema |
| 生产压测 | 强制使用影子表/影子库,禁止写入主业务表 |
造数前自动校验:目标库不是 perf_ 前缀 / 不是影子库 → 高危告警,终止执行。
清理时按 perf_tag 精准删除,一行日常测试数据都不会误删。
问题三:数据分布不真实,全是模板数据
以前:
你用脚本循环 INSERT,所有用户都是同一天注册,所有商品价格都是 100 元。
压测结果:缓存命中率 100%,P95 虚低。
上线后真实用户分散在全年 365 天注册,缓存命中率只有 60%,P95 直接炸了。
现在:
P03 支持按业务特征自动匹配分布类型:
还强制包含异常数据(压测必测边界场景):
问题四:关联数据断裂,外键报错
以前:
你造了订单数据,但对应的用户数据没造。
压测跑到一半,报 user_id=99999 在用户表不存在。
你:”哦对,还要先造用户……”
现在:
P03 自动解析数据依赖拓扑,按依赖层级自动排序:
Layer 0(无依赖):用户 → 商品 → 库存 → 优惠券
↓
Layer 1(依赖 L0):购物车 → 收藏夹
↓
Layer 2(依赖 L0+L1):订单 → 支付单
↓
Layer 3(依赖 L2):支付日志 → 订单状态流转
分批执行 + 断点续跑:千万级数据避免单次超时,每 200 万条记录一个检查点,中断后从检查点继续。
问题五:重复造数报错,幂等性没保障
以前:
你跑了一遍造数脚本,发现有些数据不对,想重新跑。
结果:重复数据全部进表,订单表多了两倍数据。
你只能手动 DELETE,跑了一下午。
现在:
P03 输出的脚本内置幂等性保障:
DDL 模式(直接灌库):
-- 重复执行不报错,不重复插数据
INSERT IGNORE INTO perf_user (user_id, ...) VALUES (...);
-- 或
INSERT INTO perf_user (...) VALUES (...)
ON DUPLICATE KEY UPDATE updated_at = NOW();
接口调用模式(走业务接口):
# 请求头携带幂等键,服务端同一键重复提交返回已存在
headers = {
"X-Idempotent-Key": md5(f"{plan_id}_{index}".encode()).hexdigest()
}
进度文件:脚本执行前读取进度,跳过已完成的部分,支持断点续跑。
问题六:分布式压测,多台机器抢同一批数据
以前:
你用 10 台压测机,每台机器用同一份 CSV 参数文件。
结果:热点 Key 被打爆,Redis CPU 直接 100%。
你:”怎么回事?单机跑没问题啊……”
现在:
P03 识别到上游计划指定 slave_count ≥ 2 时,自动触发数据分片:
| 分片策略 | 适用场景 |
|---|---|
| ID 区间分片(推荐) | 有序 ID,简单可控 |
| 用户 ID 哈希分片 | 无序 ID,分布均匀 |
京东订单案例(11 台机器,10 台 Slave):
每台机器用独立的 CSV 参数文件,避免热点 Key 冲突。
Skill核心能力
P03 支持两种数据构造模式,根据场景自动选择:
两种模式通用核心能力:
实战案例:京东订单 2000 万条数据构造
用 P03 处理京东订单提交接口的压测数据构造,完整走一遍:
上游参数(从 P02 自动读取)
| 参数 | 值 |
|---|---|
| plan_id | jd-order-perf-20260611 |
| 目标并发 C | 6000 |
| 压测时长 T | 23 分钟 |
| 接口类型 | 写接口 |
| 冷热数据比 | 9:1 |
| Slave 节点数 | 11(10 台 Slave + 1 台 Master) |
Step 1:计算数据量
写接口公式:Data = C x T x 60 x 2
= 6000 x 23 x 60 x 2
= 16,560,000 条
实际准备:20,000,000 条(含 20.8% 余量)
- 热数据(90%):18,000,000 条
- 冷数据(10%): 2,000,000 条
Step 2:生成基础数据(Layer 0)
| 数据类型 | 数量 | 分布规则 |
|---|---|---|
| 用户数据 | 10 万条 | 90% 热点(近 30 天注册),10% 冷数据(1 年前) |
| SKU 数据 | 1 万条 | 幂律分布,TOP 100 SKU 占 70% 流量 |
| 库存数据 | 1 万条 | 与 SKU 1:1,随机 100~5000 |
| 优惠券数据 | 5 万条 | 40% 命中率,4 种类型 |
Step 3:生成订单数据(Layer 2,写接口)
P03 输出 Python 造数脚本,内置:
- QPS 限速:500 QPS,避免造数本身压垮服务
- 失败重试:最多 3 次,指数退避
- 幂等键:
X-Idempotent-Key头,重复执行不重复造数 - perf_tag 标记:所有数据携带
perf_jd-order-perf-20260611_20260611
Step 4:缓存联动预热
DB 数据造完后,P03 自动生成 Redis 预热脚本:
# 预热热点 SKU 信息(TOP 100,TTL=3600s)
# 预热库存数据(TTL=600s,模拟高频刷新)
# 预热用户 Session(90,000 条,TTL=1800s)
# 预热优惠券池(SET 结构,TTL=3600s)
Step 5:输出校验报告
P03 自动生成 [plan_id]-数据构造-校验报告.md,包含:
这份报告直接作为下游 perf-readiness-checker 的入参,压测前自动检查。
输出物示例
P03 根据场景复杂度,输出 3~8 个文件:
京东订单案例输出清单:
jd-order-perf-20260611-数据构造-DDL建表.sql # 6 张表,含索引设计
jd-order-perf-20260611-数据构造-批量导入.sql # LOAD DATA INFILE,比 INSERT 快 20 倍
jd-order-perf-20260611-数据构造-接口调用.py # 主造数脚本(限速/重试/幂等)
jd-order-perf-20260611-数据构造-参数模板.json # 接口参数分布规则
jd-order-perf-20260611-数据构造-缓存预热.sh # Redis 6 步预热
jd-order-perf-20260611-数据构造-清理回滚.sql # 4 种清理模式
jd-order-perf-20260611-数据构造-校验报告.md # 量化校验,下游就绪检查入参
jd-order-perf-20260611-数据构造-分片说明.md # 10 Slave 数据范围分配
所有文件统一继承 plan_id 前缀,方便归档和追溯。
DDL建表数据如下:
批量导入测试数据:
构造数据校验报告:
怎么用
在 WorkBuddy 中使用
最佳实践:接在 P02 后面用
P02 perf-test-planner 的输出里已经有 plan_id、并发目标、时长、冷热比例。把测试计划文档扔给 P03:
> 「根据这份测试计划,帮我准备压测数据」
P03 会自动读取 P02 的输出,跳过重复问询,直接生成数据构造方案。
如果没有 P02,也可以直接描述需求:
> 「我要对订单提交接口做压测,目标并发 6000,时长 23 分钟,帮我构造测试数据」
P03 会追问几个关键问题:接口类型(读/写/混合)、冷热数据比例、是否需要分布式分片,然后生成方案。
在其他平台也能用
P03 不是 WorkBuddy 专属,每个 Skill 都内置了跨平台通用 Prompt 模板。以下平台都能用:
| 平台 | 使用方式 |
|---|---|
| WorkBuddy | @skill:perf-data-builder 直接调用,文件输出最完整 |
| Cursor | 复制 Prompt 模板 → 粘贴到 Chat 或 .cursorrules 文件 → 输入需求 |
| Trae | 复制 Prompt 模板 → 侧边栏 AI 助手 → 开始对话 |
| Claude / ChatGPT / DeepSeek | 复制 Prompt 模板 → 新建对话 → 输入具体需求 |
复制方式:打开 Skill 文件,找到 ## 跨平台 Prompt 模板 v1.1.0 部分,复制整个代码块内容,粘贴到目标平台即可。输出质量和 WorkBuddy 一致,只是文件和版本需要手动维护。
使用前 vs 使用后
总结
性能测试数据构造不是”插几条数据就完事”的。它是一套工程化流程:
- 多少数据 → 决定用公式计算,还是拍脑袋
- 什么分布 → 决定压测结果能否反映真实场景
- 怎么隔离 → 决定会不会污染日常测试环境
- 怎么清理 → 决定多轮回归能否自动化
- 怎么分片 → 决定分布式压测会不会热点爆炸
P03 perf-data-builder 把这套流程固化成 Skill,让你不再凭感觉造数,每一步都有公式、有隔离、有清理、有校验。
下一篇,我会介绍 P04 perf-readiness-checker ,压测就绪检查 Skill。数据造好了、脚本写好了、环境配好了,压测前最后一道防线,帮你把所有隐患在按下”开始”之前全部揪出来。
专栏目录(持续更新):篇号主题Skill第 1 篇需求澄清perf-requirement-clarifier第 2 篇测试计划perf-test-planner第 3 篇数据构造perf-data-builder第 4 篇就绪检查perf-readiness-checker第 5 篇JMX 脚本perf-jmx-generator第 6 篇报告分析perf-report-analyzer第 7 篇报告生成perf-report-writer
如果这篇对你有帮助,欢迎随手转发~
声明:来自AI应用案例库,仅代表创作者观点。链接:https://eyangzhen.com/8560.html