Sysbench性能测试¶
sysbench(github) 是基于LuaJIT的一个脚本化多线程性能测试工具。通常用于测试数据库性能,但是也可以创建抽象的负载用于测试多种场景:
oltp_*.lua
一系列OLTP类的数据库压测fileio
文件系统层对压测cpu
简单的CPU压测memory
内存访问压测threads
基于线程的调度器压测mutex
一个POSIX mutex压测
备注
我在 HPE DL360 BIOS升级 前后采用sysbench进行性能测试,以观察BIOS升级对性能的影戏
安装(旧方法归档)¶
在Ubuntu上可以直接安装:
sudo apt install sysbench
在CentOS或者Fedora,需要使用EPEL仓库安装:
sudo yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
然后执行:
sudo yum install sysbench
安装¶
sysbench现在提供了二进制安装仓库方法,通过 packagecloud ,可以直接针对不同操作系统进行安装
Debian/Ubuntu:
curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.deb.sh | sudo bash
sudo apt -y install sysbench
RHEL/CentOS:
curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.rpm.sh | sudo bash
sudo yum -y install sysbench
Fedora:
curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.rpm.sh | sudo bash
sudo dnf -y install sysbench
Arch Linux:
sudo pacman -Suy sysbench
macOS:
# Add --with-postgresql if you need PostgreSQL support
brew install sysbench
对于没有在官方列表中列出的操作系统,但是实际上是兼容的,例如aliOS就是兼容CentOS,可以采用先检查 packagecloud os distro version 然后通过环境变量指定系统:
wget https://packagecloud.io/install/repositories/akopytov/sysbench/script.rpm.sh
os=el dist=7 ./script.rpm.sh
sudo yum -y install sysbench
使用¶
测试 fileio
¶
当使用 fileio
,需要创建一个测试文件,建议文件大小大于可用内存,这样缓存不会过多影响测试负载:
sysbench fileio --file-total-size=8G prepare
sysbench fileio --file-total-size=8G --file-test-mode=rndrw --time=300 --max-requests=0 run
sysbench fileio --file-total-size=8G cleanup
这里可以指定不同的读写模式,例如上面采用了 rndrw
表示随机读写, --max-time
指定测试时间
输出结果如下
sysbench 1.0.18 (using system LuaJIT 2.1.0-beta3)
Running the test with following options:
Number of threads: 1
Initializing random number generator from current time
Extra file open flags: (none)
128 files, 64MiB each
8GiB total file size
Block size 16KiB
Number of IO requests: 0
Read/Write ratio for combined random IO test: 1.50
Periodic FSYNC enabled, calling fsync() each 100 requests.
Calling fsync() at the end of test, Enabled.
Using synchronous I/O mode
Doing random r/w test
Initializing worker threads...
Threads started!
File operations:
reads/s: 1446.84
writes/s: 964.56
fsyncs/s: 3086.64
Throughput:
read, MiB/s: 22.61
written, MiB/s: 15.07
General statistics:
total time: 300.0293s
total number of events: 1649469
Latency (ms):
min: 0.00
avg: 0.18
max: 25.45
95th percentile: 0.86
sum: 298910.93
Threads fairness:
events (avg/stddev): 1649469.0000/0.00
execution time (avg/stddev): 298.9109/0.00
测试 cpu
¶
在 CPU 工作负载下运行时,sysbench 将通过将数字标准除以 2 和数字平方根之间的所有数字来验证素数。 如果任何数字的余数为 0,则计算下一个数字。 可以想象,这会给 CPU 带来一些压力,但仅限于一组非常有限的 CPU 功能。
测试命令:
sysbench cpu --cpu-max-prime=20000 --threads=48 run
输出结果:
sysbench 1.0.18 (using system LuaJIT 2.1.0-beta3)
Running the test with following options:
Number of threads: 48
Initializing random number generator from current time
Prime numbers limit: 20000
Initializing worker threads...
Threads started!
CPU speed:
events per second: 12371.95
General statistics:
total time: 10.0037s
total number of events: 123788
Latency (ms):
min: 2.93
avg: 3.87
max: 59.82
95th percentile: 3.82
sum: 479410.29
Threads fairness:
events (avg/stddev): 2578.9167/20.19
execution time (avg/stddev): 9.9877/0.02
备注
sysbench执行CPU测试是纯计算,也就是全部是 user space
运行,没有任何 system calls
,所以和真实的生产环境压力有很大不同。真实环境的CPU计算会涉及大量的 system calls
所以CPU资源很大部分被 sys
吃掉了。
测试线程工作负载¶
对于线程工作负载,每个工作线程都将被分配一个互斥锁(一种锁),并且对于每次执行,将循环多次(记录为产量),其中获取锁,产量(意味着它 要求调度程序停止运行并将其放回运行队列的末尾),然后,当它再次被调度执行时,解锁。
通过调整各种参数,可以模拟具有相同锁的高并发线程,或具有多个不同锁的高并发线程等情况。
sysbench threads --thread-locks=1 --time=20 run
输出结果:
sysbench 1.0.18 (using system LuaJIT 2.1.0-beta3)
Running the test with following options:
Number of threads: 1
Initializing random number generator from current time
Initializing worker threads...
Threads started!
General statistics:
total time: 20.0005s
total number of events: 34340
Latency (ms):
min: 0.58
avg: 0.58
max: 1.89
95th percentile: 0.59
sum: 19994.57
Threads fairness:
events (avg/stddev): 34340.0000/0.00
execution time (avg/stddev): 19.9946/0.00
测试mutex工作负载¶
使用互斥量工作负载时,sysbench 应用程序将为每个线程运行一个请求。 这个请求首先会给 CPU 带来一些压力(使用一个简单的增量循环,通过 --mutex-loops
参数),然后它需要一个随机互斥锁(锁),增加一个全局变量并再次释放锁。 这个过程会重复几次,由锁的数量( --mutex-locks
)标识。 随机互斥锁取自 --mutex-num
参数确定大小的池。
sysbench mutex --threads=1024 run
输出结果:
sysbench 1.0.18 (using system LuaJIT 2.1.0-beta3)
Running the test with following options:
Number of threads: 1024
Initializing random number generator from current time
Initializing worker threads...
Threads started!
General statistics:
total time: 8.6381s
total number of events: 1024
Latency (ms):
min: 723.37
avg: 6191.90
max: 8074.94
95th percentile: 7346.49
sum: 6340509.18
Threads fairness:
events (avg/stddev): 1.0000/0.00
execution time (avg/stddev): 6.1919/1.09
这里输出结果中,运行时间长度最为关键,尽管必须考虑到线程将从可用池中随机获取一个互斥锁。 这个随机因素可能会影响结果。
测试内存工作负载¶
在 sysbench 中使用内存测试时,基准应用程序会分配一个内存缓冲区,然后从中读取或写入,每次为一个指针的大小(即 32 位或 64 位),每次执行直到读取了总缓冲区大小 从或写到。 然后重复此操作,直到达到提供的容量 ( --memory-total-size
)。 用户可以提供多线程( --threads
)、不同大小的缓冲区( --memory-block-size
)和请求类型(读或写,顺序或随机)。
sysbench memory --threads=1024 run
输出结果:
sysbench 1.0.18 (using system LuaJIT 2.1.0-beta3)
Running the test with following options:
Number of threads: 1024
Initializing random number generator from current time
Running memory speed test with the following options:
block size: 1KiB
total size: 102400MiB
operation: write
scope: global
Initializing worker threads...
Threads started!
Total operations: 72038066 (7199519.63 per second)
70349.67 MiB transferred (7030.78 MiB/sec)
General statistics:
total time: 10.0040s
total number of events: 72038066
Latency (ms):
min: 0.00
avg: 0.10
max: 484.01
95th percentile: 0.01
sum: 7182912.42
Threads fairness:
events (avg/stddev): 70349.6738/26210.63
execution time (avg/stddev): 7.0146/2.18
MySQL数据库测试(待实践)¶
创建一个test表包含 1,000,000 行数据:
sysbench --test=oltp --oltp-table-size=1000000 --db-driver=mysql --mysql-db=test --mysql-user=root --mysql-password=yourrootsqlpassword prepare
性能测试:
sysbench --test=oltp --oltp-table-size=1000000 --db-driver=mysql --mysql-db=test --mysql-user=root --mysql-password=yourrootsqlpassword --max-time=60 --oltp-read-only=on --max-requests=0 --num-threads=8 run