- 数据库
- 安全
- 后端
【免费下载链接】immudb
immudb - immutable database based on zero trust, SQL/Key-Value/Document model, tamperproof, data change history
导读
immudb 性能测试套件(test/performance-test-suite)是 immudb 项目自带的性能分析工具,用于在各种真实工作负载下检验 immudb 的性能表现。它由两大部分组成:负责压测与结果输出的perf-test(读写基准生成器 + 运行器),以及负责基准对比与回归门禁的perf-delta(增量对比工具)。阅读本文后,你将掌握如何构建并运行短/长两种性能测试、如何解析 JSON 结果的时间线与汇总数据、如何配置 InfluxDB 集中存储结果,以及如何利用perf-delta在 CI 中自动拦截性能回归。
一、套件定位与整体架构
该套件是 immudb 的主要性能分析工具,其核心目标是用真实世界负载(而非微基准)检验 immudb 的性能。从源码结构看,它由三个层级组成:
test/performance-test-suite/ ├── cmd/ │ ├── perf-test/ # 压测入口:执行全部基准并输出 JSON 结果 │ │ └── main.go │ └── perf-delta/ # 对比两个 JSON 结果,报告性能增量/回归 │ ├── main.go │ └── main_test.go └── pkg/ ├── benchmarks/ # 基准抽象与通用工具 │ ├── benchmark.go # Benchmark 接口 │ ├── format.go # 数值格式化 │ ├── hwstats.go # 硬件/系统统计采集 │ ├── keytracker.go # 键生成器(含 Zipf 分布) │ ├── rand.go # 随机字符串生成器 │ ├── readtxs/ # 读基准(Get/s) │ │ └── benchmark.go │ └── writetxs/ # 写基准(TX/s、KV/s) │ └── benchmark.go └── runner/ # 运行调度、结果结构、系统信息与 InfluxDB 上报 ├── benchmarks.go ├── influxdb_client.go ├── processinfo.go ├── results.go ├── runner.go └── systeminfo.go套件由perf-test入口驱动:runner.RunAllBenchmarks依次执行注册在 getBenchmarksToRun 中的基准,最终通过BenchmarkSuiteResult结构输出到 stdout,形成一份 JSON 报告(详见后文“输出格式”)。
二、短测试与长测试(Long vs short run)
README 明确指出:测试规模是可配置的,套件区分两种运行模式:
| 模式 | 定位 | 使用场景 |
|---|---|---|
| 短测试(short) | 快速性能测试 | 每次 immudb push 到 master 分支时执行 |
| 长测试(long) | 完整性能回归测试 | 每个 release 发布前必须执行,确保无性能回退 |
默认模式是短性能测试。两种模式在代码层面的差异体现在运行时长参数-d上:perf-test的-d标志控制每个基准的持续时长,默认值为 10 秒(main.go)。CI 与发布流程只需要传入不同的时长即可切换模式。
一个值得注意的工程细节:写基准的Run方法通过time.After(duration)与done通道协同,在时间到点后优雅关闭所有 worker goroutine(见 writetxs/benchmark.go),避免Cleanup与仍在途的SetAll调用产生竞态——这也是从源码中可以观察到的稳定性设计。
三、输出格式:时间线 + 汇总 + 系统元数据
README 说明:套件产生一个包含性能详细信息的 JSON 输出文件,内容包括:
- 整个测试期间的各项测量时间线(timeline);
- 汇总(summary);
- 尽可能采集的底层系统元数据,用于不同系统之间的对比。
3.1 JSON 顶层结构
顶层结构由 results.go 中的BenchmarkSuiteResult定义:
{ "startTime": "...", "endTime": "...", "duration": "...", "processInfo": { "commandLine": [], "version": "", "gitCommit": "", "builtBy": "", "builtAt": "" }, "systemInfo": { "hostname": "" }, "benchmarks": [ { "name": "Write TX/s async - no replicas", "summary": "TX: 1234, KV: 1234, TX/s: 123.45, KV/S: 12345.67", "startTime": "...", "endTime": "...", "duration": "...", "requestedDuration": "...", "results": { "txTotal": 1234, "kvTotal": 1234, "txs": 123.45, "kvs": 12345.67, "hwStats": { } }, "timeline": [ { "time": "...", "duration": "...", "probe": { } } ] } ] }3.2 时间线(Timeline)与探针(Probe)
每个基准运行期间,runner.RunAllBenchmarks会启动一个每秒触发一次的探针 goroutine,周期性调用Benchmark.Probe()并记录BenchmarkTimelineEntry(runner.go)。时间线条目由 results.go 定义:
time:探针采集时刻;duration:距离基准启动的累计时长;probe:该时刻的瞬时性能快照。
以写基准为例,探针返回的Result除了累计的TxTotal/KvTotal与平均Txs/Kvs之外,还会计算自上次探针以来的瞬时速率TxsInst/KvsInst(见 writetxs/benchmark.go)。因此,时间线能反映性能随时间的波动(例如冷启动、缓存升温、副本复制压力等),而不仅是最终平均速率。
3.3 系统元数据
BenchmarkSuiteResult同时携带processInfo(命令行、版本、Git 提交、构建者、构建时间,来自 processinfo.go)与systemInfo(主机名,来自 systeminfo.go)。硬件统计由 hwstats.go 通过 Prometheusprocfs库采集,HWStats字段包含:
| 字段 | JSON 键 | 含义 |
|---|---|---|
| CPUTime | cpuTime | 进程累计 CPU 时间(秒) |
| CPUKernelTimeFraction | cpuTimeKernelFraction | 内核态 CPU 时间占比 |
| VMM | vmm | 虚拟内存用量 |
| RSS | rss | 常驻内存用量 |
| IOBytesRead / IOBytesWrite | ioBytesRead/ioBytesWrite | 读/写字节数 |
| IOCallsRead / IOCallsWrite | ioCallsRead/ioCallsWrite | 读/写系统调用次数 |
这些元数据正是“用于不同系统之间对比”的基础——同一版本在不同硬件上的结果可以通过 CPU/内存/IO 指标解释差异。
3.4 时间戳序列化为人类可读格式
runner.Duration是time.Duration的包装类型,其MarshalJSON将纳秒级时长序列化为 Go 的time.Duration字符串(如"10s"、"1m2.3s"),保证 JSON 可读且可直接比较(results.go)。
四、基准集合:写路径与读路径
getBenchmarksToRun返回的基准集合分为写与读两大阵营(benchmarks.go)。
4.1 写基准(writetxs)
写基准通过writetxs.Config配置,覆盖 TX/s 与 KV/s 两个度量维度、同步/异步写两种模式、以及无副本/一个异步副本/一个同步副本三种拓扑:
| 配置 | 含义 |
|---|---|
Workers | 并发客户端数量(套件固定为 30) |
BatchSize | 每个SetAll请求携带的 KV 数(1 = 单 KV 事务,1000 = 批量) |
KeySize | 键长度(默认 32,键由sha256生成后截断) |
ValueSize | 值长度(默认 128,随机字符串) |
AsyncWrite | 是否异步写(NoWait标志,对应schema.SetRequest.NoWait) |
Replica | 空 /"async"/"sync",决定是否拉起副本及复制模式 |
由此组合出的基准名称包括:
Write TX/s async - no replicas(30 workers、batch=1、异步、无副本)Write KV/s async - no replicas(30 workers、batch=1000、异步、无副本)Write TX/s async - one async replica/Write KV/s async - one async replicaWrite TX/s async - one sync replica/Write KV/s async - one sync replicaWrite TX/s sync - no replicas/Write KV/s sync - no replicasWrite TX/s sync - one async replica/Write KV/s sync - one async replicaWrite TX/s sync - one sync replica/Write KV/s sync - one sync replica
其中“同步复制 + 1 个同步 ACK”(WithSyncReplication(true).WithSyncAcks(1))与“异步复制”分别对应 replication 管线中的不同提交语义。每个写基准在Warmup阶段会以嵌入式方式就地启动一个 immudb 服务(server.DefaultOptions()+WithPort(0)随机端口,并关闭 Web/Metrics/PgSQL 端口),随后为每个 worker 打开一个客户端会话(writetxs/benchmark.go)。复制拓扑则由一个指向主库的副本服务实现,副本选项包含PrimaryHost、PrimaryPort、PrefetchTxBufferSize=1000、ReplicationCommitConcurrency=30等。
4.2 读基准(readtxs)
读基准是写基准的读侧对偶,模拟现实工作负载的局部性。其配置包含KeyPopulation(预热键总数)与 Zipf 分布参数ZipfS/ZipfV(readtxs/benchmark.go):
| 配置 | 含义 |
|---|---|
KeyPopulation | Warmup 阶段预置的键总数(当前为 100,000) |
ZipfS | 偏斜度:1.1 ≈ 接近均匀,2.0 ≈ 极强偏斜(大多数读命中顶部约 1% 的键);0 = 退化为均匀分布 |
ZipfV | Zipf 分布的 v 参数(当前为 1) |
当前套件内置两个读基准:
Read Get/s zipf (s=1.5) - 100k key population:热集行为——少数“热键”占据大部分读流量,贴近真实负载;Read Get/s uniform - 100k key population:缓存最差情况——每次读都可能未命中。
readtxs包注释明确指出:均匀随机读会掩盖缓存与索引效应,而热集读则相反;两者共享同一KeyPopulation,保证内部存储的驻留集压力可比。在Warmup阶段,读基准会用首个客户端以每批 1000 个键的方式预置 10 万键(分批是为了保持在MaxTxEntries限制内),随后在Run阶段并发发出Get请求,结果字段为getTotal/gets/getsInstant(readtxs/benchmark.go)。
五、运行性能测试:命令行参数与示例
5.1 perf-test 命令参数
perf-test的命令行参数定义在 cmd/perf-test/main.go:
| 参数 | 默认值 | 说明 |
|---|---|---|
-d | 10s | 每个测试运行的时长 |
-s | 0 | 数据生成器种子 |
-random-seed | false | 为 true 时使用随机种子(从crypto/rand读取 8 字节生成) |
-host | "" | InfluxDB 地址 URL |
-token | "" | InfluxDB token |
-bucket | immudb-tests-results | InfluxDB bucket 名 |
-runner | "" | InfluxDB 上报用的 runner 标识(如 GitHub runner 名) |
-version | "" | InfluxDB 上报用的 immudb 版本号 |
-workdir | /tmp | 工作目录路径(嵌入式服务与客户端临时目录的基目录) |
5.2 运行示例
短测试(默认 10 秒/基准):
cd test/performance-test-suite go run ./cmd/perf-test > results.json固定种子以便结果可复现:
go run ./cmd/perf-test -d 30s -s 42 > results-short-30s.json随机种子 + 长测试(发布前回归检查):
go run ./cmd/perf-test -d 5m -random-seed > results-long.json长测试建议直接重定向保存 JSON:
go run ./cmd/perf-test -d 1h > results-release.json5.3 运行期间的日志输出
runner会输出每个基准的进度与探针快照,格式形如:
Starting immudb performance test suite Running benchmark: Write TX/s async - no replicas [Write TX/s async - no replicas] 5s/10s TX: 1234, KV: 1234, TX/s: 123.45, KV/S: 12345.67 Benchmark Write TX/s async - no replicas finished Results: TX: 1234, KV: 1234, TX/s: 123.45, KV/S: 12345.67 Finished immudb performance test suite其中每秒钟的探针行正是 JSONtimeline的实时体现。
六、结果集中存储:InfluxDB 集成
README 指出:目前性能测试结果仅附加在 CI 输出上,未来规划建立集中存储以长期积累所有结果。不过,代码中已经实现了 InfluxDB 上报通道:只要在命令行同时提供-host、-token、-runner、-version四个参数,perf-test在输出 JSON 后就会调用runner.SendResultsToInfluxDb(cmd/perf-test/main.go)。
上报逻辑位于 influxdb_client.go:它使用官方 influxdb-client-go 创建客户端,向 orgCodenotary、bucket(默认immudb-tests-results)写入performance测量点,每条时间序列携带name(基准名)、runner、version标签,字段包括duration、txTotal/kvTotal/txs/kvs(写基准)、getTotal/gets(读基准)以及共享的硬件统计字段(cpuTime、vmm、rss、IOBytesRead、IOBytesWrite、IOCallsRead、IOCallsWrite)。
示例:
go run ./cmd/perf-test \ -host http://influxdb.example.com:8086 \ -token "$INFLUX_TOKEN" \ -bucket immudb-tests-results \ -runner "github-runner-01" \ -version "v1.4.0"结合 Grafana 等可视化工具(仓库根目录 tools/monitoring/grafana-dashboard.json 提供现成 dashboard),即可把immudb-tests-results中的数据绘制成性能趋势图,逐步向“集中存储 + 长期对比”的目标演进。
七、性能回归门禁:perf-delta 增量对比工具
7.1 用途与用法
perf-delta用于对比两份perf-test生成的 JSON 结果文件,按基准逐一报告 TX/s 与 KV/s 的增量变化;当任一基准的退化幅度超过配置的容差时以非零退出码结束,因此可直接作为 CI 回归门禁使用(perf-delta/main.go)。
go run ./cmd/perf-delta \ -baseline baseline.json \ -current current.json \ -tolerance 0.057.2 参数说明
| 参数 | 默认值 | 说明 |
|---|---|---|
-baseline | "" | 基线性能结果 JSON 路径(必填) |
-current | "" | 当前性能结果 JSON 路径(必填) |
-tolerance | 0.05 | 每个指标允许的最大相对退化比例(0.05 = 5%) |
7.3 输出与退出语义
perf-delta输出稳定的 Markdown 表格,可直接附加到 PR 评论:
| Benchmark | Baseline TX/s | Current TX/s | Δ TX/s | Baseline KV/s | Current KV/s | Δ KV/s | |-----------|--------------:|-------------:|-------:|--------------:|-------------:|-------:| | Write TX/s async - no replicas | 1000.00 | 950.00 | -5.00% ❌ | 50000.00 | 49000.00 | -2.00% |- 当前结果中存在但基线中没有的基准标记为
(new / not in baseline); - 基线中存在但当前缺失的基准标记为
(missing in current)并累计missingCurr; - 任一基准的 TX/s 或 KV/s 退化 ≤
-tolerance(默认 -5%)时标记 ❌ 并计入regressions; - 末尾输出
N regression(s) beyond X% tolerance; M benchmark(s) missing in current.; - 只要存在回归(
regressions > 0),进程以退出码 1 结束,否则正常退出(perf-delta/main.go)。
7.4 关键实现细节
- 增量计算:
delta(base, curr) = (curr - base) / base;基线为 0 时返回 0,避免空基线把所有基准误判为回归或提升(perf-delta/main.go)。 - 前向兼容:工具只解码所需字段(
name、results.txs、results.kvs),对结果格式的新增字段保持稳定(perf-delta/main.go)。 - 测试保障:main_test.go 覆盖了增量计算的边界情形(相同值、±5% 增益/损失、零基线)以及 JSON 加载的成功/失败路径(文件缺失、非法 JSON)。
八、CI 集成建议(组合短测试 + 回归门禁)
将两个工具串联即可实现 README 描述的“push 到 master 即跑短测试”流程:
# 1. 跑短测试并保存结果 go run ./cmd/perf-test -d 10s > current.json # 2. 与上一轮基线的短测试结果对比,5% 容差 go run ./cmd/perf-delta -baseline previous.json -current current.json -tolerance 0.05若上一步返回非零退出码,CI 即标记该 push 存在性能回归。发布前再执行长测试(-d设为小时级)并人工审阅 JSON 时间线与硬件元数据。
九、小结
immudb performance test suite 提供了一个从“压测”到“回归门禁”的完整闭环:
- 短/长双模式:通过
-d调节测试规模,短测试守护日常 push,长测试把关每个 release; - 真实负载建模:30 并发 worker、同步/异步写、无/异步/同步副本拓扑、Zipf 热集读与均匀读,覆盖写入吞吐(TX/s、KV/s)与读取吞吐(Get/s)两大类指标;
- 丰富输出:JSON 同时包含逐秒时间线、汇总、进程/系统元数据与硬件统计,便于跨系统对比;
- 集中存储通道:InfluxDB 上报已就绪,为未来集中结果库和长期趋势分析打下基础;
- 回归门禁:
perf-delta以 Markdown 表格输出增量并以非零退出码拦截超过容差(默认 5%)的性能退化,可直接嵌入 CI。
若需要深入各基准的底层实现(嵌入式服务启动、复制选项、Zipf 键跟踪器),可继续研读 writetxs/benchmark.go、readtxs/benchmark.go 与 runner.go。
- 数据库
- 安全
- 后端
【免费下载链接】immudb
immudb - immutable database based on zero trust, SQL/Key-Value/Document model, tamperproof, data change history
相关推荐
cuML Benchmark Suite 完整指南:从命令行基准测试到 YAML 回归套件
cuML Benchmark Suite 完整指南:从命令行基准测试到 YAML 回归套件 cuML 是 NVIDIA 推出的 GPU 加速机器学习库,其内置的
机器学习高性能计算whichllm 为你的显卡挑出最好的本地大模型
whichllm 为你的显卡挑出最好的本地大模型 whichllm 是一款本地 LLM 推荐工具。你不用自己算显存,也不用逐个翻榜单,它扫一眼你的硬件,就给出该
人工智能大模型本地部署CLIruflo 基准测试套件(Benchmark Suite)Agent 深度解析:性能基准、回归检测与验证框架实战
ruflo 基准测试套件(Benchmark Suite)Agent 深度解析:性能基准、回归检测与验证框架实战 导读 ruflo(原 @claude flow
人工智能AI Agent多智能体Agent 编排Agent 记忆工具调用代码智能体MCP 服务AI 评测
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考