这部分我们将讲授一些基准测试工具的实际例子。当然我们不可能把每个工具都讲到,但是这些示例将有助于你,根据自己的目标来选择合适的基准测试工具。
让我们来看看一些使用http_load的简单示例。以及使用下面的连接,保存到urls.txt中。
http://www.mysqlperformanceblog.com/
http://www.mysqlperformanceblog.com/page/2/
http://www.mysqlperformanceblog.com/mysql-patches/
http://www.mysqlperformanceblog.com/mysql-performance-presentations/
http://www.mysqlperformanceblog.com/2006/09/06/slow-query-log-analyzes-tools/
这是最简单使用http_load的方法,可以循环取出这批URL。程序会尽可能快的运行它们。
$ http_load -parallel 1 -seconds 10 urls.txt
19 fetches, 1 max parallel, 837929 bytes, in 10.0003 seconds
44101.5 mean bytes/connection
1.89995 fetches/sec, 83790.7 bytes/sec
msecs/connect: 41.6647 mean, 56.156 max, 38.21 min
msecs/first-response: 320.207 mean, 508.958 max, 179.308 min
HTTP response codes:
code 200 – 19
结果已经足够的清楚了。简单的显示了这些请求的的统计结果。稍微复杂点的场景是尽快的获取URL,但模拟了5并发用户。
$ http_load -parallel 5 -seconds 10 urls.txt
94 fetches, 5 max parallel, 4.75565e+06 bytes, in 10.0005 seconds
50592 mean bytes/connection
9.39953 fetches/sec, 475541 bytes/sec
msecs/connect: 65.1983 mean, 169.991 max, 38.189 min
msecs/first-response: 245.014 mean, 993.059 max, 99.646 min
HTTP response codes:
code 200 – 94
我们也可以模拟预测的请求率(比如每秒5次)
$ http_load -rate 5 -seconds 10 urls.txt
48 fetches, 4 max parallel, 2.50104e+06 bytes, in 10 seconds
52105 mean bytes/connection
4.8 fetches/sec, 250104 bytes/sec
msecs/connect: 42.5931 mean, 60.462 max, 38.117 min
msecs/first-response: 246.811 mean, 546.203 max, 108.363 min
HTTP response codes:
code 200 – 48
最后,我们模拟更高的负载。大约是每秒20个请求,注意,在高负载的情况下连接和相应是如何增长的。
$ http_load -rate 20 -seconds 10 urls.txt
111 fetches, 89 max parallel, 5.91142e+06 bytes, in 10.0001 seconds
53256.1 mean bytes/connection
11.0998 fetches/sec, 591134 bytes/sec
msecs/connect: 100.384 mean, 211.885 max, 38.214 min
msecs/first-response: 2163.51 mean, 7862.77 max, 933.708 min
HTTP response codes:
code 200 -- 111
sysbench能运行多种基准测试。它常常被称作“测试”了。它不仅仅能测试数据库的性能,也可以测试系统是如何表现的。我们开始一些测试,并不是针对MySQL的以及测量了子系统的性能。这个也决定了整个系统的整体限制。最后我们再来教你怎样测量数据库的性能。
显而易见的子系统测试就是CPU基准测试了。这个基准测试用64位整数计算主要的质数到指定的最大值。我们把这个运行在两个服务器上,环境都是GNU/Linux,以及比较结果。下列是第一个服务器硬件配置:
[server1 ~]$ cat /proc/cpuinfo
...
model name : AMD Opteron(tm) Processor 246
stepping : 1
cpu MHz : 1992.857
cache size : 1024 KB
运行基准测试:
[server1 ~]$ sysbench --test=cpu --cpu-max-prime=20000 run
sysbench v0.4.8: multi-threaded system evaluation benchmark
...
Test execution summary:
total time: 121.7404s
这是第二个服务器的CPU配置:
[server2 ~]$ cat /proc/cpuinfo
...
model name : Intel(R) Xeon(R) CPU 5130 @ 2.00GHz
stepping : 6
cpu MHz : 1995.005
这是这台服务器的结果
[server1 ~]$ sysbench --test=cpu --cpu-max-prime=20000 run
sysbench v0.4.8: multi-threaded system evaluation benchmark
...
Test execution summary:
total time: 61.8596s
这结果简单的显示了需要计算质数所需要的时间。这非常容易比较了。这个例子中,第二个服务器比第一个服务器要快两倍。
fileio基准测试测量了在不同的种类的I/O下系统的表现。这非常有助于比较硬盘,RAID cards,RAID modes,以及调整I/O子系统。
第一个运行测试场景需要准备一些文件。数据量一定要大于内存可存放的数据量。因为内存可以保存数据,那么操作系统会缓存这些数据,以及I/O边界测试就不能反映出正确的结果了。我们来创建一个数据集
$ sysbench --test=fileio --file-total-size=150G prepare
第二步运行基准测试。下列是对于不同类型的I/O性能的参数。
seqwr
连续的写
seqrewr
连续的重写
seqrd
连续的读
rndrd
随机的读
rndwr
随机的写
rndrw
结合随机读和随机写
下列运行了随机读写的命令文件来做I/O基准测试
$ sysbench --test=fileio --file-total-size=150G --file-test-mode=rndrw
--init-rnd=on --max-time=300 --max-requests=0 run
结果如下:
sysbench v0.4.8: multi-threaded system evaluation benchmark
Running the test with following options:
Number of threads: 1
Initializing random number generator from timer.
Extra file open flags: 0
128 files, 1.1719Gb each
150Gb total file size
Block size 16Kb
Number of random requests for random IO: 10000
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
Threads started!
Time limit exceeded, exiting...
Done.
Operations performed: 40260 Read, 26840 Write, 85785 Other = 152885 Total
Read 629.06Mb Written 419.38Mb Total transferred 1.0239Gb (3.4948Mb/sec)
223.67 Requests/sec executed
Test execution summary:
total time: 300.0004s
total number of events: 67100
total time taken by event execution: 254.4601
per-request statistics:
min: 0.0000s
avg: 0.0038s
max: 0.5628s
approx. 95 percentile: 0.0099s
Threads fairness:
events (avg/stddev): 67100.0000/0.00
execution time (avg/stddev): 254.4601/0.00
结果的显示信息非常多,杜宇调整I/O性能而言,每秒请求数(number of requests per second),总的吞吐量(the total throughput)。这个实例中,结果为223.67requests/sec和3.4948 MB/sec。这些值提供了很好的查看硬盘性能的指标。
当完成这些测试,你可以清楚和删除sysbench创建的文件。
$ sysbench --test=fileio –-file-total-size=150G cleanup
sysbench OLTP 基准测试
OLTP模拟了事物处理的负荷。我们展示一个百万级数据表的例子。第一步要准备一个测试表。
$ sysbench --test=oltp --oltp-table-size=1000000 --mysql-db=test --mysql-user=root
prepare
sysbench v0.4.8: multi-threaded system evaluation benchmark
No DB drivers specified, using mysql
Creating table 'sbtest'...
Creating 1000000 records in table 'sbtest'...
数据准备完毕,接着,运行8个并发下,60s内只读的基准测试。
$ sysbench --test=oltp --oltp-table-size=1000000 --mysql-db=test --mysql-user=root --
max-time=60 --oltp-read-only=on --max-requests=0 --num-threads=8 run
sysbench v0.4.8: multi-threaded system evaluation benchmark
No DB drivers specified, using mysql
WARNING: Preparing of "BEGIN" is unsupported, using emulation
(last message repeated 7 times)
Running the test with following options:
Number of threads: 8
Doing OLTP test.
Running mixed OLTP test
Doing read-only test
Using Special distribution (12 iterations, 1 pct of values are returned in 75 pct
cases)
Using "BEGIN" for starting transactions
Using auto_inc on the id column
Threads started!
Time limit exceeded, exiting...
(last message repeated 7 times)
Done.
OLTP test statistics:
queries performed:
read: 179606
write: 0
other: 25658
total: 205264
transactions: 12829 (213.07 per sec.)
deadlocks: 0 (0.00 per sec.)
read/write requests: 179606 (2982.92 per sec.)
other operations: 25658 (426.13 per sec.)
Test execution summary:
total time: 60.2114s
total number of events: 12829
total time taken by event execution: 480.2086
per-request statistics:
min: 0.0030s
avg: 0.0374s
max: 1.9106s
approx. 95 percentile: 0.1163s
Threads fairness:
events (avg/stddev): 1603.6250/70.66
execution time (avg/stddev): 60.0261/0.06
像其他测试一样,结果非常之多。我们感兴趣的指标如下
其他sysbench的特性。
sysbench可以做很多其他的系统基准测试,这些测试都不能直接的测量数据库服务器的性能。
内存(memory)
连续的内存读写。
线程(threads)
测试线程排期(thread scheduler)性能。这个测试对于测试高负载下的排期行为格外有用。
互斥(mutex)
在大部分时间,线程并发的情形下,仅仅获取互斥锁来测量互斥性能。(互斥十一哥数据结果,保证了独自的访问一些资源,避免了并发访问所引起的问题。)
seqwr
测量连续写的性能。这点对于测试系统性能极限是非常重要的。它能显示RAID控制器缓存的表现以及提醒你这个结果是否正常。一个例子,如果你没有后备电源的写缓存,但是你的硬盘每秒完成了3000个请求,可能会有错误,你的数据不安全。
除了--test这个参数之外,sysbench还有其他一些常见参数,如,--num-threads,--max-requests,以及--max-time.详细的看官方文档。
数据库测试套件中的dbt2工具是实现了TPC-C测试并且是免费的。TPC-C是有TPC组织发布的一个模拟复杂的联机事务处理的测试标准。它提供了在每分钟的事物(tpmC)并且这个事物的消耗(Price/tpmC)的报告结果。这个结果依赖于硬件配置,因此这个TPC-C结果包含了服务器的详细的指标。
让我们来看看怎样设置和运行dbt2基准测试的简单示例。我们使用的版本是dbt2 0.37.这个版本常常被我们用作测试MySQL。需要进行的步骤如下:
1。准备数据:
下面的命令准备了在指定的目录的10个数据仓库。这些数据仓库使用了总共700M的硬盘空间。这个空间总量需求要相对于数据仓库数量的比例而变化。因此,你可以通过-w参数来创建你需要数据集的大小。
# src/datagen -w 10 -d /mnt/data/dbt2-w10
warehouses = 10
districts = 10
customers = 3000
items = 100000
orders = 3000
stock = 100000
new_orders = 900
Output directory of data files: /mnt/data/dbt2-w10
Generating data files for 10 warehouse(s)...
Generating item table data...
Finished item table data...
Generating warehouse table data...
Finished warehouse table data...
Generating stock table data...
2.读取数据到MySQL数据库中。
下面的命令创建了一个名为db2w10的数据库,并且把我们上一步的数据导入到这个库中。(-d 是数据库名字 -f是数据生成的目录)
# scripts/mysql/mysql_load_db.sh -d dbt2w10 -f /mnt/data/dbt2-w10 -s /var/lib/
mysql/mysql.sock
3.运行这个基准测试
# run_mysql.sh -c 10 -w 10 -t 300 -n dbt2w10 -u root -o /var/lib/mysql/mysql.sock
-e
************************************************************************
* DBT2 test for MySQL started *
* *
* Results can be found in output/9 directory *
************************************************************************
* *
* Test consists of 4 stages: *
* *
* 1. Start of client to create pool of databases connections *
* 2. Start of driver to emulate terminals and transactions generation *
* 3. Test *
* 4. Processing of results *
* *
************************************************************************
DATABASE NAME: dbt2w10
DATABASE USER: root
DATABASE SOCKET: /var/lib/mysql/mysql.sock
DATABASE CONNECTIONS: 10
TERMINAL THREADS: 100
SCALE FACTOR(WARHOUSES): 10
TERMINALS PER WAREHOUSE: 10
DURATION OF TEST(in sec): 300
SLEEPY in (msec) 300
ZERO DELAYS MODE: 1
Stage 1. Starting up client...
Delay for each thread - 300 msec. Will sleep for 4 sec to start 10 database
connections
CLIENT_PID = 12962
Stage 2. Starting up driver...
Delay for each thread - 300 msec. Will sleep for 34 sec to start 100 terminal
threads
All threads has spawned successfuly.
Stage 3. Starting of the test. Duration of the test 300 sec
Stage 4. Processing of results...
Shutdown clients. Send TERM signal to 12962.
Response Time (s)
Transaction % Average : 90th % Total Rollbacks %
------------ ----- ----------------- ------ --------- -----
Delivery 3.53 2.224 : 3.059 1603 0 0.00
New Order 41.24 0.659 : 1.175 18742 172 0.92
Order Status 3.86 0.684 : 1.228 1756 0 0.00
Payment 39.23 0.644 : 1.161 17827 0 0.00
Stock Level 3.59 0.652 : 1.147 1630 0 0.00
3396.95 new-order transactions per minute (NOTPM)
5.5 minute duration
0 total unknown errors
31 second(s) ramping up
最重要的测试结果如下:
3396.95 new-order transactions per minute (NOTPM)
显示了每分钟系统可以处理的事物数量。这个数值越多越好。(new-order并不是事务处理的一个类型,而是假想的商务系统的一个新的订单)
你可以使用一些参数来创建不同的基准测试
-c 数据库的连接数。你可以通过这个参数模拟不同级别的并发以及看看系统的伸缩性怎么样。
-e 这个开启zero-delay模式。意思就是在执行语句之间没有延迟。这个对数据库进行压力测试。但是这种测试不现实,因为在执行语句之前,用户都会需要一定的时间进行思考。
-t 基准测试持续的时间。要小心设置这个参数或者这个结果是无意义的。对I/O边界的基准测试时间太短,就会得到不正确的结果,因为系统没有足够的时间去预热缓存以及正常的去工作。另一方面,如果你想对CPU边界进行基准测试,也不应该让时间过长,否则数据集增长过于明显,最终这个测试变为I/O的基准测试了。
这个基准测试结果能提供的数据不仅仅是性能的了。比如,如果你看到过多的回滚,说明系统可能出现了错误。
MySQL基准套件是由一组Perl的基准测试组成。因此你需要用perl去运行它们。你能在MySQL安装目录的sql-bench的子目录中找到这些脚本。在Debian GNU/Linux系统中,它们在/usr/share/mysql/sql-bench/中。
在开始之前,请阅读README文件。这个文件解释了如果使用这个套件以及记录了命令行工具的参数。用下面的命令运行所有的测试。
$ cd /usr/share/mysql/sql-bench/
sql-bench$ ./run-all-tests --server=mysql --user=root --log --fast
Test finished. You can find the result in:
output/RUN-mysql_fast-Linux_2.4.18_686_smp_i686
这基准测试需要一些时间,也许会超过一个小时,当然时间消耗取决于你系统的硬件和配置。如果你在命令行添加--log参数,测试运行的时候,就可以监控这个过程了。每个测试的日志文件都存放在一个output的子目录中。每个文件包含了一些列指定时间的每个基准测试的操作。
sql-bench$ tail -5 output/select-mysql_fast-Linux_2.4.18_686_smp_i686
Time for count_distinct_group_on_key (1000:6000):
34 wallclock secs ( 0.20 usr 0.08 sys + 0.00 cusr 0.00 csys = 0.28 CPU)
Time for count_distinct_group_on_key_parts (1000:100000):
34 wallclock secs ( 0.57 usr 0.27 sys + 0.00 cusr 0.00 csys = 0.84 CPU)
Time for count_distinct_group (1000:100000):
34 wallclock secs ( 0.59 usr 0.20 sys + 0.00 cusr 0.00 csys = 0.79 CPU)
Time for count_distinct_big (100:1000000):
8 wallclock secs ( 4.22 usr 2.20 sys + 0.00 cusr 0.00 csys = 6.42 CPU)
Total time:
868 wallclock secs (33.24 usr 9.55 sys + 0.00 cusr 0.00 csys = 42.79 CPU)
这个例子中,count_distinct_group_on_key(1000:6000) 测试用了34s去执行。那是client运行测试所需总共的时间。其他的值(usr,sys,cursr,csys)之和0.28s是这个测试的消耗。这个是运行基准测试的时间,而不包括等待MySQL服务器响应时间。我们所关心的就是,client控制之外的被消耗的时间,那就是33.72s。
你可以单独的运行这些测试,而不是整体运行。比如,你可能关注的是insert的性能。下面给出详细的命令
sql-bench$ ./test-insert
Testing server 'MySQL 4.0.13 log' at 2003-05-18 11:02:39
Testing the speed of inserting data into 1 table and do some selects on it.
The tests are done with a table that has 100000 rows.
Generating random keys
Creating tables
Inserting 100000 rows in order
Inserting 100000 rows in reverse order
Inserting 100000 rows in random order
Time for insert (300000):
42 wallclock secs ( 7.91 usr 5.03 sys + 0.00 cusr 0.00 csys = 12.94 CPU)
Testing insert of duplicates
Time for insert_duplicates (100000):
16 wallclock secs ( 2.28 usr 1.89 sys + 0.00 cusr 0.00 csys = 4.17 CPU)