IO 性能對於一個系統的影響是相當重要的。一個系統通過多項優化之後,瓶頸每每落在數據庫;而數據庫通過多種優化之後,瓶頸最終會落到 IO 。而 IO 性能的發展,明顯落後於 CPU 的發展。 Memchached 也好, NoSql 也好,這些流行技術的背後都在直接或者間接地迴避 IO 瓶頸,從而提升系統性能。html
上圖層次比較多,但總的就是三部分。磁盤 (存儲)、 VM (卷管理)和文件系統 。專有名詞很差理解,打個比方說:磁盤就至關於一塊待用的空地; LVM 至關於空地上的圍牆(把空地劃分紅多個部分);文件系統則至關於每塊空地上建的樓房(決定了有多少房間、房屋編號如何,能容納多少人住);而房子裏面住的人,則至關於系統裏面存的數據。ios
對應了上圖的 File System 和 Buffer Cache 。git
File System (文件系統):解決了空間管理的問題 ,即:數據如何存放、讀取。github
Buffer Cache :解決數據緩衝的問題。對讀,進行 cache ,即:緩存常常要用到的數據;對寫,進行buffer ,緩衝必定數據之後,一次性進行寫入。數據庫
對應上圖的 Vol Mgmt 。編程
VM 其實跟 IO 沒有必然聯繫。他是處於文件系統和磁盤(存儲)中間的一層。 VM 屏蔽了底層磁盤對上層文件系統的影響 。當沒有 VM 的時候,文件系統直接使用存儲上的地址空間,所以文件系統直接受限於物理硬盤,這時若是發生磁盤空間不足的狀況,對應用而言將是一場噩夢,不得不新增硬盤,而後從新進行數據複製。而 VM 則能夠實現動態擴展,而對文件系統沒有影響。另外, VM 也能夠把多個磁盤合併成一個磁盤,對文件系統呈現統一的地址空間,這個特性的殺傷力不言而喻。緩存
對應上圖的 Device Driver 、 IO Channel 和 Disk Device安全
數據最終會放在這裏,所以,效率、數據安全、容災是這裏須要考慮的問題。而提升存儲的性能,則能夠直接提升物理 IO 的性能網絡
邏輯 IO 是操做系統發起的 IO ,這個數據可能會放在磁盤上,也可能會放在內存(文件系統的 Cache )裏。oracle
物理 IO 是設備驅動發起的 IO ,這個數據最終會落在磁盤上。
邏輯 IO 和物理 IO 不是一一對應的。
這部分的東西在網絡編程常常能看到,不過在全部IO處理中都是相似的。
等待資源階段:IO請求通常須要請求特殊的資源(如磁盤、RAM、文件),當資源被上一個使用者使用沒有被釋放時,IO請求就會被阻塞,直到可以使用這個資源。
使用資源階段:真正進行數據接收和發生。
舉例說就是排隊和服務。
阻塞IO:資源不可用時,IO請求一直阻塞,直到反饋結果(有數據或超時)。
非阻塞IO:資源不可用時,IO請求離開返回,返回數據標識資源不可用
同步IO:應用阻塞在發送或接收數據的狀態,直到數據成功傳輸或返回失敗。
異步IO:應用發送或接收數據後馬上返回,數據寫入OS緩存,由OS完成數據發送或接收,並返回成功或失敗的信息給應用。
從性能上看,異步IO的性能無疑是最好的。
阻塞IO:使用簡單,但隨之而來的問題就是會造成阻塞,須要獨立線程配合,而這些線程在大多數時候都是沒有進行運算的。Java的BIO使用這種方式,問題帶來的問題很明顯,一個Socket須要一個獨立的線程,所以,會形成線程膨脹。
非阻塞IO:採用輪詢方式,不會造成線程的阻塞。Java的NIO使用這種方式,對比BIO的優點很明顯,可使用一個線程進行全部Socket的監聽(select)。大大減小了線程數。
同步IO:同步IO保證一個IO操做結束以後纔會返回,所以同步IO效率會低一些,可是對應用來講,編程方式會簡單。Java的BIO和NIO都是使用這種方式進行數據處理。
異步IO:因爲異步IO請求只是寫入了緩存,從緩存到硬盤是否成功不可知,所以異步IO至關於把一個IO拆成了兩部分,一是發起請求,二是獲取處理結果。所以,對應用來講增長了複雜性。可是異步IO的性能是全部很好的,並且異步的思想貫穿了IT系統放放面面。
最重要的三個指標
IOPS,Input/Output Per Second,即每秒鐘處理的I/O請求數量。IOPS是隨機訪問類型業務(OLTP類)很重要的一個參考指標。
從磁盤上進行數據讀取時,比較重要的幾個時間是:尋址時間(找到數據塊的起始位置),旋轉時間(等待磁盤旋轉到數據塊的起始位置),傳輸時間(讀取數據的時間和返回的時間)。其中尋址時間是固定的(磁頭定位到數據的存儲的扇區便可),旋轉時間受磁盤轉速的影響,傳輸時間受數據量大小的影響和接口類型的影響(不用硬盤接口速度不一樣),可是在隨機訪問類業務中,他的時間也不多。所以,在硬盤接口相同的狀況下,IOPS主要受限於尋址時間和傳輸時間。以一個15K的硬盤爲例,尋址時間固定爲4ms,傳輸時間爲60s/15000 * 1/2=2ms,忽略傳輸時間。1000ms/6ms=167個IOPS。
常見磁盤平均物理尋道時間爲:
7200RPM(轉)/分的STAT硬盤平均物理尋道時間是9ms,平均旋轉延遲大約 4.17ms
10000RPM(轉)/分的SAS硬盤平均物理尋道時間是6ms ,平均旋轉延遲大約 3ms
15000RPM(轉)/分的SAS硬盤平均物理尋道時間是4ms,平均旋轉延遲大約 2ms
最大IOPS的理論計算方法:IOPS = 1000 ms/ (尋道時間 + 旋轉延遲)。忽略數據傳輸時間。
7200 rpm的磁盤IOPS = 1000 / (9 + 4.17) = 76 IOPS
10000 rpm的磁盤IOPS = 1000 / (6+ 3) = 111 IOPS
15000 rpm的磁盤IOPS = 1000 / (4 + 2) = 166 IOPS
RAID0/RAID5/RAID6的多塊磁盤能夠並行工做,因此,在這樣的硬件條件下, IOPS 相應倍增。假如, 兩塊15000 rpm 磁盤的話,166 * 2 = 332 IOPS。
維基上列出了常見硬盤的IOPS
SSD 達到了驚人的100,000。 見下圖
固態硬盤沒有尋道時間和旋轉時間。IO耗時是經過地址查找數據耗時,根據芯片顆粒SLC、MLC,中控芯片、隊列深度32~6四、接口Sata、PCIE的不一樣,通常負載非過高時是相對固定值(控制在60%利用率)。
IOPS = 1000/IO耗時。由於SSD比較固定,好比Intel 320 SSD對8K avgrq-sz耗時0.1ms,1000/0.1ms=10000 IOPS。
在沒有文件系統、沒有VM(卷管理)、沒有RAID、沒有存儲設備的狀況下,這個答案仍是成立的。可是當這麼多中間層加進去之後,這個答案就不是這樣了。物理硬盤提供的IO是有限的,也是整個IO系統存在瓶頸的最大根源。因此,若是一塊硬盤不能提供,那麼多塊在一塊兒並行處理,這不就好了嗎?確實是這樣的。能夠看到,越是高端的存儲設備的cache越大,硬盤越多,一方面經過cache異步處理IO,另外一方面經過盤數增長,儘量把一個OS的IO分佈到不一樣硬盤上,從而提升性能。文件系統則是在cache上會影響,而VM則多是一個IO分佈到多個不一樣設備上(Striping)。
因此,一個OS的IO在通過多箇中間層之後,發生在物理磁盤上的IO是不肯定的。多是一對一個,也可能一個對應多個。
對單塊磁盤的IOPS的計算沒有沒問題,可是當系統後面接的是一個存儲系統時、考慮不一樣讀寫比例,IOPS則很難計算,而須要根據實際狀況進行測試。主要的因素有:
存儲系統自己有本身的緩存。緩存大小直接影響IOPS,理論上說,緩存越大能cache的東西越多,在cache命中率保持的狀況下,IOPS會越高。
RAID級別。不一樣的RAID級別影響了物理IO的效率。
讀寫混合比例。對讀操做,通常只要cache能足夠大,能夠大大減小物理IO,而都在cache中進行;對寫操做,不論cache有多大,最終的寫仍是會落到磁盤上。所以,100%寫的IOPS要越獄小於100%的讀的IOPS。同時,100%寫的IOPS大體等同於存儲設備能提供的物理的IOPS。
一次IO請求數據量的多少。一次讀寫1KB和一次讀寫1MB,顯而易見,結果是徹底不一樣的。
當時上面N多因素混合在一塊兒之後,IOPS的值就變得撲朔迷離了。因此,通常須要經過實際應用的測試才能得到。
即IO的響應時間。IO響應時間是從操做系統內核發出一個IO請求到接收到IO響應的時間。所以,IO Response time除了包括磁盤獲取數據的時間,還包括了操做系統以及在存儲系統內部IO等待的時間。通常看,隨IOPS增長,由於IO出現等待,IO響應時間也會隨之增長。對一個OLTP系統,10ms之內的響應時間,是比較合理的。下面是一些IO性能示例:
須要注意,IOPS與IO Response Time有着密切的聯繫。通常狀況下,IOPS增長,說明IO請求多了,IO Response Time會相應增長。可是會出現IOPS一直增長,可是IO Response Time變得很是慢,超過20ms甚至幾十ms,這時候的IOPS雖然還在提升,可是意義已經不大,由於整個IO系統的服務時間已經不可取。
爲吞吐量。這個指標衡量標識了最大的數據傳輸量。如上說明,這個值在順序訪問或者大數據量訪問的狀況下會比較重要。尤爲在大數據量寫的時候。
吞吐量不像IOPS影響因素不少,吞吐量通常受限於一些比較固定的因素,如:網絡帶寬、IO傳輸接口的帶寬、硬盤接口帶寬等。通常他的值就等於上面幾個地方中某一個的瓶頸。
即單個IO操做請求數據的大小。一次IO操做是指從發出IO請求到返回數據的過程。IO Chunk Size與應用或業務邏輯有着很密切的關係。好比像Oracle一類數據庫,因爲其block size通常爲8K,讀取、寫入時都此爲單位,所以,8K爲這個系統主要的IO Chunk Size。IO Chunk Size 小,考驗的是IO系統的IOPS能力;IO Chunk Size 大,考驗的時候IO系統的IO吞吐量。
熟悉數據庫的人都知道,SQL是能夠批量提交的,這樣能夠大大提升操做效率。IO請求也是同樣,IO請求能夠積累必定數據,而後一次提交到存儲系統,這樣一些相鄰的數據塊操做能夠進行合併,減小物理IO數。並且Queue Deep如其名,就是設置一塊兒提交的IO請求數量的。通常Queue Deep在IO驅動層面上進行配置。
Queue Deep與IOPS有着密切關係。Queue Deep主要考慮批量提交IO請求,天然只有IOPS是瓶頸的時候纔會有意義,若是IO都是大IO,磁盤已經成瓶頸,Queue Deep意義也就不大了。通常來講,IOPS的峯值會隨着Queue Deep的增長而增長(不會很是顯著),Queue Deep通常小於256。
隨機訪問的特色是每次IO請求的數據在磁盤上的位置跨度很大(如:分佈在不一樣的扇區),所以N個很是小的IO請求(如:1K),必須以N次IO請求才能獲取到相應的數據。
順序訪問的特色跟隨機訪問相反,它請求的數據在磁盤的位置是連續的。當系統發起N個很是小的IO請求(如:1K)時,由於一次IO是有代價的,系統會取完整的一塊數據(如4K、8K),因此當第一次IO完成時,後續IO請求的數據可能已經有了。這樣能夠減小IO請求的次數。這也就是所謂的預取。
隨機訪問和順序訪問一樣是有應用決定的。如數據庫、小文件的存儲的業務,大可能是隨機IO。而視頻類業務、大文件存取,則大多爲順序IO。
以上各指標中,不用的應用場景須要觀察不一樣的指標,由於應用場景不一樣,有些指標甚至是沒有意義的。
隨機訪問和IOPS: 在隨機訪問場景下,IOPS每每會到達瓶頸,而這個時候去觀察Throughput,則每每遠低於理論值。
順序訪問和Throughput:在順序訪問的場景下,Throughput每每會達到瓶頸(磁盤限制或者帶寬),而這時候去觀察IOPS,每每很小。
與 CPU 不一樣,不一樣環境下,磁盤的性能指標與廠家標稱會不一致。所以,在性能分析前,對所在的計算環境進行標定是頗有必要的。
目前主流的第三方IO測試工具備fio、iometer 和 Orion,這三種工具各有千秋。
fio 在 Linux 系統下使用比較方便,iometer 在 window 系統下使用比較方便,Orion 是 oracle 的IO測試軟件,可在沒有安裝 oracle 數據庫的狀況下模擬 oracle 數據庫場景的讀寫。
FIO是測試IOPS的很是好的工具,用來對硬件進行壓力測試和驗證,支持13種不一樣的I/O引擎,包括:sync,mmap,libaio,posixaio,SGv3,splice,null,network,syslet,guasi,solarisaio等等。
在FIO官網地址下載最新文件,解壓後./configure、make、make install 就可使用fio了。
可使用fio -help查看每一個參數,具體的參數左右能夠在官網查看how to文檔,以下爲幾個常見的參數描述
filename=/dev/emcpowerb 支持文件系統或者裸設備,-filename=/dev/sda2或-filename=/dev/sdb direct=1 測試過程繞過機器自帶的buffer,使測試結果更真實 rw=randwread 測試隨機讀的I/O rw=randwrite 測試隨機寫的I/O rw=randrw 測試隨機混合寫和讀的I/O rw=read 測試順序讀的I/O rw=write 測試順序寫的I/O rw=rw 測試順序混合寫和讀的I/O bs=4k 單次io的塊文件大小爲4k bsrange=512-2048 同上,提定數據塊的大小範圍 size=5g 本次的測試文件大小爲5g,以每次4k的io進行測試 numjobs=30 本次的測試線程爲30 runtime=1000 測試時間爲1000秒,若是不寫則一直將5g文件分4k每次寫完爲止 ioengine=psync io引擎使用pync方式,若是要使用libaio引擎,須要yum install libaio-devel包 rwmixwrite=30 在混合讀寫的模式下,寫佔30% group_reporting 關於顯示結果的,彙總每一個進程的信息 此外 lockmem=1g 只使用1g內存進行測試 zero_buffers 用0初始化系統buffer nrfiles=8 每一個進程生成文件的數量
測試場景
100%隨機,100%讀, 4K fio -filename=/dev/emcpowerb -direct=1 -iodepth 1 -thread -rw=randread -ioengine=psync -bs=4k -size=1000G -numjobs=50 -runtime=180 -group_reporting -name=rand_100read_4k 100%隨機,100%寫, 4K fio -filename=/dev/emcpowerb -direct=1 -iodepth 1 -thread -rw=randwrite -ioengine=psync -bs=4k -size=1000G -numjobs=50 -runtime=180 -group_reporting -name=rand_100write_4k 100%順序,100%讀 ,4K fio -filename=/dev/emcpowerb -direct=1 -iodepth 1 -thread -rw=read -ioengine=psync -bs=4k -size=1000G -numjobs=50 -runtime=180 -group_reporting -name=sqe_100read_4k 100%順序,100%寫 ,4K fio -filename=/dev/emcpowerb -direct=1 -iodepth 1 -thread -rw=write -ioengine=psync -bs=4k -size=1000G -numjobs=50 -runtime=180 -group_reporting -name=sqe_100write_4k 100%隨機,70%讀,30%寫 4K fio -filename=/dev/emcpowerb -direct=1 -iodepth 1 -thread -rw=randrw -rwmixread=70 -ioengine=psync -bs=4k -size=1000G -numjobs=50 -runtime=180 -group_reporting -name=randrw_70read_4k
實際測試
fio -filename=/dev/sda -direct=1 -iodepth 1 -thread -rw=randrw -rwmixread=70 -ioengine=psync -bs=16k -size=200G -numjobs=30 -runtime=100 -group_reporting -name=mytest -ioscheduler=noop
上述命令,進行隨機讀寫測試。隊列深度爲1。
VM (long time running) 是 測試用的虛擬機。這臺 VM的磁盤性能極低。只有兩位數。同一臺 ESXi 上的另外一臺 VM(new build ),磁盤性能很正常。二者的區別在於,前者不是新裝,而是一直跑 volume test 。後者是新安裝的。
用途:主要用於監控系統設備的IO負載狀況,iostat首次運行時顯示自系統啓動開始的各項統計信息,以後運行iostat將顯示自上次運行該命令之後的統計信息。用戶能夠經過指定統計的次數和時間來得到所需的統計信息。
缺點:iostat有一個弱點,就是它不能對某個進程進行深刻分析,僅對系統的總體狀況進行分析。iostat屬於sysstat軟件包。能夠用yum install sysstat 直接安裝。
命令格式:
iostat[參數][時間][次數]
命令參數: • -C 顯示CPU使用狀況 • -d 顯示磁盤使用狀況 • -k 以 KB 爲單位顯示 • -m 以 M 爲單位顯示 • -N 顯示磁盤陣列(LVM) 信息 • -n 顯示NFS 使用狀況 • -p[磁盤] 顯示磁盤和分區的狀況 • -t 顯示終端和CPU的信息 • -x 顯示詳細信息 • -V 顯示版本信息
如上圖,每1秒鐘顯示一次報告
iostat -x 2 6 /dev/sda1
每兩秒鐘顯示一次sda1的統計報告,共顯示6次。
CPU 屬性值
• %user:CPU處在用戶模式下的時間百分比。 • %nice:CPU處在帶NICE值的用戶模式下的時間百分比。 • %system:CPU處在系統模式下的時間百分比。 • %iowait:CPU等待輸入輸出完成時間的百分比。 • %steal:管理程序維護另外一個虛擬處理器時,虛擬CPU的無心識等待時間百分比。 • %idle:CPU空閒時間百分比。
設備屬性值
備註: • 若是%iowait的值太高,表示硬盤存在I/O瓶頸, • %idle值高,表示CPU較空閒, • 若是%idle值高但系統響應慢時,有多是CPU等待分配內存,此時應加大內存容量。 • %idle值若是持續低於10,那麼系統的CPU處理能力相對較低,代表系統中最須要解決的資源是CPU。 磁盤每一列的含義以下: • rrqm/s: 每秒進行 merge 的讀操做數目。 即 rmerge/s • wrqm/s: 每秒進行 merge 的寫操做數目。即 wmerge/s • r/s: 每秒完成的讀 I/O 設備次數。 即 rio/s • w/s: 每秒完成的寫 I/O 設備次數。即 wio/s • rsec/s: 每秒讀扇區數。即 rsect/s • wsec/s: 每秒寫扇區數。即 wsect/s • rkB/s: 每秒讀 K 字節數。是 rsect/s 的一半,由於扇區大小爲 512 字節 • wkB/s: 每秒寫 K 字節數。是 wsect/s 的一半 • avgrq-sz: 平均每次設備 I/O 操做的數據大小(扇區) • avgqu-sz: 平均 I/O 隊列長度。 • await: 平均每次設備 I/O 操做的等待時間(毫秒) • r_await:每一個讀操做平均所需的時間=[Δrd_ticks/Δrd_ios] 不只包括硬盤設備讀操做的時間,還包括了在kernel隊列中等待的時間。 • w_await:每一個寫操做平均所需的時間=[Δwr_ticks/Δwr_ios] 不只包括硬盤設備寫操做的時間,還包括了在kernel隊列中等待的時間。 • svctm: 平均每次設備 I/O 操做的服務時間(毫秒) • %util: 一秒中有百分之多少的時間用於 I/O 操做,或者說一秒中有多少時間 I/O 隊列是非空的。 備註: • 若是 %util 接近 100%,說明產生的I/O請求太多,I/O系統已經滿負荷,該磁盤可能存在瓶頸。 • 若是 svctm 比較接近 await,說明 I/O 幾乎沒有等待時間; • 若是 await 遠大於 svctm,說明I/O 隊列太長,io響應太慢,則須要進行必要優化。 • 若是avgqu-sz比較大,也表示有當量io在等待。
在某些場景下,咱們須要找到佔用IO特別大的進程,而後關閉它,須要知道PID或者進程名稱,這就須要用到iotop。iotop是一個檢測Linux系統進程IO的工具,界面相似top,以下圖。
iotop和top同樣,也能夠經過鍵入相應鍵,觸發排序選項,例如按o能夠在IO活動進程和全部進程之間切換。能夠經過左右箭頭,選擇響應的列進行數據排序。
iotop的經常使用參數以下:
-h, --help 查看幫助信息 -o, --only 只查看有IO操做的進程 -b, --batch 非交互模式 -n, --iter= 設置迭代次數 -d, --delay 刷新頻率,默認是1秒 -p, --pid 查看指定的進程號的IO,默認是全部進程 -u, --user 查看指定用戶進程的IO,默認是全部用戶 -P, --processes 只看進程,不看線程 -a, --accumulated 看累計IO,而不是實時IO -k, --kilobytes 以KB爲單位查看IO,而不是以最友好的單位顯示 -t, --time 每行添加一個時間戳,默認便開啓--batch -q, --quit 不顯示頭部信息
blktrace是一柄神器,不少工具都是基於該神器的:ioprof,seekwatcher,iowatcher,這個工具基本能夠知足咱們的對塊設備請求的全部瞭解。
一個I/O請求,從應用層到底層塊設備,路徑以下圖所示:
從上圖能夠看出IO路徑是很複雜的。這麼複雜的IO路徑咱們是沒法用短短一篇小博文介紹清楚的。咱們將IO路徑簡化一下:
一個I/O請求進入block layer以後,可能會經歷下面的過程:
blktrace 可以記錄下IO所經歷的各個步驟:
咱們一塊兒看下blktrace的輸出長什麼樣子:
第一個字段:8,0 這個字段是設備號 major device ID和minor device ID。
第二個字段:3 表示CPU
第三個字段:11 序列號
第四個字段:0.009507758 Time Stamp是時間偏移
第五個字段:PID 本次IO對應的進程ID
第六個字段:Event,這個字段很是重要,反映了IO進行到了那一步
第七個字段:R表示 Read, W是Write,D表示block,B表示Barrier Operation
第八個字段:223490+56,表示的是起始block number 和 number of blocks,即咱們常說的Offset 和 Size
第九個字段: 進程名
其中第六個字段很是有用:每個字母都表明了IO請求所經歷的某個階段。
Q – 即將生成IO請求 | G – IO請求生成 | I – IO請求進入IO Scheduler隊列 | D – IO請求進入driver | C – IO請求執行完畢
注意,整個IO路徑,分紅不少段,每一段開始的時候,都會有一個時間戳,根據上一段開始的時間和下一段開始的時間,就能夠獲得IO 路徑各段花費的時間。
注意,咱們心心念唸的service time,也就是反應塊設備處理能力的指標,就是從D到C所花費的時間,簡稱D2C。
而iostat輸出中的await,即整個IO從生成請求到IO請求執行完畢,即從Q到C所花費的時間,咱們簡稱Q2C。
僅僅查看數據進行分析,很是的不直觀。工具 iowatcher 能夠把 blktrace 採集的信息,轉化爲圖像和動畫,方便分析。
iowatcher -t sda.blktrace.bin -o disk.svg iowatcher -t sda.blktrace.bin --movie -o disk.mp4
首先,咱們看 VM volume test 的圖像:
說說IO(一)- IO的分層
說說IO(二)- IO模型
說說IO(三)- IO性能的重要指標
說說IO(四)- 文件系統
說說IO(五)- 邏輯卷管理
說說IO(六)- Driver & IO Channel
說說IO(七)- RAID
說說IO(八)- 三分天下
磁盤性能分析
IO測試工具之fio詳解
blktrace分析IO