1. 程式人生 > >系統技術非業餘研究 » Fio壓測工具和io佇列深度理解和誤區

系統技術非業餘研究 » Fio壓測工具和io佇列深度理解和誤區

Fio 是個強大的IO壓力測試工具,我之前寫過不少fio的使用和實踐,參見 這裡

隨著塊裝置的發展,特別是SSD盤的出現,裝置的並行度越來越高。利用好這些裝置,有個訣竅就是提高裝置的iodepth, 一把餵給裝置更多的IO請求,讓電梯演算法和裝置有機會來安排合併以及內部並行處理,提高總體效率。

應用使用IO通常有二種方式:同步和非同步。 同步的IO一次只能發出一個IO請求,等待核心完成才返回,這樣對於單個執行緒iodepth總是小於1,但是可以透過多個執行緒併發執行來解決,通常我們會用16-32根執行緒同時工作把iodepth塞滿。 非同步的話就是用類似libaio這樣的linux native aio一次提交一批,然後等待一批的完成,減少互動的次數,會更有效率。

io佇列深度通常對不同的裝置很敏感,那麼如何用fio來探測出合理的值呢?

讓我們先來看下和iodepth相關的引數:

iodepth=int
Number of I/O units to keep in flight against the file. Note that increasing iodepth beyond 1 will not affect synchronous ioengines
(except for small degress when verify_async is in use). Even async engines my impose OS restrictions causing the desired depth not to be
achieved. This may happen on Linux when using libaio and not setting direct=1, since buffered IO is not async on that OS. Keep an eye on
the IO depth distribution in the fio output to verify that the achieved depth is as expected. Default:
1.

iodepth_batch=int
Number of I/Os to submit at once. Default: iodepth.

iodepth_batch_complete=int
This defines how many pieces of IO to retrieve at once. It defaults to 1 which
means that we’ll ask for a minimum of 1 IO in the retrieval process from the kernel. The IO retrieval will go on until we hit the limit
set by iodepth_low. If this variable is set to 0, then fio will always check for completed events before queuing more IO. This helps
reduce IO latency, at the cost of more retrieval system calls.

iodepth_low=int
Low watermark indicating when to start filling the queue again. Default: iodepth.

direct=bool
If true, use non-buffered I/O (usually O_DIRECT). Default: false.

fsync=int
How many I/Os to perform before issuing an fsync(2) of dirty data. If 0, don’t sync. Default: 0.

這幾個引數在libaio的引擎下的作用,文件寫的挺明白,但容我再羅嗦下IO請求的流程:

libaio引擎會用這個iodepth值來呼叫io_setup準備個可以一次提交iodepth個IO的上下文,同時申請個io請求佇列用於保持IO。 在壓測進行的時候,系統會生成特定的IO請求,往io請求佇列裡面扔,當佇列裡面的IO個數達到iodepth_batch值的時候,就呼叫io_submit批次提交請求,然後開始呼叫io_getevents開始收割已經完成的IO。 每次收割多少呢?由於收割的時候,超時時間設定為0,所以有多少已完成就算多少,最多可以收割iodepth_batch_complete值個。隨著收割,IO佇列裡面的IO數就少了,那麼需要補充新的IO。 什麼時候補充呢?當IO數目降到iodepth_low值的時候,就重新填充,保證OS可以看到至少iodepth_low數目的io在電梯口排隊著。

注意:這些引數在文件裡面描述的有點小問題,比如說預設值什麼的是不太對的,所以我的建議是這些引數要去顯示的寫。

如何確認fio安裝我們的配置在工作呢? fio提供了診斷辦法 --debug=io ,我們來演示下:

# cat nvdisk-test
[global]
bs=512
ioengine=libaio
userspace_reap
rw=randrw
rwmixwrite=20
time_based
runtime=180
direct=1
group_reporting
randrepeat=0
norandommap
ramp_time=6
iodepth=16
iodepth_batch=8
iodepth_low=8
iodepth_batch_complete=8
exitall
[test]
filename=/dev/nvdisk0
numjobs=1

fio任務配置裡面有幾個點需要非常注意:
1. libaio工作的時候需要檔案direct方式開啟。
2. 塊大小必須是扇區(512位元組)的倍數。
3. userspace_reap提高非同步IO收割的速度。
4. ramp_time的作用是減少日誌對高速IO的影響。
5. 只要開了direct,fsync就不會發生。

# fio nvdisk-test --debug=io
fio: set debug option io
io       22441 load ioengine libaio
io       22441 load ioengine libaio
test: (g=0): rw=randrw, bs=512-512/512-512, ioengine=libaio, iodepth=16
fio 2.0.5
Starting 1 process
io       22444 invalidate cache /dev/nvdisk0: 0/8589926400
io       22444 fill_io_u: io_u 0x6d3210: off=3694285312/len=512/ddir=0//dev/nvdisk0
io       22444 prep: io_u 0x6d3210: off=3694285312/len=512/ddir=0//dev/nvdisk0
io       22444 ->prep(0x6d3210)=0
io       22444 queue: io_u 0x6d3210: off=3694285312/len=512/ddir=0//dev/nvdisk0
io       22444 fill_io_u: io_u 0x6d2f80: off=4595993600/len=512/ddir=0//dev/nvdisk0
io       22444 prep: io_u 0x6d2f80: off=4595993600/len=512/ddir=0//dev/nvdisk0
io       22444 ->prep(0x6d2f80)=0
io       22444 queue: io_u 0x6d2f80: off=4595993600/len=512/ddir=0//dev/nvdisk0
io       22444 fill_io_u: io_u 0x6d2cb0: off=3825244160/len=512/ddir=0//dev/nvdisk0
io       22444 prep: io_u 0x6d2cb0: off=3825244160/len=512/ddir=0//dev/nvdisk0
io       22444 ->prep(0x6d2cb0)=0
io       22444 queue: io_u 0x6d2cb0: off=3825244160/len=512/ddir=0//dev/nvdisk0
io       22444 fill_io_u: io_u 0x6d29a0: off=6994864640/len=512/ddir=0//dev/nvdisk0
io       22444 prep: io_u 0x6d29a0: off=6994864640/len=512/ddir=0//dev/nvdisk0
io       22444 ->prep(0x6d29a0)=0
io       22444 queue: io_u 0x6d29a0: off=6994864640/len=512/ddir=0//dev/nvdisk0
io       22444 fill_io_u: io_u 0x6d2710: off=2572593664/len=512/ddir=0//dev/nvdisk0
io       22444 prep: io_u 0x6d2710: off=2572593664/len=512/ddir=0//dev/nvdisk0
io       22444 ->prep(0x6d2710)=0
io       22444 queue: io_u 0x6d2710: off=2572593664/len=512/ddir=0//dev/nvdisk0
io       22444 fill_io_u: io_u 0x6d2400: off=3267822080/len=512/ddir=0//dev/nvdisk0
io       22444 prep: io_u 0x6d2400: off=3267822080/len=512/ddir=0//dev/nvdisk0
io       22444 ->prep(0x6d2400)=0
io       22444 queue: io_u 0x6d2400: off=3267822080/len=512/ddir=0//dev/nvdisk0
io       22444 fill_io_u: io_u 0x6d2130: off=7099489280/len=512/ddir=0//dev/nvdisk0
io       22444 prep: io_u 0x6d2130: off=7099489280/len=512/ddir=0//dev/nvdisk0
io       22444 ->prep(0x6d2130)=0
io       22444 queue: io_u 0x6d2130: off=7099489280/len=512/ddir=0//dev/nvdisk0
io       22444 fill_io_u: io_u 0x6d1ea0: off=7682447872/len=512/ddir=0//dev/nvdisk0
io       22444 prep: io_u 0x6d1ea0: off=7682447872/len=512/ddir=0//dev/nvdisk0
io       22444 ->prep(0x6d1ea0)=0
io       22444 queue: io_u 0x6d1ea0: off=7682447872/len=512/ddir=0//dev/nvdisk0
io       22444 calling ->commit(), depth 8
io       22444 fill_io_u: io_u 0x6d1b90: off=5983331840/len=512/ddir=0//dev/nvdisk0
io       22444 prep: io_u 0x6d1b90: off=5983331840/len=512/ddir=0//dev/nvdisk0
io       22444 ->prep(0x6d1b90)=0
io       22444 queue: io_u 0x6d1b90: off=5983331840/len=512/ddir=0//dev/nvdisk0
io       22444 fill_io_u: io_u 0x6cdfa0: off=6449852928/len=512/ddir=0//dev/nvdisk0
...

我們可以看到詳細的IO工作過程,這個方法不需要對OS非常的熟悉,比較實用。

還有個方法就是透過strace來跟蹤系統呼叫的情況, 更直觀點。

# pstree -p
init(1)─┬─agent_eagleye(22296)
        ├─screen(13490)─┬─bash(18324)─┬─emacs(19429)
        │               │             ├─emacs(20365)
        │               │             ├─emacs(21268)
        │               │             ├─fio(22452)─┬─fio(22454)
        │               │             │            └─{fio}(22453)
        │               │             └─man(20385)───sh(20386)───sh(20387)───less(20391)
        ├─sshd(1834)───sshd(13115)───bash(13117)───screen(13662)
        └─udevd(705)─┬─udevd(1438)
                     └─udevd(1745
# strace -p 22454
...
io_submit(140534061244416, 8, {{(nil), 0, 1, 0, 3}, {(nil), 0, 0, 0, 3}, {(nil), 0, 0, 0, 3}, {(nil), 0, 0, 0, 3}, {(nil), 0, 0, 0, 3}, {(nil), 0, 1, 0, 3}, {(nil), 0, 1, 0, 3}, {(nil), 0, 0, 0, 3}}) = 8
io_getevents(140534061244416, 8, 8, {{(nil), 0x6d3210, 512, 0}, {(nil), 0x6d2f80, 512, 0}, {(nil), 0x6d2cb0, 512, 0}, {(nil), 0x6d29a0, 512, 0}, {(nil), 0x6d2710, 512, 0}, {(nil), 0x6d2400, 512, 0}, {(nil), 0x6d2130, 512, 0}, {(nil), 0x6d1ea0, 512, 0}}, NULL) = 8
...

最後有效的一招就是用iostat -dx 1來確認你的iodepth是符合裝置特性的。

(由於我用的是nvram卡,這個卡的裝置驅動沒有佇列,iostat看不到佇列深度,就用了其他的裝置的圖代替,表明可以用看iostat看IO佇列深度,謝謝網友Uranus指出)
通過這些方法確認你的配置是對的,之後分析出來的資料才會有意義。

祝玩得開心!

Post Footer automatically generated by wp-posturl plugin for wordpress.

相關推薦

系統技術業餘研究 » Fio工具io佇列深度理解誤區

Fio 是個強大的IO壓力測試工具,我之前寫過不少fio的使用和實踐,參見 這裡。 隨著塊裝置的發展,特別是SSD盤的出現,裝置的並行度越來越高。利用好這些裝置,有個訣竅就是提高裝置的iodepth, 一把餵給裝置更多的IO請求,讓電梯演算法和裝置有機會來安排合併以及內部並行處理,提高總體效率。

系統技術業餘研究 » fio效能測試工具新添圖形前端gfio

gfio.c: In function ‘gfio_ui_setup_log’: gfio.c:322: error: ‘GtkTreeSelection’ undeclared (first use in this function) gfio.c:322: error: ‘selection

系統技術業餘研究 » Fio模擬Mysql伺服器IO壓力指令碼

fio是個非常好用的io壓力模擬工具,功能非常齊全, 有興趣的同學參看 這裡。 這裡我用fio模擬我們線上mysql伺服器的壓力來為廠家送來的pci-ssd卡做壓力測試,底下是指令碼(已經測試正確),也許有的同學有用。 $ cat mysql-test # QPS: 40000(10 core

系統技術業餘研究 » Fio IO效能測試工具介紹

官網:http://freshmeat.net/projects/fio/ fio is an I/O tool meant to be used both for benchmark and stress/hardware verification. It has support for 13

系統技術業餘研究 » fio配合cgroup測試儲存裝置IOPS分配

隨著包括儲存裝置在內伺服器的能力越來越高,特別是用上了PCIe儲存卡後,IOPS能力通常有10幾萬,馬上過剩。在這種情況下,一臺伺服器可以幹很多事情,在上面跑很多服務。那麼如何保證系統的服務質量是個很重要的事情了。 我們在下來的的專案中傾向於用cgroup來做資源的隔離和限制,原因是cgroup的

系統技術業餘研究 » 如何檢視節點的可用控制代碼數目已用控制代碼數

很多同學在使用erlang的過程中, 碰到了很奇怪的問題, 後來查明都是檔案控制代碼不夠用了, 因為系統預設的是每個程序1024. 所以我們有必要在程式執行的時候, 瞭解這些資訊, 以便診斷和預警. 下面的這個程式就演示了這個如何檢視節點的可用控制代碼數目和已用控制代碼數的功能. 首先確保你已經安

系統技術業餘研究 » Erlang虛擬機器基礎設施dtrace探測點介紹使用

最新的Erlang虛擬機器(R15B01)很大的一個改進就是加入了對dtrace探測點的支援了, 具體參見這裡, 主要目標是方便在生產實踐中定位複雜的效能問題。 目前Erlang的虛擬機器的探測點支援Linux的systemtap和freebsd的dtrace,我們剛好能夠享受的到。 作者Scot

系統技術業餘研究 » erlang的profile工具原理優缺點

erlang的tools application下包含了一系列的profile工具, 包括 eprof cprof fprof, 具體的使用可以參看文件和<< erlang effective guide>>. 我這裡要說的是他們的工作原理。 這些模組的核心都是根據erla

系統技術業餘研究 » erl命令列工具鏈的設計思路

erlang otp標準釋出包裡面的命令列工具都在bin目錄下 dialyzer erlc escript typer erlang的這些命令列工具基本上都是erl模組的c的wrapper, 最後都是呼叫erl來執行相應的模組完成任務。 實驗如下: [email protected]:~

系統技術業餘研究 » Tsung壓力測試工具介紹PPT

準備為測試部門的同學作個Tsung的講座, 點選下載Tsung 需要進一步瞭解Tsung的同學 點這裡看官方的文件! 想了解如何使用的還可以到Erlang china這裡看看! Post Footer automatically generated by wp-posturl plugin f

系統技術業餘研究 » systemtap函式呼叫棧資訊不齊的原因解決方法

有時候在看系統程式碼的時候,我們很難從原始碼中看出我們感興趣的函式是如何被呼叫的,因為呼叫路徑有可能太多。使用者空間的程式gdb設斷點是個好的方法,核心的就麻煩了。這時候systemtap可以幫忙, 比如: $uname -r 2.6.18-164.el5 $stap -V Syste

系統技術業餘研究 » Tsung用於MySQL伺服器的指令碼

這個MySQL伺服器壓測的需求是 : 環境: Linux RHEL 5U4 X86-64, 24G記憶體, 16核. MySQL伺服器在xx.232.36.1上。 壓力由最多32個客戶端發起,每個客戶端分別做update, insert, delete操作,概率分別是50%, 30%, 20%

系統技術業餘研究 » Linux下FioBlktrace模擬塊裝置的訪問模式

我們在做塊裝置調優的時候, 我們關心的是塊裝置是如何被訪問的,也就是訪問模式(比如說每次從什麼地方讀,每次讀多少塊,熱點在哪裡等),至於每次讀寫的什麼資料我們並不關心. 這些模式當然可以自己去構造,但是如果能把真實應用的訪問模式記錄下來,並且在調優的時候能重放,我們就可以一遍又一遍的除錯直到達到最

系統技術業餘研究

ItPub寫的文章“2017 年度 DB-Engines 資料庫冠軍得主:PostgreSQL 封王!”, 點選 這裡 進一步閱讀 升的最快的幾個資料庫,我簡單的無責任點評: PG資料庫是很老的資料庫,不過這幾年冉冉升起,因為是學院派的,有很好的學術和智力的支援,一直以來在資料庫的體系結構,程式碼

系統技術業餘研究 » MySQL資料庫架構的演化觀察

MySQL資料庫架構的演化觀察 December 14th, 2017 Categories: 資料庫 Tags: mysql

系統技術業餘研究 » inet_dist_connect_options

Erlang 17.5版本引入了inet_dist_{listen,connect}_options,對於結點間的互聯socket可以有更精細的控制,RPC的時候效能可以微調: raimo/inet_tcp_dist-priority-option/OTP-12476: Document ke

系統技術業餘研究 » 推薦工作機會

最後更新時間:2014/11/28 請賜簡歷至:[email protected], 感謝您對加入我們公司有興趣,我們希望能早日和您共事。 以下幾個職位1年內有效,歡迎內部轉崗:
 資深資料工程師 公司:阿里(核心系統資料庫組) 工作地點:杭州(西溪園區) 崗位描述: 分析雲服務產生的海

系統技術業餘研究 » 新的工作研究方向

和大家更新下: 做了將近8年資料庫後,我的工作和研究方向將會延伸到虛擬化和計算相關的雲服務,希望能夠和大家一起進步,Happy New Year! 預祝大家玩得開心! Post Footer automatically generated by wp-posturl plugin for w

系統技術業餘研究 » 叢集引入inet_dist_{listen,connect}_options更精細引數微調

Erlang 17.5版本引入了inet_dist_{listen,connect}_options,對於結點間的互聯socket可以有更精細的控制,RPC的時候效能可以微調: raimo/inet_tcp_dist-priority-option/OTP-12476: Document ke

系統技術業餘研究 » 2017升的最快的幾個資料庫無責任點評

ItPub寫的文章“2017 年度 DB-Engines 資料庫冠軍得主:PostgreSQL 封王!”, 點選 這裡 進一步閱讀 升的最快的幾個資料庫,我簡單的無責任點評: PG資料庫是很老的資料庫,不過這幾年冉冉升起,因為是學院派的,有很好的學術和智力的支援,一直以來在資料庫的體系結構,程式碼