golang多数据库性能基准测试工具插件库dbbench的使用
golang多数据库性能基准测试工具插件库dbbench的使用
简介
dbbench
是一个简单的数据库基准测试或压力测试工具。您可以使用内置的简单基准测试或运行自己的查询。
注意:此工具不提供任何保证。请不要在生产数据库上运行它。
示例
$ dbbench postgres --user postgres --pass example --iter 100000
inserts 6.199670776s 61996 ns/op
updates 7.74049898s 77404 ns/op
selects 2.911541197s 29115 ns/op
deletes 5.999572479s 59995 ns/op
total: 22.85141994s
安装
预编译二进制文件
所有主要平台都有可用的二进制文件。不幸的是,这些构建禁用了 cgo
,这意味着不支持 SQLite。
Homebrew
使用 macOS 的 Homebrew 包管理器:
brew install sj14/tap/dbbench
手动安装
也可以使用 go get
安装当前开发快照(不推荐):
go get -u github.com/sj14/dbbench/cmd/dbbench
Docker
docker run ghcr.io/sj14/dbbench:latest
支持的数据库/驱动
数据库 | 驱动 |
---|---|
Cassandra 和兼容数据库(如 ScyllaDB) | github.com/gocql/gocql |
MS SQL 和兼容数据库(暂无内置基准测试) | github.com/denisenkom/go-mssqldb |
MySQL 和兼容数据库(如 MariaDB 和 TiDB) | github.com/go-sql-driver/mysql |
PostgreSQL 和兼容数据库(如 CockroachDB) | github.com/lib/pq |
SQLite3 和兼容数据库 | github.com/mattn/go-sqlite3 |
使用方法
可用子命令:
cassandra|cockroach|mssql|mysql|postgres|sqlite
使用 'subcommand --help' 查看指定命令的所有标志。
所有子命令的通用标志:
--clean 仅清理基准测试数据,例如崩溃后
--iter int 运行多少次迭代(默认 1000)
--noclean 保留基准测试数据
--noinit 不初始化数据库和表,例如仅运行自己的脚本时
--run string 仅运行指定的基准测试,例如 "inserts deletes"(默认 "all")
--script string 要执行的自定义 SQL 文件
--sleep duration 每次单个基准测试后暂停多长时间(有效单位:ns, us, ms, s, m, h)
--threads int 最大绿色线程数(iter >= threads > 0)(默认 25)
--version 打印版本信息
自定义脚本
您可以使用 --script
标志运行自己的 SQL 语句。可以使用自动生成的表。注意文件大小,因为它会完全加载到内存中。
脚本必须包含对您的数据库有效的 SQL 语句。它使用 golang 的模板引擎,使用分隔符 {{
和 }}
。函数使用 call
命令执行,参数在函数名后传递。
基准测试设置
使用 \benchmark
关键字创建新的基准测试,后跟 once
或 loop
。可选参数可以在同一行中添加。
更多信息请参阅使用说明和示例部分。
用法 | 描述 |
---|---|
\benchmark once |
仅执行以下语句(行)一次(例如创建和删除表)。 |
\benchmark loop |
默认模式。循环执行以下语句(行)。依次执行它们,然后开始新的迭代。添加另一个 \benchmark loop 以开始另一组语句的基准测试。 |
\name insert |
为 DB 语句设置自定义名称,将输出而不是行号(insert 是一个示例名称)。 |
语句替换
用法 | 描述 |
---|---|
{{.Iter}} |
迭代计数器。当 \benchmark once 时将返回 1 。 |
{{call .RandInt64}} |
godoc |
{{call .RandInt64N 9999}} |
godoc(9999 是一个示例上限) |
{{call .RandUint64}} |
godoc |
{{call .RandUint64N 9999}} |
godoc(9999 是一个示例上限) |
{{call .RandFloat32}} |
godoc |
{{call .RandFloat64}} |
godoc |
{{call .RandExpFloat64}} |
godoc |
{{call .RandNormFloat64}} |
godoc |
示例
示例 sqlite_bench.sql
文件:
-- 创建表
\benchmark once \name init
CREATE TABLE dbbench_simple (id INT PRIMARY KEY, balance DECIMAL);
-- 插入和删除需要多长时间?
\benchmark loop \name single
INSERT INTO dbbench_simple (id, balance) VALUES({{.Iter}}, {{call .RandInt64}});
DELETE FROM dbbench_simple WHERE id = {{.Iter}};
-- 在单个事务中需要多长时间?
\benchmark loop \name batch
BEGIN TRANSACTION;
INSERT INTO dbbench_simple (id, balance) VALUES({{.Iter}}, {{call .RandInt64}});
DELETE FROM dbbench_simple WHERE id = {{.Iter}};
COMMIT;
-- 删除表
\benchmark once \name clean
DROP TABLE dbbench_simple;
在此脚本中,我们手动创建和删除表,因此我们将传递 --noinit
和 --noclean
标志,否则会为我们创建此默认表:
dbbench sqlite --script scripts/sqlite_bench.sql --iter 5000 --noinit --noclean
输出:
(once) init: 3.404784ms 3404784 ns/op
(loop) single: 10.568390874s 2113678 ns/op
(loop) batch: 5.739021596s 1147804 ns/op
(once) clean: 1.065703ms 1065703 ns/op
total: 16.312319959s
故障排除
错误消息
failed to insert: UNIQUE constraint failed: dbbench_simple.id
描述
之前的数据未被删除(例如因为基准测试被取消)。尝试再次运行相同的命令,但附加 --clean
标志,这将删除旧数据。然后再次运行原始命令。
错误消息
failed to create table: Binary was compiled with 'CGO_ENABLED=0', go-sqlite3 requires cgo to work. This is a stub
描述 目前发布的二进制构建不包含 SQLite 支持。您必须手动编译 dbbench,可以从特定的发布源代码(推荐)或当前的主分支(不推荐)。
开发
以下是一些如何运行不同数据库以及用于测试/开发的等效 dbbench
调用的示例。
Cassandra
docker run --name dbbench-cassandra -p 9042:9042 -d cassandra:latest
dbbench cassandra
CockroachDB
# 端口 8080 是 Web 界面(可选)
docker run --name dbbench-cockroach -d -p 26257:26257 -p 8080:8080 cockroachdb/cockroach:latest start --insecure
dbbench cockroach
Microsoft SQL Server
docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=yourStrong(!)Password' -p 1433:1433 -d microsoft/mssql-server-linux
dbbench mssql -user sa -pass 'yourStrong(!)Password'
MariaDB
docker run --name dbbench-mariadb -p 3306:3306 -d -e MYSQL_ROOT_PASSWORD=root mariadb
dbbench mariadb
MySQL
docker run --name dbbench-mysql -p 3306:3306 -d -e MYSQL_ROOT_PASSWORD=root mysql
dbbench mysql
PostgreSQL
docker run --name dbbench-postgres -p 5432:5432 -d postgres
dbbench postgres --user postgres --pass example
ScyllaDB
docker run --name dbbench-scylla -p 9042:9042 -d scylladb/scylla
dbbench scylla
SQLite
dbbench sqlite
TiDB
git clone https://github.com/pingcap/tidb-docker-compose.git
cd tidb-docker-compose && docker-compose pull
docker-compose up -d
dbbench tidb --pass '' --port 4000
致谢
感谢 Go 的作者以及直接和间接使用的库的作者,特别是驱动程序开发人员。没有你们的工作,这是不可能的。
这个工具高度受到用户 Fale 的代码片段和工具 pgbench 的启发。后来,也受到 MemSQL 的 dbbench 的启发,它之前有这个名称和类似的想法。
更多关于golang多数据库性能基准测试工具插件库dbbench的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang多数据库性能基准测试工具插件库dbbench的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
dbbench - Golang多数据库性能基准测试工具
dbbench 是一个用于对多种数据库进行性能基准测试的Go语言工具库,它支持多种数据库引擎,并提供统一的测试接口。
主要特性
- 支持多种数据库:MySQL、PostgreSQL、SQLite、MongoDB等
- 提供统一的测试接口
- 可自定义测试场景
- 生成详细的性能报告
安装
go get github.com/yourusername/dbbench
基本使用示例
package main
import (
"fmt"
"log"
"github.com/yourusername/dbbench"
_ "github.com/go-sql-driver/mysql"
_ "github.com/lib/pq"
)
func main() {
// 配置要测试的数据库连接
configs := []dbbench.DBConfig{
{
Name: "MySQL",
Driver: "mysql",
DSN: "user:password@tcp(127.0.0.1:3306)/testdb?parseTime=true",
},
{
Name: "PostgreSQL",
Driver: "postgres",
DSN: "postgres://user:password@localhost:5432/testdb?sslmode=disable",
},
}
// 创建测试场景
benchmark := dbbench.NewBenchmark(
dbbench.WithDBConfigs(configs...),
dbbench.WithConcurrency(10), // 并发数
dbbench.WithDuration(30), // 测试持续时间(秒)
dbbench.WithWarmup(5), // 预热时间(秒)
)
// 添加测试用例
benchmark.AddTest("SELECT_1", "SELECT 1")
benchmark.AddTest("INSERT_TEST", "INSERT INTO test_table(name, value) VALUES(?, ?)", "test", 123)
benchmark.AddTest("SELECT_TEST", "SELECT * FROM test_table WHERE value > ?", 100)
// 运行基准测试
results, err := benchmark.Run()
if err != nil {
log.Fatal(err)
}
// 打印结果
for _, result := range results {
fmt.Printf("\n=== Database: %s ===\n", result.DBName)
for _, test := range result.Tests {
fmt.Printf("Test: %s\n", test.Name)
fmt.Printf(" Queries: %d\n", test.Queries)
fmt.Printf(" Duration: %v\n", test.Duration)
fmt.Printf(" QPS: %.2f\n", test.QPS)
fmt.Printf(" Avg Latency: %v\n", test.AvgLatency)
fmt.Printf(" Min Latency: %v\n", test.MinLatency)
fmt.Printf(" Max Latency: %v\n", test.MaxLatency)
fmt.Printf(" Errors: %d\n", test.Errors)
}
}
}
高级功能
自定义测试函数
benchmark.AddCustomTest("CUSTOM_TEST", func(db *sql.DB) error {
// 执行复杂的测试逻辑
_, err := db.Exec("CREATE TEMPORARY TABLE IF NOT EXISTS temp_test (id INT)")
if err != nil {
return err
}
for i := 0; i < 100; i++ {
_, err = db.Exec("INSERT INTO temp_test VALUES(?)", i)
if err != nil {
return err
}
}
return nil
})
结果导出
// 导出为JSON
err := dbbench.ExportToJSON(results, "results.json")
if err != nil {
log.Fatal(err)
}
// 导出为CSV
err = dbbench.ExportToCSV(results, "results.csv")
if err != nil {
log.Fatal(err)
}
可视化报告
// 生成HTML报告
err := dbbench.GenerateHTMLReport(results, "report.html")
if err != nil {
log.Fatal(err)
}
最佳实践
- 预热数据库:确保测试前数据库已经预热,避免冷启动影响结果
- 适当并发:根据实际应用场景设置合理的并发数
- 多次测试:进行多次测试取平均值,减少偶然性
- 环境隔离:测试环境应与生产环境尽可能相似
- 监控资源:测试时监控数据库服务器的CPU、内存、IO等资源使用情况
注意事项
- 测试前确保数据库已正确配置并可以连接
- 对于写操作测试,建议使用测试专用数据库或定期清理测试数据
- 长时间运行的测试要注意数据库连接池的配置
dbbench 提供了灵活的配置选项和丰富的测试功能,可以帮助开发者全面评估不同数据库在特定场景下的性能表现。