Linux IO系統(tǒng)的架構(gòu)圖

一.設(shè)備-------- 影響磁盤性能的因素
硬盤的轉(zhuǎn)速影響硬盤的整體性能。一般情況下轉(zhuǎn)速越大,性能會越好。
硬盤的性能因素主要包括兩個:1.平均訪問時間2傳輸速率。
平均訪問時間包括兩方面因素:
平均尋道時間(Average Seek Time)是指硬盤的磁頭移動到盤面指定磁道所需的時間。一般在3ms至15ms之間。
平均旋轉(zhuǎn)等待時間(Latency)是指磁頭已處于要訪問的磁道,等待所要訪問的扇區(qū)旋轉(zhuǎn)至磁頭下方的時間。一般在2ms至6ms之間。
傳輸速率(Data Transfer Rate) 硬盤的數(shù)據(jù)傳輸率是指硬盤讀寫數(shù)據(jù)的速度,單位為兆字節(jié)每秒(MB/s)。磁盤每秒能傳輸80M~320M字節(jié)。
傳輸速率包括內(nèi)部傳輸速率和外部傳輸速率。
內(nèi)部傳輸率(Internal Transfer Rate) 也稱為持續(xù)傳輸率(Sustained Transfer Rate),它反映了硬盤緩沖區(qū)未用時的性能。內(nèi)部傳輸率主要依賴于硬盤的旋轉(zhuǎn)速度。
外部傳輸率(External Transfer Rate)也稱為突發(fā)數(shù)據(jù)傳輸率(Burst Data Transfer Rate)或接口傳輸率,它標稱的是系統(tǒng)總線與硬盤緩沖區(qū)之間的數(shù)據(jù)傳輸率,外部數(shù)據(jù)傳輸率與硬盤接口類型和硬盤緩存的大小有關(guān)。STAT2 的傳輸速率在300MB/s級別。
因此在硬件級上,提高磁盤性能的關(guān)鍵主要是降低平均訪問時間。
二.設(shè)備驅(qū)動
內(nèi)存到硬盤的傳輸方式:poll,中斷,DMA
DMA:當 CPU 初始化這個傳輸動作,傳輸動作本身是由 DMA 控制器 來實行和完成。
DMA控制器獲得總線控制權(quán)后,CPU即刻掛起或只執(zhí)行內(nèi)部操作,由DMA控制器輸出讀寫命令,直接控制RAM與I/O接口進行DMA傳輸。DMA每次傳送的是磁盤上相鄰的扇區(qū)。Scatter-gather DMA允許傳送不相鄰的扇區(qū)。
CPU性能與硬盤與內(nèi)存的數(shù)據(jù)傳輸速率關(guān)系不大。
設(shè)備驅(qū)動內(nèi)有一個結(jié)構(gòu)管理著IO的請求隊列
structrequest_queue(include/linux/Blkdev.h)
這里不僅僅有讀寫請求的數(shù)據(jù)塊,還有用于IO調(diào)度的回調(diào)函數(shù)結(jié)構(gòu)。每次需要傳輸?shù)臅r候,就從隊列中選出一個數(shù)據(jù)塊交給DMA進行傳輸。
所以IO調(diào)度的回調(diào)函數(shù)這是降低平均訪問的時間的關(guān)鍵。
三.OS
IO調(diào)度器
Linux kernel提供了四個調(diào)度器供用戶選擇。他們是noop,cfq,deadline,as。可以在系統(tǒng)啟動時設(shè)置內(nèi)核參數(shù)elevator=<name>來指定默認的調(diào)度器。也可以在運行時為某個塊設(shè)備設(shè)置IO調(diào)度程序。
下面來簡要介紹這四個調(diào)度器的電梯調(diào)度算法。
Noop:最簡單的調(diào)度算法。新的請求總是被添加到隊頭或者隊尾,然后總是從隊頭中選出將要被處理的請求。
CFQ:(Complete FarinessQueueing)它的目標是在所有請求的進程中平均分配IO的帶寬。因此,它會根據(jù)進程創(chuàng)建自己的請求隊列,然后將IO請求放入相應(yīng)的隊列中。在使用輪轉(zhuǎn)法從每個非空的隊列中取出IO請求。
Deadline:使用了四個隊列,兩個以磁盤塊序號排序的讀寫隊列,兩個以最后期限時間排序的讀寫隊列。算法首先確定下一個讀寫的方向,讀的優(yōu)先級高于寫。然后檢查被選方向的最后期限隊列:如果最后期限時間的隊列中有超時的請求,則將剛才的請求移動至隊尾,然后在磁盤號排序隊列中從超時請求開始處理。當處理完一個方向的請求后,在處理另一個方向的請求。(讀請求的超時時間是500ms,寫請求的超時時間是5s)
Anticipatory:它是最復(fù)雜的IO調(diào)度算法。和deadline算法一樣有四個隊列。還附帶了一些啟發(fā)式策略。它會從當前的磁頭位置后的磁盤號中選擇請求。在調(diào)度了一個由P進程的IO請求后,會檢查下一個請求,如果還是P進程的請求,則立即調(diào)度,如果不是,同時預(yù)測P進程很快會發(fā)出請求,則還延長大約7ms的時間等待P進程的IO請求。
Write/Read函數(shù)
以ext3的write為例:
系統(tǒng)調(diào)用write()的作用就是修改頁高速緩存內(nèi)的一些頁的內(nèi)容,如果頁高速緩存內(nèi)沒有所要的頁則分配并追加這些頁。
當臟頁達到一定數(shù)量或者超時后,將臟頁刷回硬盤。也可以執(zhí)行相關(guān)系統(tǒng)調(diào)用。
為什么要達到一定數(shù)量,是因為延遲寫能在一定層度上提高系統(tǒng)的性能,這也使得塊設(shè)備的平均讀請求會多于寫請求。
在程序中調(diào)用write函數(shù),將進入系統(tǒng)調(diào)用f_op->write。這個函數(shù)將調(diào)用ext3的do_sync_write。這個函數(shù)將參數(shù)封裝后調(diào)用generic_file_aio_write。由參數(shù)名可以看出同步寫變成了異步寫。如果沒有標記O_DIRECT,將調(diào)用函數(shù)generic_file_buffered_write將寫的內(nèi)容寫進kernel的高速頁緩存中。Buffer是以page為單位即4k。之后當調(diào)用cond_resched()進行進程的調(diào)度,DMA會將buffer中的內(nèi)容寫進硬盤。
所以當每次以4k為單位寫入硬盤時效率會達到最高。下面是UNIX環(huán)境高級編程的實驗結(jié)果:

下圖是linux 的塊設(shè)備的數(shù)據(jù)操作層次:
Sector扇區(qū):是設(shè)備驅(qū)動和IO調(diào)度程序處理數(shù)據(jù)粒度。
Block塊:是VFS和文件系統(tǒng)處理數(shù)據(jù)的粒度。其大小不唯一,可以是512,1024,2048,4096字節(jié)。內(nèi)核操作的塊大小是4096字節(jié)。
Segment段:是DMA傳送的單位。每一個段包含了相鄰的扇區(qū),它能使DMA傳送不相鄰的扇區(qū)。

四.用戶程序
根據(jù)以上的分析,我們的write buffer一般設(shè)置為4K的倍數(shù)。
在程序中有意識的延遲寫。這個是os的策略,當然也可以應(yīng)用到程序的設(shè)計中。當然也會有缺點:1.如果硬件錯誤或掉電,則會丟失內(nèi)容(做額外的備份)2.需要額外的內(nèi)存空間。(犧牲內(nèi)存來提高IO的效率)
我們還需根據(jù)系統(tǒng)的IO調(diào)度器的調(diào)度策略,設(shè)計出不同的IO策略。盡量降低磁盤的平均訪問時間,降低請求隊列,提高數(shù)據(jù)傳輸?shù)乃俾省?/span>
五.監(jiān)控硬盤的工具和指標
Iostat–x –k 1
-x顯示更多的消息 -k數(shù)據(jù)以KB為單位 1每秒顯示一次
輸出顯示的信息
Iowait:cpu等待未完成的IO請求而空閑的時間的比例。
Idle:cpu空閑且無IO請求的比例。
rrqm/s:每秒這個設(shè)備相關(guān)的讀取請求有多少被Merge了。
wrqm/s:每秒這個設(shè)備相關(guān)的寫入請求有多少被Merge了。
rsec/s:每秒讀取的扇區(qū)數(shù);
wsec/:每秒寫入的扇區(qū)數(shù)。
r/s:每秒完成的讀 I/O 設(shè)備次數(shù)。即 delta(rio)/s
w/s:每秒完成的寫 I/O 設(shè)備次數(shù)。即 delta(wio)/s
await:每一個IO請求的處理的平均時間(單位是毫秒)。包括加入請求隊列和服務(wù)的時間。
svctm: 平均每次設(shè)備I/O操作的服務(wù)時間。
avgrq-sz: 平均每次設(shè)備I/O操作的數(shù)據(jù)大小 (扇區(qū))。即 delta(rsect+wsect)/delta(rio+wio)
avgqu-sz: 平均I/O隊列長度。即 delta(aveq)/s/1000 (因為aveq的單位為毫秒)。
%util:在統(tǒng)計時間內(nèi)所有處理IO時間,除以總共統(tǒng)計時間。例如,如果統(tǒng)計間隔1秒,該設(shè)備有0.8秒在處理IO,而0.2秒閑置,那么該設(shè)備的%util = 0.8/1 = 80%,所以該參數(shù)暗示了設(shè)備的繁忙程度。一般地,如果該參數(shù)是100%表示設(shè)備已經(jīng)接近滿負荷運行了(當然如果是多磁盤,即使%util是100%,因為磁盤的并發(fā)能力,所以磁盤使用未必就到了瓶頸)。
下面我們做一個實驗來分析一下
我們使用命令
time dd if=/dev/zero of=/home/zhouyuan/mytest bs=1M count=3000
向mytest寫入數(shù)據(jù),寫入3G。
截取部分的狀態(tài)監(jiān)控:



如圖2,當兩條數(shù)據(jù) iowait 達到了 99% 以上,寫入的數(shù)據(jù)是0,這是因為DMA將內(nèi)存的中的數(shù)據(jù)傳輸給設(shè)備。結(jié)合圖1的前兩條數(shù)據(jù),利用率達到了99%+卻沒有寫入的磁盤塊。
如圖3,iowait下降,說明cpu開始執(zhí)行相關(guān)程序,而此時塊設(shè)備開始寫入的數(shù)據(jù)。這兩個操作是異步進行的。
Vmstat–k –n 1
Swap
si: 從磁盤交換到內(nèi)存的交換頁數(shù)量,單位:KB/秒
so: 從內(nèi)存交換到磁盤的交換頁數(shù)量,單位:KB/秒
IO
bi: 從塊設(shè)備接受的塊數(shù),單位:塊/秒
bo: 發(fā)送到塊設(shè)備的塊數(shù),單位:塊/秒


從圖中我們可以看出系統(tǒng)的延遲寫。