每日一句正能量
每一个不曾起舞的日子都是对生命的辜负。
它是一声激昂的号角,催促我们珍惜当下,用最大的热情去爱、去创造、去体验,让每一天都充满“活着”的实感。它和“平静”并不矛盾,因为内心的丰盈起舞,也可以是静默而深沉的。
摘要
摘要:基准测试最容易犯的错是只跑一个"好看"的配置。本文固定数据集规模,系统性扫描并发与批量参数,给出 KWDB 在你硬件环境下的写入吞吐与查询延迟曲线,并诚实呈现波动与不理想的数据点。
一、为什么需要自己做基准:官方口径 vs 自测的必要性
1.1 官方数据的"滤镜"
KWDB 官方宣称:"单节点支持 50 万测点/秒实时数据写入,批量写入支持千万测点/秒,TSBS 基准写入速度达 200 万记录/秒"。这些数据来自特定硬件(16 核/32GB/SSD)和特定配置(workers=12, batch-size=10000)。
但你的生产环境可能是:
- 4 核 8GB 的云服务器
- 共享存储而非本地 SSD
- 网络延迟更高的分布式部署
官方数据是"上限参考",不是"性能保证"。
1.2 测试环境透明化披露
| 项目 | 配置 |
|---|---|
| 机器型号 | 阿里云 ECS g7.xlarge |
| CPU | 4 核 Intel Xeon Platinum 8369B |
| 内存 | 16 GB |
| 磁盘 | ESSD PL1 云盘 100GB |
| 操作系统 | Ubuntu 22.04 LTS |
| KWDB 版本 | V3.1.0 |
| 部署方式 | Docker 单节点 |
| kwdb-tsbs 版本 | master 分支(2026-10-20) |
二、kwdb-tsbs 上手:三阶段跑通实录
2.1 kwdb-tsbs 基准测试三阶段流程
┌─────────────────────────────────────────────────────────────────┐
│ kwdb-tsbs 基准测试全流程 │
└─────────────────────────────────────────────────────────────────┘
│
┌─────────────────┼─────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────
│ 阶段一 │ │ 阶段二 │ │ 阶段三 │
│ 数据生成 │ │ 数据写入 │ │ 查询测试 │
│ │ │ │ │ │
│ tsbs_generate│ │ tsbs_load │ │ tsbs_run │
│ _data │ │ _kwdb │ │ _queries │
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
▼ ▼ ▼
┌───────────── ┌─────────────┐ ┌─────────────┐
│ 输入参数 │ │ 输入参数 │ │ 输入参数 │
│ │ │ │ │ │
│ • scale │ │ • file │ │ • file │
│ • log-interval│ │ • batch-size│ │ • workers │
│ • timestamp │ │ • workers │ │ • query-type│
│ • orderqty │ │ • insert-type│ │ • queries │
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────
│ 输出结果 │ │ 输出结果 │ │ 输出结果 │
│ │ │ │ │ │
│ • data.dat │ │ • 写入耗时 │ │ • 查询延迟 │
│ • 记录数 │ │ • metrics/s │ │ • QPS │
│ • 指标数 │ │ • rows/s │ │ • min/max │
└─────────────┘ └─────────────┘ └─────────────┘
2.2 关键参数说明
| 阶段 | 关键参数 | 说明 | 默认值 |
|---|---|---|---|
| 数据生成 | scale |
设备数量 | 100 |
log-interval |
采样间隔 | 10s | |
timestamp-start/end |
时间范围 | 1天 | |
| 数据写入 | batch-size |
每批写入量 | 10000 |
workers |
并发写入数 | 4 | |
insert-type |
写入模式 | insert | |
| 查询测试 | workers |
并发查询数 | 1 |
query-type |
查询类型 | double-groupby-5 | |
queries |
查询总数 | 1000 |
2.3 环境准备与编译
# 克隆仓库
git clone https://gitee.com/kwdb/kwdb-tsbs.git
cd kwdb-tsbs
# 编译(需 Go 1.23+)
make
# 确认二进制文件
ls bin/
# tsbs_generate_data tsbs_load_kwdb tsbs_generate_queries tsbs_run_queries_kwdb
编译耗时:~3 分钟(依赖网络下载 Go modules)
2.4 阶段一:数据生成
./bin/tsbs_generate_data \
--format="kwdb" \
--use-case="cpu-only" \
--seed=123 \
--scale=100 \
--timestamp-start="2026-01-01T00:00:00Z" \
--timestamp-end="2026-01-02T00:00:00Z" \
--log-interval="10s" \
--orderquantity=12 \
> data.dat
关键参数说明:
scale=100:100 台设备log-interval=10s:每 10 秒采样一次orderquantity=12:与后续 workers 参数对齐
生成结果:
文件大小:~45 MB
记录数:864,000 条(100 设备 × 8640 采样点/设备)
指标数:8,640,000 个(每台设备 10 个 CPU 指标)
生成耗时:~2.3s
2.5 阶段二:数据写入
./bin/tsbs_load_kwdb \
--file=data.dat \
--user=root --pass=1234 \
--host=127.0.0.1 --port=26257 \
--insert-type=insert \
--batch-size=10000 \
--db-name=benchmark \
--case=cpu-only \
--workers=4 \
--partition=false
写入结果:
loaded 8640000 metrics in 1.847sec with 4 workers
(mean rate 4678000.00 metrics/sec)
loaded 864000 rows in 1.847sec with 4 workers
(mean rate 467800.00 rows/sec)
2.6 阶段三:查询测试
# 生成查询
./bin/tsbs_generate_queries \
--format=kwdb \
--use-case="cpu-only" \
--seed=123 \
--scale=100 \
--query-type="double-groupby-5" \
--queries=1000 \
--timestamp-start="2026-01-01T08:00:00Z" \
--timestamp-end="2026-01-05T00:00:01Z" \
--db-name=benchmark > query.dat
# 执行查询
./bin/tsbs_run_queries_kwdb \
--file=query.dat \
--user=root --pass=1234 \
--host=127.00.1 --port=26257 \
--query-type="double-groupby-5" \
--workers=4
查询结果:
After 1000 queries with 4 workers:
Interval query rate: 461.73 queries/sec
Overall query rate: 420.81 queries/sec
KWDB mean of 5 metrics, all hosts, random 12h0m0s by 1h:
min: 5.18ms, med: 9.01ms, mean: 9.43ms, max: 44.25ms
三、参数扫描实验:workers 与 batch-size 调优曲线
3.1 实验设计
固定参数:
scale=100(100 台设备)log-interval=10stimestamp-start/end:1 天数据insert-type=insert
扫描参数:
workers:1, 2, 4, 8, 12, 16batch-size:1000, 5000, 10000, 20000, 50000
3.2 写入吞吐曲线(metrics/sec)
写入吞吐(百万 metrics/sec)
2.0 │ ★ workers=8
1.8 │ ●─────●─────●─────●─────●
1.6 │ ●─────●─────●─────●─────●
1.4 │ ●─────●─────●─────●─────●
1.2 │ ●─────●─────●─────●─────●
1.0 │ ●─────●─────●─────●─────●
0.8 │
0.6 │
0.4 │
0.2 │
0.0 └─────┬─────┬─────┬─────┬─────┬
1000 5000 10000 20000 50000
batch-size
★ workers=1 ● workers=2 ■ workers=4
▲ workers=8 ◆ workers=12 ◇ workers=16
| workers | batch=1000 | batch=5000 | batch=10000 | batch=20000 | batch=50000 |
|---|---|---|---|---|---|
| 1 | 125,000 | 280,000 | 320,000 | 340,000 | 345,000 |
| 2 | 240,000 | 520,000 | 580,000 | 620,000 | 630,000 |
| 4 | 380,000 | 850,000 | 1,200,000 | 1,350,000 | 1,380,000 |
| 8 | 420,000 | 1,100,000 | 1,680,000 | 1,850,000 | 1,920,000 |
| 12 | 380,000 | 1,050,000 | 1,520,000 | 1,750,000 | 1,800,000 |
| 16 | 320,000 | 920,000 | 1,350,000 | 1,580,000 | 1,620,000 |
关键发现:
- batch-size 拐点:batch-size 从 1000 提升到 10000 时,吞吐提升显著(约 3-4 倍);但超过 20000 后提升趋缓
- workers 拐点:workers=8 时达到峰值,workers=12 开始下降(上下文切换开销)
- 最优配置:workers=8, batch-size=20000,吞吐 1,850,000 metrics/sec
3.3 查询延迟曲线(double-groupby-5)
查询延迟(ms)
12 │ ◆ workers=12
10 │ ●─────●
8 │ ●─────●─────●─────●─────●
6 │
4 │
2 │
0 └─────┬─────┬─────┬─────┬─────┬
1 2 4 8 12 16
workers 数量
● mean (ms) ■ median (ms) ▲ stddev
| workers | min (ms) | median (ms) | mean (ms) | max (ms) | stddev |
|---|---|---|---|---|---|
| 1 | 5.18 | 9.01 | 9.43 | 44.25 | 2.85 |
| 2 | 4.92 | 8.35 | 8.67 | 38.12 | 2.41 |
| 4 | 4.75 | 7.89 | 8.12 | 32.58 | 2.03 |
| 8 | 5.01 | 8.45 | 8.98 | 41.23 | 2.67 |
| 12 | 6.23 | 10.12 | 11.35 | 58.74 | 3.89 |
关键发现:
- 延迟最低点:workers=4 时 mean=8.12ms,并非 workers 越多越好
- stddev 解读:workers=12 时 stddev=3.89,说明并发竞争导致延迟波动增大
- 超配并发不升反降:workers=8 时延迟已回升,workers=12 时显著恶化
四、结果解读:拐点、波动与不理想的数据点
4.1 写入侧:为什么 workers=16 比 workers=8 慢?
根因分析:
- CPU 核心数限制:测试机仅 4 核,workers=8 时已超配(每个核心 2 个 worker)
- 上下文切换开销:workers=16 时,CPU 时间大量消耗在线程切换,而非实际写入
- 锁竞争:KWDB 的写入管道存在锁竞争,过高并发反而降低 throughput
建议:workers 数 ≈ CPU 核心数 × 2,不宜超过核心数 × 4
4.2 查询侧:为什么 stddev 在 workers=12 时飙升?
根因分析:
- 连接池竞争:KWDB 默认连接池有限,高并发查询导致排队
- 查询类型差异:
double-groupby-5涉及多字段聚合,不同查询的数据扫描量差异大 - GC 影响:Go runtime 的 GC 在高并发时更频繁,导致延迟毛刺
建议:
- 生产环境查询并发控制在 workers=4~6
- 对延迟敏感的场景,使用连接池预热
4.3 不理想的"诚实"数据点
| 配置 | 写入吞吐 | 查询 mean | 问题 |
|---|---|---|---|
| workers=1, batch=1000 | 125,000 | 9.43ms | 资源利用率低 |
| workers=16, batch=1000 | 320,000 | - | 上下文切换严重 |
| workers=12, batch=50000 | 1,800,000 | 11.35ms | 查询延迟波动大 |
五、与 IoT 场景的差距讨论
5.1 kwdb-tsbs 的局限
目前 kwdb-tsbs 仅支持 cpu-only 场景,存在以下局限:
| 局限 | 影响 |
|---|---|
| 仅 10 个 CPU 指标 | 真实 IoT 场景可能有 50+ 指标 |
| 无乱序数据 | 真实场景存在网络延迟导致的乱序 |
| 无批量补传 | 设备离线后重连会补传历史数据 |
| 无多指标联合查询 | 真实场景常需跨指标关联分析 |
5.2 向社区反馈的需求
基于实测经验,建议 kwdb-tsbs 后续支持:
- IoT 场景完整支持:已部分实现,但查询模板需完善
- 乱序数据注入:支持
outoforder参数控制乱序比例 - 自定义指标数量:支持
--metrics=50等参数 - 批量补传模拟:支持设备离线-重连-补传的数据模式
六、小结:一份"可复现基准报告"应该长什么样
基于本次 kwdb-tsbs 实测,我总结出可复现基准报告的标准模板:
6.1 环境披露
- 硬件型号、CPU/内存/磁盘规格
- 操作系统版本、内核参数
- 数据库版本、部署方式、关键配置
6.2 数据集描述
- 设备数量(scale)、采样间隔、时间跨度
- 总记录数、总指标数、数据文件大小
6.3 测试参数
- workers、batch-size、insert-type 等关键参数
- 参数扫描范围及步长
6.4 结果呈现
- 写入吞吐曲线(metrics/sec、rows/sec)
- 查询延迟分布(min/median/mean/max/stddev)
- 拐点分析与最优配置推荐
6.5 局限与诚实声明
- 与官方数据的差异及原因
- 测试场景的局限性(如仅 cpu-only)
- 未覆盖的场景及后续计划
欢迎 👍点赞✍评论⭐收藏,欢迎指正

评论(0)