如何用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的性能測試。

原文連接

相關文章
相關標籤/搜索