警告
本文最后更新于 2024-04-09,文中内容可能已过时。
Sysbench 是一个开源的多线程性能测试工具。它提供了一系列的测试用例,用户可以通过命令行参数自定义测试的各种方面,如线程数、测试时长、数据大小等。
Sysbench 内置了一些基本的测试模式,如CPU、内存和I/O性能测试,以及针对MySQL和PostgreSQL的数据库测试。但是,当这些内置测试不足以满足用户的特定需求时,Lua 脚本就显得尤为重要。通过编写Lua脚本,用户可以创建完全定制的测试案例,从而获得更精确和相关的性能指标。
用简短的时间了解些lua语法:https://www.runoob.com/lua/lua-tutorial.html
编写 sysbench 的 lua 脚本主要工作就是实现如下6个函数,主要实现prepare、event、cleanup即可
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| function init()
print("init ...")
end
-- sysbench preapre 阶段
function prepare()
print("prepare ...")
end
-- sysbench cleanup 阶段
function cleanup()
print("clenup ...")
end
-- sysbench run 阶段,分成3部分,主要逻辑在event中实现,init 和 done 可以用来做数据准备和计算、数据库连接与断开
function thread_init()
print("thread init ...")
end
function event()
print("event ...")
end
function thread_done()
print("thread done ...")
end
|
执行 sysbench prepare
1
2
3
4
5
| #( 04/10/24@ 2:55下午 )( root@MacBook-Pro ):~/code/cpp/sysbench@heads/1.0.20✗✗✗
sysbench demo.lua --mysql-host=127.0.0.1 --time=1 --report-interval=1 --mysql-port=4000 --mysql-userroot --mysql-passwordroot --mysql-db=b --table-size=100 --tables=1 --threads=1 prepare
sysbench 1.0.20 (using system LuaJIT 2.1.0-beta3)
prepare ... # 这里对应 function prepare()
|
执行 sysbench run
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
| #( 04/10/24@ 2:55下午 )( root@MacBook-Pro ):~/code/cpp/sysbench@heads/1.0.20✗✗✗
sysbench demo.lua --mysql-host=127.0.0.1 --time=1 --report-interval=1 --mysql-port=4000 --mysql-userroot --mysql-passwordroot --mysql-db=b --table-size=100 --tables=1 --threads=1 run
sysbench 1.0.20 (using system LuaJIT 2.1.0-beta3)
init ... # 这里对应 function init()
Running the test with following options:
Number of threads: 1
Report intermediate results every 1 second(s)
Initializing random number generator from current time
Initializing worker threads...
thread init ... # 这里对应 function thread_init()
Threads started!
event ... # 这里对应 function event()
event ...
... ...
event ...
event ...
thread done ... # 这里对应 function thread_done()
General statistics:
total time: 1.0006s
total number of events: 680596
Latency (ms):
min: 0.00
avg: 0.00
max: 0.98
95th percentile: 0.00
sum: 835.41
Threads fairness:
events (avg/stddev): 680596.0000/0.00
execution time (avg/stddev): 0.8354/0.00
|
执行 sysbench cleanup
1
2
3
4
5
| #( 04/10/24@ 2:55下午 )( root@MacBook-Pro ):~/code/cpp/sysbench@heads/1.0.20✗✗✗
sysbench demo.lua --mysql-host=127.0.0.1 --time=1 --report-interval=1 --mysql-port=4000 --mysql-userroot --mysql-passwordroot --mysql-db=b --table-size=100 --tables=1 --threads=1 cleanup
sysbench 1.0.20 (using system LuaJIT 2.1.0-beta3)
clenup ... # 这里对应 function cleanup()
|
当然如果你有一些自定义参数,也可以通过如下方式声明,string、number、boolean都可以,这样就可以在上面的五个函数中使用
1
2
3
4
5
6
7
8
9
10
11
12
| sysbench.cmdline.options = {
table_size = {"Number of rows per table", 10000},
create_secondary = {"Create a secondary index in addition to the PRIMARY KEY", true},
mysql_storage_engine = {"Storage engine, if MySQL is used", "innodb"},
-- ...
}
-- ...
function event()
print(sysbench.opt.table_size) -- 使用自定义命令行参数
end
|
当然 sysbenc 也提供了一些库函数、类型,我们可以直接使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
| -- 一些随机函数
function sysbench.rand.uniform_uint64()
function sysbench.rand.default(a, b)
function sysbench.rand.uniform(a, b)
function sysbench.rand.gaussian(a, b)
function sysbench.rand.special(a, b)
function sysbench.rand.pareto(a, b)
function sysbench.rand.unique()
function sysbench.rand.string(fmt)
function sysbench.rand.uniform_double()
-- 数据库驱动
function sysbench.sql.driver(driver_name)
-- 连接数据库(上面函数执行后返回值可以调动的方法)
local driver_methods = {}
function driver_methods.connect(self)
-- 数据库操作(上面函数执行后返回值可以调动的方法)
local connection_methods = {}
function connection_methods.disconnect(self)
function connection_methods.reconnect(self)
function connection_methods.check_error(self, rs, query)
function connection_methods.query(self, query)
function connection_methods.bulk_insert_init(self, query)
function connection_methods.bulk_insert_next(self, val)
function connection_methods.bulk_insert_done(self)
function connection_methods.prepare(self, query)
function connection_methods.query_row(self, query)
-- 数据库查询结果(执行query后返回值可以调用的方法)
local result_methods = {}
function result_methods.fetch_row(self)
function result_methods.free(self)
-- ...
|
下面看个简单的例子,来自官方 bulk_insert.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
| #!/usr/bin/env sysbench
-- sysbench prepare 阶段,灌数据
function prepare()
local i
local drv = sysbench.sql.driver()
local con = drv:connect() -- 连接数据库
for i = 1, sysbench.opt.threads do
print("Creating table 'sbtest" .. i .. "'...") -- 创建表
con:query(string.format([[
CREATE TABLE IF NOT EXISTS sbtest%d (
id INTEGER NOT NULL,
k INTEGER DEFAULT '0' NOT NULL,
PRIMARY KEY (id))]], i)) -- 查询数据,对应 function connection_methods.query(self, query)
end
end
-- sysbench run 阶段,准备工作
function thread_init()
drv = sysbench.sql.driver() -- 连接数据库
con = drv:connect()
end
-- sysbench run 阶段,收尾工作
cursize=0
function event()
if (cursize == 0) then
con:bulk_insert_init("INSERT INTO sbtest" .. thread_id+1 .. " VALUES") -- function connection_methods.bulk_insert_init(self, query)
end
cursize = cursize + 1
con:bulk_insert_next("(" .. cursize .. "," .. cursize .. ")") -- 写入数据,function connection_methods.bulk_insert_next(self, val)
end
-- sysbench run 阶段,收尾工作
function thread_done(thread_9d)
con:bulk_insert_done() -- function connection_methods.bulk_insert_done(self)
con:disconnect() -- 断开数据库连接
end
-- sysbench cleanup 阶段,清理数据
function cleanup()
local i
local drv = sysbench.sql.driver()
local con = drv:connect()
for i = 1, sysbench.opt.threads do
print("Dropping table 'sbtest" .. i .. "'...")
con:query("DROP TABLE IF EXISTS sbtest" .. i )
end
end
|
1
2
3
4
5
6
7
8
| -- prepare
sysbench /usr/local/share/sysbench/bulk_insert.lua --mysql-host=127.0.0.1 --time=60 --report-interval=1 --mysql-port=3306 --mysql-user=root --mysql-password=123456 --mysql-db=a --table-size=100 --tables=4 --threads=4 prepare
-- run
sysbench /usr/local/share/sysbench/bulk_insert.lua --mysql-host=127.0.0.1 --time=60 --report-interval=1 --mysql-port=3306 --mysql-user=root --mysql-password=123456 --mysql-db=a --table-size=100 --tables=4 --threads=4 run
-- cleanup
sysbench /usr/local/share/sysbench/bulk_insert.lua --mysql-host=127.0.0.1 --time=60 --report-interval=1 --mysql-port=3306 --mysql-user=root --mysql-password=123456 --mysql-db=a --table-size=100 --tables=4 --threads=4 cleanup
|