Linux

Linux上的SSD IOPS,DIRECT比緩衝快得多,fio

  • June 30, 2018

我有一個由 10 個 DC-S4500 Intel SSD 組成的 30Tb 大小的硬體 RAID-6 系統 (LSI 9280-8e),用於數據庫。帶有 3.2 核心的作業系統 Debian 7.11。文件系統是使用 nobarrier 選項安裝的 XFS。

看到與我在隨機 I/O 中的預期性能相比有些遲鈍,我開始通過執行 fio 基準來調查發生了什麼。令我驚訝的是,當我在(iodepth=32 和 ioengine=libaio)的隨機讀取設置中對 1Tb 文件使用 fio 時,我得到了 ~ 3000 IOPS,這比我預期的要低得多。

random-read: (groupid=0, jobs=1): err= 0: pid=128531
 read : io=233364KB, bw=19149KB/s, iops=4787 , runt= 12187msec
 ...
 cpu          : usr=1.94%, sys=5.81%, ctx=58484, majf=0, minf=53
 IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=99.9%, >=64=0.0%
    submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
    complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.1%, 64=0.0%, >=64=0.0%
    issued    : total=r=58341/w=0/d=0, short=r=0/w=0/d=0

但是,如果我使用 direct=1 選項(即繞過 linux 的緩衝區記憶體),我會得到 ~ 40000 IOPS,這是我希望看到的。

random-read: (groupid=0, jobs=1): err= 0: pid=130252
 read : io=2063.7MB, bw=182028KB/s, iops=45507 , runt= 11609msec
....
 cpu          : usr=6.93%, sys=23.29%, ctx=56503, majf=0, minf=54
 IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=100.0%, >=64=0.0%
    submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
    complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.1%, 64=0.0%, >=64=0.0%
    issued    : total=r=528291/w=0/d=0, short=r=0/w=0/d=0

我似乎以調度程序、預讀和旋轉設置的形式對 SSD 分區進行了所有正確的設置。

root@XX:~# cat /sys/block/sdd/queue/scheduler
[noop] deadline cfq 
root@XX:~# cat /sys/block/sdd/queue/rotational
0
root@XX:~# blockdev --getra /dev/sdd
0

我是否仍然錯過了會大大降低緩衝性能的東西?還是預計會看到 DIRECT 與緩沖之間的這種差異?

我還查看了兩次執行期間的 iostat 輸出 這是使用 direct=1 的情況:

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sdd               0.00     0.00 48110.00    0.00 192544.00     0.00     8.00    27.83    0.58    0.58    0.00   0.02  99.60

這是緩衝執行

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sdd               0.00     0.00 4863.00    0.00 19780.00     0.00     8.13     0.89    0.18    0.18    0.00   0.18  85.60

所以看起來關鍵的區別是隊列大小(avgqu-sz),在使用緩衝 I/O 時它很小。鑑於 nr_requests 和 queue_depth 都很高,我覺得這很奇怪:

root@XX:~# cat /sys/block/sdd/queue/nr_requests
128
root@XX:~# cat /sys/block/sda/device/queue_depth
256

這裡有什麼建議嗎?

帶有 3.2 核心的 Debian 7.11

盡可能升級。您不僅可以獲得核心改進,而且 Wheezy 是生命的盡頭。


是的,當 direct=1 時,您會看到更高的使用率和隊列深度。fio 手冊特別提到了這種情況(強調我的):

iodepth=int

要針對文件保持執行的 I/O 單元數。請注意,將 iodepth 增加到 1 以上不會影響同步 ioengine(使用 verify_async 時的小度數除外)。甚至非同步引擎也可能會施加作業系統限制,導致無法達到所需的深度。**當使用 libaio 且未設置 direct=1 時,這可能在 Linux 上發生,因為緩衝 I/O 在該作業系統上不是非同步的。**密切關注 fio 輸出中的 I/O 深度分佈,以驗證達到的深度是否符合預期

所以 libaio 需要 O_DIRECT 進行非同步,這是一個需要了解的重要實現細節。有人問如果不直接使用 libaio 是個好主意:

使用libaio時設置direct=0是否有效?

你可以這樣做,但我不建議這樣做。在當今的 Linux 核心中,如果沒有 O_DIRECT,libaio 送出可能會變得阻塞(因此不再是非同步的),這會限制實現的並行 I/O 數量。有一個強有力的論點是 fio 的例子不應該鼓勵這樣的選項組合……

> > man doc中的“排隊”行為是什麼意思? > > >

如果您的意思是“請注意,Linux 可能僅支持非緩衝 I/O 的排隊行為”(在 http://fio.readthedocs.io/en/latest/fio_doc.html#io-engine中),我認為是想說:

“而不是阻塞送出系統呼叫,直到 I/O 關閉並從最低的磁碟設備返回(阻塞行為),當使用直接 = 1 和 libaio 時,您可以送出 I/O 並讓它非同步排隊核心允許送出系統呼叫立即返回,並為您在 I/O 完成之前排隊其他送出提供機會”。

還可以嘗試使用 ioengine=psync 和 direct=0 進行控制測試。即使是帶有記憶體的同步寫入也可以執行大量 IOPS。

所有這些都迴避了真正的問題:您執行的數據庫工作負載有什麼問題?問題症狀、軟體版本、配置、性能指標 (iostat)。DBMS 的 I/O 實現可能與您所模擬的、使用的系統呼叫、執行 I/O 的多個文件和作業、任何數量的事情大不相同。如果您想進一步調查,這值得提出自己的問題。

引用自:https://serverfault.com/questions/918896