漫談linux文件IO

原文轉自:http://blog.chinaunix.net/uid-27105712-id-3270102.htmlhtml

在Linux 開發中,有幾個關係到性能的東西,技術人員很是關注:進程,CPU,MEM,網絡IO,磁盤IO。本篇文件打算詳細全面,深刻淺出。剖析文件IO的細節。從多個角度探索如何提升IO性能。本文儘可能用通俗易懂的視角去闡述。不copy內核代碼。node

闡述以前,要先有個大視角,讓咱們站在萬米高空,鳥瞰咱們的文件IO,它們設計是分層的,分層有2個好處,一是架構清晰,二是解耦。讓咱們看一下下面這張圖。linux

 clip_image002

圖一ios

1.       穿越各層寫文件方式

程序的最終目的是要把數據寫到磁盤上, 可是系統從通用性和性能角度,儘可能提供一個折中的方案來保證這些。讓咱們來看一個最經常使用的寫文件典型example,也是路徑最長的IO。算法

[cpp]  view plain copy
  1. {  
  2.     char *buf = malloc(MAX_BUF_SIZE);  
  3.   
  4.     strncpy(buf, src, , MAX_BUF_SIZE);  
  5.   
  6.     fwrite(buf, MAX_BUF_SIZE, 1, fp);  
  7.   
  8.     fclose(fp);  
  9. }   

這裏malloc的buf對於圖層中的application buffer,即應用程序的buffer;調用fwrite後,把數據從application buffer 拷貝到了 CLib buffer,即C庫標準IObuffer。fwrite返回後,數據還在CLib buffer,若是這時候進程core掉。這些數據會丟失。沒有寫到磁盤介質上。當調用fclose的時候,fclose調用會把這些數據刷新到磁盤介質上。除了fclose方法外,還有一個主動刷新操做fflush函數,不過fflush函數只是把數據從CLib buffer 拷貝到page  cache 中,並無刷新到磁盤上,從page cache刷新到磁盤上能夠經過調用fsync函數完成。緩存

從上面類子看到,一個經常使用的fwrite函數過程,基本上歷經千辛萬苦,數據通過屢次copy,纔到達目的地。有人心生疑問,這樣會提升性能嗎,反而會下降性能吧。這個問題先放一放。安全

有人說,我不想經過fwrite+fflush這樣組合,我想直接寫到page cache。這就是咱們常見的文件IO調用read/write函數。這些函數基本上是一個函數對應着一個系統調用,如sys_read/sys_write. 調用write函數,是直接經過系統調用把數據從應用層拷貝到內核層,從application buffer 拷貝到 page cache 中。網絡

系統調用,write會觸發用戶態/內核態切換?是的。那有沒有辦法避免這些消耗。這時候該mmap出場了,mmap把page cache 地址空間映射到用戶空間,應用程序像操做應用層內存同樣,寫文件。省去了系統調用開銷。數據結構

那若是繼續刨根問底,若是想繞過page cache,直接把數據送到磁盤設備上怎麼辦。經過open文件帶上O_DIRECT參數,這是write該文件。就是直接寫到設備上。架構

若是繼續較勁,直接寫扇區有沒有辦法。這就是所謂的RAW設備寫,繞開了文件系統,直接寫扇區,想fdsik,dd,cpio之類的工具就是這一類操做。

2.       IO調用鏈

列舉了上述各類穿透各類cache 層寫操做,能夠看到系統提供的接口至關豐富,知足你各類寫要求。下面經過講解圖一,瞭解一下文件IO的調用鏈。

fwrite是系統提供的最上層接口,也是最經常使用的接口。它在用戶進程空間開闢一個buffer,將屢次小數據量相鄰寫操做先緩存起來,合併,最終調用write函數一次性寫入(或者將大塊數據分解屢次write調用)。

Write函數經過調用系統調用接口,將數據從應用層copy到內核層,因此write會觸發內核態/用戶態切換。當數據到達page cache後,內核並不會當即把數據往下傳遞。而是返回用戶空間。數據何時寫入硬盤,有內核IO調度決定,因此write是一個異步調用。這一點和read不一樣,read調用是先檢查page cache裏面是否有數據,若是有,就取出來返回用戶,若是沒有,就同步傳遞下去並等待有數據,再返回用戶,因此read是一個同步過程。固然你也能夠把write的異步過程改爲同步過程,就是在open文件的時候帶上O_SYNC標記。

數據到了page cache後,內核有pdflush線程在不停的檢測髒頁,判斷是否要寫回到磁盤中。把須要寫回的頁提交到IO隊列——即IO調度隊列。又IO調度隊列調度策略調度什麼時候寫回。

提到IO調度隊列,不得不提一下磁盤結構。這裏要講一下,磁頭和電梯同樣,儘可能走到頭再回來,避免來回搶佔是跑,磁盤也是單向旋轉,不會反覆逆時針順時針轉的。從網上copy一個圖下來,具體這裏就不介紹。

clip_image003

IO隊列有2個主要任務。一是合併相鄰扇區的,而是排序。合併相信很容易理解,排序就是儘可能按照磁盤選擇方向和磁頭前進方向排序。由於磁頭尋道時間是和昂貴的。

這裏IO隊列和咱們經常使用的分析工具IOStat關係密切。IOStat中rrqm/s wrqm/s表示讀寫合併個數。avgqu-sz表示平均隊列長度。

內核中有多種IO調度算法。當硬盤是SSD時候,沒有什麼磁道磁頭,人家是隨機讀寫的,加上這些調度算法反而多此一舉。OK,恰好有個調度算法叫noop調度算法,就是什麼都不錯(合併是作了)。恰好能夠用來配置SSD硬盤的系統。

從IO隊列出來後,就到了驅動層(固然內核中有更多的細分層,這裏忽略掉),驅動層經過DMA,將數據寫入磁盤cache。

至於磁盤cache時候寫入磁盤介質,那是磁盤控制器本身的事情。若是想要睡個安慰覺,確認要寫到磁盤介質上。就調用fsync函數吧。能夠肯定寫到磁盤上了。

3.       一致性和安全性

談完調用細節,再將一下一致性問題和安全問題。既然數據沒有到到磁盤介質前,可能處在不一樣的物理內存cache中,那麼若是出現進程死機,內核死,掉電這樣事件發生。數據會丟失嗎。

當進程死機後:只有數據還處在application cache或CLib cache時候,數據會丟失。數據到了page cache。進程core掉,即便數據尚未到硬盤。數據也不會丟失。

當內核core掉後,只要數據沒有到達disk cache,數據都會丟失。

掉電狀況呢,哈哈,這時候神也救不了你,哭吧。

那麼一致性呢,若是兩個進程或線程同時寫,會寫亂嗎?或A進程寫,B進程讀,會寫髒嗎?

文章寫到這裏,寫得太長了,就舉出各類各樣的例子。講一下大概判斷原則吧。fwrite操做的buffer是在進程私有空間,兩個線程讀寫,確定須要鎖保護的。若是進程,各有各的地址空間。是否要加鎖,看應用場景。

write操做若是寫大小小於PIPE_BUF(通常是4096),是原子操做,能保證兩個進程「AAA」,「BBB」寫操做,不會出現「ABAABB」這樣的數據交錯。O_APPEND標誌能保證每次從新計算pos,寫到文件尾的原子性。

數據到了內核層後,內核會加鎖,會保證一致性的。

4.       性能問題

性能從系統層面和設備層面去分析;磁盤的物理特性從根本上決定了性能。IO的調度策略,系統調用也是致命殺手。

磁盤的尋道時間是至關的慢,平均尋道時間大概是在10ms,也就是是每秒只能100-200次尋道。

磁盤轉速也是影響性能的關鍵,目前最快15000rpm,大概就每秒500轉,滿打滿算,就讓磁頭不尋道,設想全部的數據連續存放在一個柱面上。你們能夠算一下每秒最多能夠讀多少數據。固然這個是理論值。通常狀況下,盤片轉太快,磁頭感應跟不上,因此須要轉幾圈才能徹底讀出磁道內容。

另外設備接口總線傳輸率是實際速率的上限。

另外有些等密度磁盤,磁盤外圍磁道扇區多,線速度快,若是頻繁操做的數據放在外圍扇區,也能提升性能。

利用多磁盤併發操做,也不失爲提升性能的手段。

這裏給個業界經驗值:機械硬盤順序寫~30MB,順序讀取速率通常~50MB好的能夠達到100多M, SSD讀達到~400MB,SSD寫性能和機械硬盤差很少。

Ps:

O_DIRECT 和 RAW設備最根本的區別是O_DIRECT是基於文件系統的,也就是在應用層來看,其操做對象是文件句柄,內核和文件層來看,其操做是基於inode和數據塊,這些概念都是和ext2/3的文件系統相關,寫到磁盤上最終是ext3文件。而RAW設備寫是沒有文件系統概念,操做的是扇區號,操做對象是扇區,寫出來的東西不必定是ext3文件(若是按照ext3規則寫就是ext3文件)。通常基於O_DIRECT來設計優化本身的文件模塊,是不滿系統的cache和調度策略,本身在應用層實現這些,來制定本身特有的業務特點文件讀寫。可是寫出來的東西是ext3文件,該磁盤卸下來,mount到其餘任何linux系統上,均可以查看。而基於RAW設備的設計系統,通常是不滿現有ext3的諸多缺陷,設計本身的文件系統。本身設計文件佈局和索引方式。舉個極端例子:把整個磁盤作一個文件來寫,不要索引。這樣沒有inode限制,沒有文件大小限制,磁盤有多大,文件就能多大。這樣的磁盤卸下來,mount到其餘linux系統上,是沒法識別其數據的。二者都要經過驅動層讀寫;在系統引導啓動,還處於實模式的時候,能夠經過bios接口讀寫raw設備。

相關文章
相關標籤/搜索