如何用sysbench作好IO性能测试

sysbench 是一个很是经典的综合性能测试工具,一般都用它来作数据库的性能压测,但也能够用来作CPU,IO的性能测试。而对于IO测试,不是很推荐sysbench,倒不是说它有错误,工具自己没有任何问题,它的测试方法致使测试的数据会让人有些困惑:性能数据究竟是不是这样呢,跟云厂商承诺的性能有关系嘛。通常咱们都用FIO来进行性能测试,云厂商都推荐用FIO进行性能测试,经过FIO性能测试,都能轻易达到云厂商承诺的性能。数据库

插曲:关于sysbench的版本,如今主要有0.4.12和1.0.版本。截止2006年sysbench好长时间没有发展,2017年以前都是用旧版本0.4.12(因此网上一搜一大堆文章都是0.4.的教程),而后做者估计修了几个bug,变成0.5版本,而后就跟过去作了告别,从2017从新开发了一个新版本sysbench 1.0.*,这里讲述的性能测试都是用了最新版。缓存

1. sysbench fileio测试

言归正传,sysbench怎么作IO的性能测试呢,sysbench fileio help,参数以下:异步

#/usr/local/sysbench_1/bin/sysbench fileio help
sysbench 1.0.9 (using bundled LuaJIT 2.1.0-beta2)

fileio options:
  --file-num=N              number of files to create [128]
  --file-block-size=N       block size to use in all IO operations [16384]
  --file-total-size=SIZE    total size of files to create [2G]
  --file-test-mode=STRING   test mode {seqwr, seqrewr, seqrd, rndrd, rndwr, rndrw}
  --file-io-mode=STRING     file operations mode {sync,async,mmap} [sync]
  --file-async-backlog=N    number of asynchronous operatons to queue per thread [128]
  --file-extra-flags=STRING additional flags to use on opening files {sync,dsync,direct} []
  --file-fsync-freq=N       do fsync() after this number of requests (0 - don't use fsync()) [100]
  --file-fsync-all[=on|off] do fsync() after each write operation [off]
  --file-fsync-end[=on|off] do fsync() at the end of test [on]
  --file-fsync-mode=STRING  which method to use for synchronization {fsync, fdatasync} [fsync]
  --file-merged-requests=N  merge at most this number of IO requests if possible (0 - don't merge) [0]
  --file-rw-ratio=N         reads/writes ratio for combined test [1.5]

sysbench的性能测试都须要作prepare,run,cleanup这三步,准备数据,跑测试,删除数据。那下面就开始实战:
客户用2C4G的vm,挂载120G的SSD云盘作了性能测试,测试命令以下:async

cd /mnt/vdb  #必定要到你测试的磁盘目录下执行,不然可能测试系统盘了
sysbench fileio --file-total-size=15G --file-test-mode=rndrw --time=300 --max-requests=0 prepare
sysbench fileio --file-total-size=15G --file-test-mode=rndrw --time=300 --max-requests=0 run
sysbench fileio --file-total-size=15G --file-test-mode=rndrw --time=300 --max-requests=0 cleanup

结果以下:工具

File operations:
    reads/s:                      2183.76
    writes/s:                     1455.84
    fsyncs/s:                     4658.67

Throughput:
    read, MiB/s:                  34.12
    written, MiB/s:               22.75

General statistics:
    total time:                          300.0030s
    total number of events:              2489528

Latency (ms):
         min:                                  0.00
         avg:                                  0.12
         max:                                204.04
         95th percentile:                      0.35
         sum:                             298857.30

Threads fairness:
    events (avg/stddev):           2489528.0000/0.00
    execution time (avg/stddev):   298.8573/0.00

随机读写性能好像不咋地,换算IOPS为(34.12+22.75)*1024/16.384=3554.375,与宣称的5400IOPS有很大差距。眼尖的人确定发现只有2个核,去遍历128个文件,好像会下降效率,因而定制file-num去作了系列测试,测试结果以下:性能

file-num 1 2 4 8 16 32 64 128
read(MB/s) 57.51 57.3 57.36 57.33 55.12 47.72 41.11 34.12
write(MB/s) 38.34 38.2 38.24 38.22 36.75 31.81 27.4 22.75

明显能够看到,默认测试方法会致使性能降低,文件数设置为1达到最大性能。
那file-num=128与file-num=1的区别是测试文件从128个变成1个,可是总文件大小都是15G,都是随机读写,按理性能应该是一致的,区别是会在多个文件之间切换读写,那么可能会致使中断增长和上下文切换开销增大。经过vmstat命令获得了验证:
file-num=128的vmstat输出是这样的:

file-num=1的vmstat输出是这样的:

从上面两个图能够看出file-num=1的时候上下文切换只有8500左右比file-num=128的时候24800小多了,in(中断)也少太多了。减小了中断和上下文切换开销,吞吐能力显著提高了。
再作了一个实验,一样磁盘大小,改为挂载到8C的vm下,改为8线程进行测试,获得以下数据:测试

file-num 1 2 4 8 16 32 64 128
read(MB/s) 253.08 209.86 193.38 159.73 117.98 86.78 67.39 51.98
write(MB/s) 168.72 139.9 128.92 106.49 78.66 57.85 44.93 34.65

能够得出一样的结论,file-num=1能够获得最好的性能,理由如上。this

2. 与fio测试的比较

单进程下,file-num=1换算到IOPS为(57.51+38.34)*1024/16.384=5990.625,这好像超过咱们的IOPS设置限定了。经过fio是怎么测得这个IOPS的呢:spa

fio -direct=1 -iodepth=128 -rw=randrw -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=iotest -name=randrw_test

经过阅读源代码,发现不少不一样:操作系统

  1. 一个是经过libaio,一个是经过pwrite/pread。libaio的性能是很是强劲的,详情能够参考文章
    即便ioengine=psync,这个engine的读写方法是pread和pwrite,可是整个实现也是不一致的。
  2. fio测试的时候direct=1,就是每次都写入磁盘,而sysbench默认file-fsync-freq=100,也就是完成100次操做才会有一个fsync操做,这种操做涉及系统缓存。

3. 深刻一步

上节认为操做系统干扰以及io读写方式的差别,形成了测试数据的不一致。深刻去研究了下源代码,其实sysbench的做者是提倡用libaio,代码里面大量地运用了宏定义,如:

/* 异步写的截取代码 */
#ifdef HAVE_LIBAIO
  else if (file_io_mode == FILE_IO_MODE_ASYNC)
  {
    /* Use asynchronous write */
    io_prep_pwrite(&iocb, fd, buf, count, offset);

    if (file_submit_or_wait(&iocb, FILE_OP_TYPE_WRITE, count, thread_id))
      return 0;

    return count;
  }
#endif

那怎么启用这个宏呢,默认就是启用这个宏的。
启用这个宏后,执行sysbench fileio help,会发现有这一项:--file-async-backlog=N number of asynchronous operatons to queue per thread [128],说明HAVE_LIBAIO这个宏确实生效了。
既然sysbench默认有libaio后,那整个测试方法须要调整:

# --file-extra-flags=direct 文件读写模式改为direct
# --file-io-mode=async 确保libaio起效
# --file-fsync-freq=0 不须要执行fsync
sysbench fileio --file-total-size=15G --file-test-mode=rndrw --time=300 --max-requests=0 --file-io-mode=async --file-extra-flags=direct  --file-num=1 --file-rw-ratio=1 --file-fsync-freq=0 run

获得测试结果以下:

对于FIO命令也进行了调整,把bs调整成16k,其余不变,仍是达到上限5400。测试结果以下:

能够看到sysbench测试的效果与fio的测试效果彻底一致!

不过我的仍是推荐FIO来作IO的性能测试。

原文连接

相关文章
相关标签/搜索