news 2026/9/25 17:03:24

immudb 性能测试套件(performance test suite)实战指南:从基准压测到回归门禁

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
immudb 性能测试套件(performance test suite)实战指南:从基准压测到回归门禁
  • 数据库
  • 安全
  • 后端

【免费下载链接】immudb

immudb - immutable database based on zero trust, SQL/Key-Value/Document model, tamperproof, data change history

项目地址:https://gitcode.com/gh_mirrors/im/immudb
点击查看免费下载

导读

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 键含义
CPUTimecpuTime进程累计 CPU 时间(秒)
CPUKernelTimeFractioncpuTimeKernelFraction内核态 CPU 时间占比
VMMvmm虚拟内存用量
RSSrss常驻内存用量
IOBytesRead / IOBytesWriteioBytesRead/ioBytesWrite读/写字节数
IOCallsRead / IOCallsWriteioCallsRead/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 replica
  • Write TX/s async - one sync replica/Write KV/s async - one sync replica
  • Write TX/s sync - no replicas/Write KV/s sync - no replicas
  • Write TX/s sync - one async replica/Write KV/s sync - one async replica
  • Write 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):

配置含义
KeyPopulationWarmup 阶段预置的键总数(当前为 100,000)
ZipfS偏斜度:1.1 ≈ 接近均匀,2.0 ≈ 极强偏斜(大多数读命中顶部约 1% 的键);0 = 退化为均匀分布
ZipfVZipf 分布的 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:

参数默认值说明
-d10s每个测试运行的时长
-s0数据生成器种子
-random-seedfalse为 true 时使用随机种子(从crypto/rand读取 8 字节生成)
-host""InfluxDB 地址 URL
-token""InfluxDB token
-bucketimmudb-tests-resultsInfluxDB 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.json

5.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.05

7.2 参数说明

参数默认值说明
-baseline""基线性能结果 JSON 路径(必填)
-current""当前性能结果 JSON 路径(必填)
-tolerance0.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

项目地址:https://gitcode.com/gh_mirrors/im/immudb
点击查看免费下载

相关推荐

上一篇:Docusaurus 站点构建与部署实战:从 npm run build 到 Vercel 零配置上线
下一篇:Nx 迁移机制实战:自动将 dev.nx.gradle.project-graph 插件升级到 0.1.8

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/25 16:57:30

rkt 容器引擎全解析:pod 原生架构、安全特性与标准兼容性

容器运行时云原生网络 【免费下载链接】rkt [Project ended] rkt is a pod-native container engine for Linux. It is composable, secure, and built on standards. 项目地址: https://gitcode.com/gh_mirrors/rk/rkt 点击查看 免费下载 rkt(发音同 &…

作者头像 李华
网站建设 2026/9/25 16:53:43

写屏障机制原理

写屏障机制原理 1. 核心概念与工作原理 并发 GC 最大的难题不是"如何快",而是"如何对"。当 GC 扫描与用户 goroutine 同时运行时,用户 goroutine 改写指针的瞬间可能让 GC 漏标存活对象。这就需要一种机制——每当用户程序执行指针赋…

作者头像 李华
网站建设 2026/9/25 16:46:40

基于SpringBoot的鲜花在线商城管理系统:技术栈、背景意义与核心代码

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 1. 项目背景与意义 随着互联网和移动支付的普及,线上购物已成为人们日常生活的重要组成部分。鲜花作为一种具有时效性、季节性和情感属性的特殊商品&#x…

作者头像 李华
网站建设 2026/9/25 16:43:07

【2015-04-27】Linux下使用JNI封装调用已经存在的动态静态库

[历史归档] 本文原发布于 cstriker1407.info 个人博客,内容为历史存档,仅供参考。 发布时间: 2015-04-27 | 标题:Linux下使用JNI封装调用已经存在的动态静态库 | 分类: 编程 / java / C &am…

作者头像 李华