基准测试的重要性
基准测试是唯一方便有效、可以学习系统在给定负载下会发生什么的方法。基准测试可以观察系统在不同压力下的行为,评估系统的内容,掌握哪些是重要的变化,或者观察系统如何处理不同的数据。
导致基准测试不精确的一些因素
• 使用真实数据的子集而不是全集。例如应用需要处理几百GB的数据,但测试只有1GB数据,或者只使用当前数据进行测试,却希望模拟未来业务大幅增长后的情况
• 使用错误的数据分布。比如使用数据均匀的数据测试,而系统的真实数据有很多热点区域。数据的碎片化程度,在磁盘的分布,都会导致测试结果的不相同。保持磁盘数据分布尽可能一致的方法,应该对真实数据的磁盘分区进行复制。
• 使用不真实的分布参数,例如假定所有用户的个人信息都会被平均地读取(新浪微博周杰伦的个人主页信息比普通个人信息查看频率要高得多)。
• 在多用户场景中,只使用单用户的测试。
• 在单服务器上测试分布式应用。
• 与真实用户行为不匹配。例如Web页面中的“思考时间”。真实用户在请求到一个页面后会阅读一段时间,而不是不停顿地一个接一个点击相关链接。
• 反复执行同一个查询。真实的查询时不尽相同的,这可能会导致缓存命中率性降低。而反复执行同一个查询在某种程度上,会全部或部分缓存结果。
• 忽略了系统预热的过程。例如系统刚重启,硬件的性能可能不一致,项目刚启动,缓存还没有数据等。想要预测系统的稳定性,也应该有足够长的测试时间(应该大于八小时,设计性能变化曲线,在曲线达到平稳状态后也要观察足够长的时间)
• 使用默认的服务器配置。比如MySQL的默认配置和一个高并发项目中真实使用到的配置是不一样的。
基准测试的工具
集成式测试工具
ab
ab是Apache HTTP服务器基准测试工具。它可以测试HTTP服务器每秒可以处理的请求。用途相对有限,只能对单个URL进行尽可能快的压力测试。
用法示例:
ab [ -A auth-username:password ] [ -b windowsize ] [ -B local-address ] [ -c concurrency ] [ -C cookie-name=value ] [ -d ] [ -e csv-file ] [ -E client-certificate file ] [ -f protocol ] [ -g gnuplot-file ] [ -h ] [ -H custom-header ] [ -i ] [ -k ] [ -l ] [ -m HTTP-method ] [ -n requests ] [ -p POST-file ] [ -P proxy-auth-username:password ] [ -q ] [ -r ] [ -s timeout ] [ -S ] [ -t timelimit ] [ -T content-type ] [ -u PUT-file ] [ -v verbosity] [ -V ] [ -w ] [ -x <table>-attributes ] [ -X proxy[:port] ] [ -y <tr>-attributes ] [ -z <td>-attributes ] [ -Z ciphersuite ] [http[s]://]hostname[:port]/path
ab-n1000-c10http:/www.taoquan.ink/#-n访问1000次,-c并发10个
Server Software: Apache #服务器软件
Server Hostname: www.taoquan.ink #域名
Server Port: 80 #请求端口号
Document Path: / #文件路径
Document Length: 40888 bytes #页面字节数
Concurrency Level: 10 #请求的并发数
Time taken for tests: 27.300 seconds #总访问时间
Complete requests: 1000 #请求成功数量
Failed requests: 0 #请求失败数量
Write errors: 0
Total transferred: 41054242 bytes #请求总数据大小(包括header头信息)
HTML transferred: 40888000 bytes #html页面实际总字节数
Requests per second: 36.63 [#/sec] (mean) #每秒多少请求,这个是非常重要的参数数值,服务器的吞吐量
Time per request: 272.998 [ms] (mean) #用户平均请求等待时间
Time per request: 27.300 [ms] (mean, across all concurrent requests) # 服务器平均处理时间,也就是服务器吞吐量的倒数
Transfer rate: 1468.58 [Kbytes/sec] received #每秒获取的数据长度
Connection Times (ms)
min mean[+/-sd] median max
Connect: 43 47 2.4 47 53
Processing: 189 224 40.7 215 895
Waiting: 102 128 38.6 118 794
Total: 233 270 41.3 263 945
Percentage of the requests served within a certain time (ms)
50% 263 #50%用户请求在263ms内返回
66% 271 #66%用户请求在271ms内返回
75% 279 #75%用户请求在279ms内返回
80% 285 #80%用户请求在285ms内返回
90% 303 #90%用户请求在303ms内返回
95% 320 #95%用户请求在320ms内返回
98% 341 #98%用户请求在341ms内返回
99% 373 #99%用户请求在373ms内返回
100% 945 (longest request)
http_load
这个工具也是针对Web服务器测试,但是比ab相对灵活。可以在一个文件夹内填写多个url,http_load对url进行随机测试,也能制定不同的时间比率进行测试,而不仅仅是测试最大的请求处理。
用法示例:
创建一个urls.txt文件,输入几条url
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/
模拟5个用户,连续访问10秒
http_load -parallel 5 -seconds 10 urls.txt
参数说明:
-fetches 简写-f :含义是总计的访问次数
-rate 简写-r :含义是每秒的访问频率
-seconds简写-s :含义是总计的访问时间
-parallel 简写-p:并发访问的线程数
urls是一个url 列表,每个url 单独的一行。可以单个页面。
返回结果:
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
JMeter
JMeter相比ab和http_load使用复杂得多,功能也更健全。JMeter可以测试web服务器,ftp服务器和通过jdbc对数据库查询进行测试。它可以设置预热时间参数,更灵活地模拟真实用户对访问,有内置对图形处理功能,会对测试进行记录然后离线重演测试结果。
更多信息可参考:
http://jakarta.apache.org/jmeter/
单组件式测试工具
Super Smack
Super Smack是一款用于MySQL和PostgreSQL的基准测试工具,可以提供压力测试和负载生成。可以模拟多用户访问,可以加载测试数据到数据库,并支持使用随机数据填充测试表。测试定义在smack文件中,使用一种简单的语义定义测试的客户端、表、查询等测试要素。
sysbench
sysbench是多线程系统压测工具。它可以测试文件I/O、操作系统调度器、内存分配和传输速度、POSIX线程、以及数据库服务器等。sysbench支持Lua脚本语言,可以对测试场景灵活设置。
用法示例:
CPU基准测试
CPU基准测试。该测试使用64位整数,测试计算素数直到某个最大值所需时间。--cpu-max-prime表示素数生成数量的上限。最后返回结果total time,以秒为单位。
sysbench --test=cpu --cpu-max-prime=20000 run
返回结果:
sysbench v0.4.8 multithreaded system evaluation benchmark
...
Test execution summary: total time: 61.8596s
文件I/O测试
文件I/O测试会准备测试文件,文件大小至少要大于内存的大小。文件测试可以测试系统在不同I/O负载下的性能,针对不同的I/O类型有六个参数选项:
seqwr 顺序写入
seqrewr 顺序重写
seqrd 顺序读取
rndrd 随机读取
rndwr 随机写入
rndrw 混合随机读/写
下面例子测试I/O混合随机读写
sysbench --test=fileio --file-total-size=150G --file-test-mode=rndrw/
--init-rng=on --max-time=300 --max-requests=0 run
结果如下:
sysbench v0.4.8 multithreaded 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 16 Kb
Number or random requests for random IO: 10000
Read/Write ratio for combined random IO test: 1.50
Periodoc 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.06 Mb Written 419.38Mb Total transfferred 1.0239Gb (3.4948Mb/sec)
233.67 Request/sec executed
Total 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
测试结果有大量对信息,在上述例子中,每秒请求数是223.67 Requests/sec, 吞吐量是3.4948MB/sec,大约95%时间分布。这些信息都对评估一个磁盘性能十分有用。
OLTP基准测试
OLTP基准测试模拟一个简单对事务处理系统的工作负载。下面例子使用一张超过百万记录的表,第一步生成表:
1) 准备数据
sysbench --test=oltp --mysql-table-engine=innodb --oltp-table-size=1000000/
--mysql-db=test --mysql-user=root prepare
采用8个并发程序,测试只读模式(去除--oltp-read-only,或选项为off时可以测试混合读写性能) ,测试60秒:
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
测试结果如下:
OLTP test statistics:
queries performed:
read: 179606 // 总select数量
write: 0 // 总update、insert、delete语句数量
other: 25658 // commit、unlock tables以及其他mutex的数量
total: 205264 //总的操作数量
transactions: 12829 (213.07 per sec.)// 后面那个是TPS,每秒事务量
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 // 即max-time指定的压测实际
total number of events: 12829 // 总的事务数,一般与transactions相同
total time taken by event execution: 480.2086 // 事务执行所需时间
per-request statistics:
min: 0.0030s // 语句最小响应时间
avg: 0.0374s // 语句平价响应时间
max: 1.9106s // 语句最多响应时间
approx. 95percentile: 0.1163s // 95%语句的平均响应时间
Thread fairness:
events (avg/stddev) : 1603.6250/70.66 // 线程执行平均次数
execution time (avg/stddev): 60.0261/0.06 // 线程执行时间
参考资料
《高性能MySQL》第三版