Linux上的SSD IOPS,DIRECT比緩衝快得多,fio
我有一個由 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 的多個文件和作業、任何數量的事情大不相同。如果您想進一步調查,這值得提出自己的問題。