一
通過fio工具測試磁盤性能
SPDK采用異步I/O(Asynchronous I/O)加輪詢(Polling)的工作模式,通常與Kernel的異步I/O作為對比。在此,主要介紹通過使用fio評估Kernel異步I/O,以及spdk fio_plugin的兩種模式。
01
fio評估kernel異步I/O(AIO)
fio支持多種模式的I/O引擎,同時也包含了測試異步I/O的引擎,即libaio。在測試異步I/O的時候,只需要將fio啟動配置文件中的ioengine設為libaio即可。通常在做異步I/O的時候,I/O請求會發送到相應的隊列中,等待被處理,因此隊列深度將會影響磁盤性能。所以在測試異步I/O的時候,根據磁盤的特性指定相應的隊列深度(iodepth)。
測試Kernel異步I/O的fio配置參數示例如下:
[Global]ioengine=libaiodirect=1rw=randrwrwmixread=100 (100% reads), 70 (70% reads 30% writes), 0 (100 writes)thread=1norandommap=1time_base=1runtime=300sramp_time=10sbs=4kiodepth=32Numjobs=1[test]filename=/dev/nvme0n1
參數詳解
ioengine:指定I/O引擎,在這里測試Kernel的異步I/O,因此指定I/O引擎為libaio;direct: 指定direct模式O_DIRECT,I/O會繞過系統的page buffer;rw:讀寫模式,這里指定randrw表示混合隨機讀寫;rwmixread:混合隨機讀寫模式下read請求所占比例;thread:指定使用線程模式。由于spdk fio_plugin只支持線程模式,因此與Kernel對比時,通常都統一指定線程模式來對比;norandommap:指定I/O時,每次都獲取一個新的隨機offset,防止額外的CPU使用消耗;time_based:指定采用時間模式;runtime:測試時長;ramp_time:統計性能之前所運行的時間,為了防止沒有進行穩態而造成的性能虛高帶來的影響;bs:I/O塊大小;iodepth:隊列深度;numjobs:worker的個數;filename:指定測試的對象。
02
基于NVMe的fio_plugin
安裝步驟
a. 下載編譯fio:
git clone https://github.com/axboe/fiocd fio && git checkout fio-3.3make
b.下載編譯SPDK:
git clone https://github.com/spdk/spdkcd spdk && git submodule update --init./configure --with-fio=/path/to/fio/repo
注意:由于fio_plugin要依賴fio中提供的一些依賴包,因此在運行configure時,必須指定fio目錄,否則默認fio_plugin不會編譯
測試方法
a. 使用fio_plugin測試裸盤,需要引入fio_plugin路徑,因此在運行fio時,在fio命令之前加如下參數:
LD_PRELOAD=
b. 其次,需要在fio配置文件中設定ioengine為spdk。
c. 運行fio時候,不僅要指定fio運行配置文件,同時要通過額外的參數'--filename'指定spdk能夠識別的設備地址信息。通常,fio_plugin支持兩種模式下的測試,一是本地的NVMe設備,即NVMe over PCIe;二是遠端的NVMe設備,即NVMe over Fabrics。如下所示:
NVMe over PCIe:LD_PRELOAD=.../fio_plugin fio config.fio '--filename=trtype=PCIe traddr=0000.06.00.0 ns=1'NVMe over Fabrics:LD_PRELOAD=.../fio_plugin fio config.fio '--filename=trtype=RDMA adrfam=IPv4 traddr=192.0.0.1 trsvcid=4420 ns=1'
其它說明
a. 對于使用1個core,測試多塊盤的情況,通常只需要設定numjob為1,同時在fio命令通過多個filename參數來指定多塊要測試的盤(多個filename參數之間用空格相隔即可),例如同時測試三塊盤:
LD_PRELOAD=.../fio_plugin fio config.fio '--filename=trtype=PCIe traddr=0000.06.00.0 ns=1' '--filename=trtype=PCIe traddr=0000.07.00.0 ns=1' '--filename=trtype=PCIe traddr=0000.08.00.0 ns=1'
b. 對于使用fio_plugin作為新的ioengine而引入的新的fio參數說明,可以通過以下命令查看相關參數說明:
LD_PRELOAD.../fio_plugin fio --enghelp=spdk
c. 此外,可以通過直接在ioengine中指定fio_plugin的絕對路徑,而無須每次運行fio都動態加載LD_PRELOAD。即: fio配置文件中添加修改ioengine=
03
基于bdev的fio_plugin
基于bdev的fio_plugin是將I/O在spdk塊設備bdev之上進行發送。而基于裸盤的fio_plugin,I/O是直接到裸盤上進行處理。因此兩者最大的差別在于I/O是否經過bdev這一層。因此,基于bdev的fio_plugin能夠很好的評估spdk塊設備層bdev的性能。
其編譯安裝與裸盤的fio_plugin完全相同,下面詳細介紹其測試方法:
a. 使用fio_plugin測試bdev性能,需要bdev fio_plugin的路徑,因此在運行fio時,在fio命令之前加如下參數:
LD_PRELOAD=
b. 其次,需要在fio配置文件中設定ioengine為spdk_bdev
c. 需要在fio配置文件中指定spdk啟動配置文件。如下所示:
spdk_conf=./example/bdev/fio_plugin/bdev.conf
spdk運行配置文件中指定了所有bdev的配置信息,示例如下:
[Malloc]
NumberOfLuns 1LunSizeInMB 128
[Nvme]
TransportID "trtype:PCIe traddr:0000:82:00.0" Nvme0
RetryCount 4TimeoutUsec 0AcctionOnTimeout NoneAdminPollRate 100000
d.運行fio的時候,通過'--filename'直接指定所要測試的bdev名稱即可,示例如下:
LD_PRELOAD=.../fio_plugin fio config.fio '--filename=Nvme0n1'
其他說明
a. 使用基于bdev的fio_plugin測試多個設備時候,需要在spdk運行配置文件中寫入相應的bdev配置信息,其次在fio運行時,指定多個filename參數即可,多個filename之間用空格相隔。例如同時測兩個設備Malloc0與Nvme0n1,如下所示:
LD_PRELOAD=.../fio_plugin fio config.fio '--filename=Nvme0n1' '--filename=Malloc0'
b.同理,若查看基于bdev的fio_plugin相關參數說明,可以通過如下命令:
LD_PRELOAD.../fio_plugin fio --enghelp=spdk_bdev
c. 此外,可以通過直接在ioengine中指定fio_plugin的絕對路徑,而無須每次運行fio都動態加載LD_PRELOAD。即:
fio配置文件中添加修改ioengine=
二
通過spdk perf測試磁盤性能
01
基于NVMe的perf工具
成功編譯spdk后,可在spdk/examples/nvme/perf/目錄下找到perf工具的二進制運行文件。perf使用方法如下所示:
perf -c
更多參數解析,請參考perf --help
perf支持本地的NVMe設備,同時也支持遠端的NVMeoF的設備。使用范例如下:
NVMe over PCIe:perf -q 32 -s 1024 -w randwrite -t 1200 -c 0xF -o 4096 -r 'trtype:PCIe traddr:0000:06:00.0'NVMe over Fabrics:perf -q 32 -s 1024 -w randwrite -t 1200 -c 0xF -o 4096 -r 'trtype:RDMA adrfam:IPv4 traddr:192.0.0.1 trsvcid:4420'
對于同時測試多塊盤,只需要添加-r并指定設備地址即可,例如一個core測試三塊盤:
perf -q 32 -s 1024 -w randwrite -t 1200 -c 0x1 -o 4096 -r 'trtype:PCIe traddr:0000:06:00.0' -r 'trtype:PCIetraddr:0000:07:00.0' -r 'trtype:PCIe traddr:0000:08:00.0'
02
perf評估Linux異步I/O(AIO)
使用方式與測試spdkdriver相同,只需要在perf命令后添加設備名稱即可。使用范例如下:
perf -q 32 -s 1024 -w randwrite -t 1200 -c 0xF -o 4096 /dev/nvme0n1
03
基于bdev的perf工具
成功編譯spdk后,可在spdk/test/bdev/bdevperf/目錄下找到bdevperf工具的二進制運行文件。bdevperf使用方法如下所示:
bdevperf -c
更多參數解析,請參考perf --help。
其中,-c是指定bdevperf的配置文件,需要測試的bdev設備都在配置文件中指定,例如,若需要測試本地的兩塊NVMe設備,則bdevperf的配置文
件示例如下:
[Nvme]
TransportID "trtype:PCIe traddr:0000:82:00.0" Nvme0RetryCount 4TimeoutUsec 0AcctionOnTimeout NoneAdminPollRate 100000
相應的bdevperf啟動參數示例如下:
bdevperf -q 32 -s 1024 -w randwrite -t 1200 -o 4096 -m 0xF -c bdevperf.conf
對于bdevperf,若要測試多塊盤,則只需要在spdk配置文件中配置多塊盤的信息即可,例如同時測試三塊盤:
[Nvme]
TransportID "trtype:PCIe traddr:0000:82:00.0" Nvme0
TransportID "trtype:PCIe traddr:0000:83:00.0" Nvme1TransportID "trtype:PCIe traddr:0000:84:00.0" Nvme2RetryCount 4TimeoutUsec 0AcctionOnTimeout NoneAdminPollRate 100000
三
常見問題
1
通過fio與perf對SPDK進行性能評估,得到的結果不同,大部分的時候perf所得到的性能會比fio所得到的性能要高。
兩種工具最大的差別在于,fio是通過與Linux fio工具進行集成,使其可以用fio_plugin引擎測試SPDK設備。而由于fio本身架構的問題,不能充分發揮SPDK的優勢,整個應用框架仍然使用fio原本的架構。例如fio使用Linux的線程模型,在使用的時候,線程仍然被內核調度。而對于perf來說,是針對SPDK所設計的性能測試工具,因此在底層,不僅是I/O通過SPDK下發,同時一些底層應用框架都是為SPDK所設計的。例如剛剛所提到的線程模型,perf中是使用DPDK所提供的線程模型,通過使用CPU的親和性將CPU核與線程捆綁,不再受內核調度,因此可以充分發揮SPDK下發I/O時的異步無鎖化優勢。這就是為什么perf所測得的性能要比fio高,尤其是在使用單個線程(單核)同時測試多塊盤的情況下,fio所得性能要明顯小于perf所得性能。因此,在同等情況下,我們更推薦用戶使用perf工具對SPDK進行性能評估。
此外,在多numjob的情況下,fio與perf對iodepth的分配是不同的。通常在fio中,指定的iodepth表示所有的job一共的iodepth,而在perf指定的iodepth(perf中-q參數)通常指的是每個job所使用的iodepth。舉例如下:Fio:numjob=4, iodepth=128。則每個job對應的iodepth為32(128/4)。Perf:-c 0xF (相當于fio中numjob=4),-q 128(相當于fio中iodepth=128)。則每個job對應的iodepth為128。
2
對SPDK和內核的性能評估時,雖然性能有所提升,但是沒有看到SPDK官方所展示的特別大的性能差異。
首先,如問題1中所述,不同的工具之間所得出的性能結果是不同的,另外最主要的因素還是硬盤本身的性能瓶頸所導致的問題。例如,以2D NAND為介質的Intel DC P3700,本身的性能都存在一定的瓶頸,因此無論是SPDK用戶態驅動還是內核驅動,都不會達到較高的IOPS。若換用更高性能的硬盤,例如使用以3D Xpoint為介質的Optane(Intel DC P4800X)為測試對象,便會看到很大的性能差異。因此,硬盤性能越高,SPDK所發揮出的優勢越明顯,這也是SPDK產生的初衷,其本身就是為高性能硬盤所訂制的。
3
關于評估不同硬盤的隊列深度(iodepth)與CPU core的問題。
通常根據不同硬盤的特點,選擇不同的iodepth以及所使用的CPUcore。通常在評估以2D NAND、3D NAND介質的硬盤,一般情況下,為了達到磁盤的最高性能,通常會選擇較高的iodepth(128或256)。對于P4XXX的硬盤,通常可能一個CPU core無法達到滿IOPS,此時并不是由于一個core的能力不夠,而是由于硬盤中硬件隊列本身限制的問題。因此,通常需要使用兩個CPU core才能夠達到specification中的滿IOPS。此外,對于以3D Xpoint為介質的Optane(Intel P4800X),通常只需要一個core并使用較小的iodepth即可達到滿IOPS,此時已經達到硬盤的上限,若再次增大iodepth只會是latency變大而IOPS不再增長。
下面給出各種硬盤建議的評估參數:Intel P3700: numjob=1, iodepth=128Intel P4500、Intel P4510、Intel P4600:numjob=2, iodepth=256Intel Optane(Intel P4800X):numjob=1, iodepth=8/16/32
4
關于寫性能虛高的問題。
通常以2D NAND、3D NAND為介質的硬盤,在測試write/randwrite的性能時候,通常要比sepcification里的最高值高很多。這是由于這類介質本身的問題,所以在測試時會出現write/randwrite性能虛高的問題。因此在測試該類硬盤,為了避免此類現象,通常需要對磁盤做一次precondition。通常的做法為:在格式化之后,對磁盤不斷進行寫操作,寫滿整個磁盤,使其進行穩態。以DC P3700 800GB為例,通常首先以4KB的大小順序寫兩小時,之后再隨機寫一小時。此外,在測試的時候,fio參數中的ramp_time可以設置較大一些,避免初始的虛高值計入最終結果。
5
關于磁盤性能測試指標。
通常,對于一個磁盤的性能,我們主要從三方面去評估:IOPS、bandwidth、latency。
IOPS:通常評估磁盤的IOPS,主要關注塊大小為4k,隨機讀寫的情況。因此,通常fio關鍵參數為:bs=4k,iodepth=128,direct=1,rw=randread/randwrite。
Bandwidth:評估磁盤的bandwidth,通常是關注塊大小為128k,順序讀寫的情況。因此,通常fio關鍵參數為:bs=128k,iodepth=128,direct=1,rw=read/write。
Latency:評估latency通常情況下,是關注一個I/O發送/完成的延遲情況,因此,通常選擇iodepth為1。因此,通常fio關鍵參數為:bs=4k,iodepth=1,direct=1,rw=randread/randwrite。此外,對于latency的結果,不僅要關注平均值,同時也要注意長尾延遲,即99.99%的延遲情況。
注意:通常在測試磁盤的性能時,要添加direct=1,即繞過系統的cache buffer。這時測得的性能為裸盤的性能 。
-
SSD
+關注
關注
20文章
2791瀏覽量
116662 -
磁盤
+關注
關注
1文章
355瀏覽量
25096
原文標題:基于SPDK的NVMe SSD性能評估指南
文章出處:【微信號:SSDFans,微信公眾號:SSDFans】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論