Linux-內核緩存區和write行為


《Unix環境高級編程》

應用緩沖技術能很明顯的提高系統效率。內核與外圍設備的數據交換,內核與用戶空間的數據交換都是比較費時的,使用緩沖區就是為了優化這些費時的操作。其實核心到用戶空間的操作本身是不buffer的,是由I/O庫用buffer來優化了這個操作。比如read本來從內核讀取數據時是比較費時的,所以一次取出一塊,以避免多次陷入內核。
      內核緩沖區的 主要思想就是一次讀入大量的數據放在緩沖區,需要的時候從緩沖區取得數據。
      管理員模式和用戶模式之間的切換需要消耗時間,但相比之下,磁盤的I/O操作消耗的時間更多,為了提高效率,內核也使用緩沖區技術來提高對磁盤的訪問速度磁 盤是數據塊的集合,內核會對磁盤上的數據塊做緩沖。內核將磁盤上的數據塊復制到內核緩沖區中,當一個用戶空間中的進程要從磁盤上讀數據時,內核一般不直接 讀磁盤,而是將內核緩沖區中的數據復制到進程的緩沖區中。當進程所要求的數據塊不在內核緩沖區時,內核會把相應的數據塊加入到請求隊列,然后把該進程掛 起,接着為其他進程服務。一段時間之后(其實很短的時間),內核把相應的數據塊從磁盤讀到內核緩沖區,然后再把數據復制到進程的緩沖區中,最后喚醒被掛起的進程。
      注:理解內核緩沖區技術的原理有助於更好的掌握系統調用read&write,read把數據從內核緩沖區復制到進程緩沖區,write把數據從進程緩沖區復制到內核緩沖區,它們不等價於數據在內核緩沖區和磁盤之間的交換
      從理論上講,內核可以在任何時候寫磁盤,但並不是所有的write操作都會導致內核的寫動作。內核會把要寫的數據暫時存在緩沖區中,積累到一定數量后再一 次寫入。有時會導致意外情況,比如斷電,內核還來不及把內核緩沖區中的數據寫道磁盤上,這些更新的數據就會丟失。
      應用內核緩沖技術導致的結果是:提高了磁盤的I/O效率;優化了磁盤的寫操作;需要及時的將緩沖數據寫到磁盤

Write行為

從write()調用返回時,內核已經將緩沖區所提供的數據到內核的緩沖區,但是無法保證數據已經寫出到其預定的目的地。的確,寫入調用返回的速度實在太快了,可能沒有時間完成該項目的工作。處理器和硬盤之間的性能差異使得此類令人頭痛的行為顯而易見。

 

事實上,如果用戶空間應用程序發出write()系統調用,Linux內核會先進行若干檢查,接着將數據復制進緩沖區。稍后,內核會在后台收集所有 “臟”(有數據寫入)緩沖區(內容跟相應磁盤塊不同的所有緩沖區),將它們安排成最佳順序,接着寫進磁盤。這讓寫入調用的執行快如閃電,幾乎立即返回,這 也讓內核可以將寫入操作延后到較空閑的時段再進行,並且是多筆寫入操作會整批一起進行。

 

延后進行的寫入操作並不會改變POSIX的語義。舉例來說,數據剛寫入緩沖區而尚未寫回磁盤,此時如果發出讀取請求,此請求可從緩沖區得到滿足,而 且不會因此而讀取到地盤上的舊數據。此行為會實際提高性能,因為讀取請求可從內存中的緩沖區得到滿足,而不必從磁盤。當讀取和寫入請求如預期般交替出現 時,結果也和預期一樣,也就是說,數據被寫回磁盤之前系統不會崩潰!即使應用程序相信寫入請求已經成功完成了,但事實上數據尚未寫回磁盤。

 

延后寫入的另一個問題是無法安排寫入順序,盡管應用程序可能會安排寫入請求的順序,好讓他們能夠按照特定的順序寫回磁盤,內核會以它認為合適的方式 重新安排寫入請求的順序,主要是基於新能的考慮。除非系統崩潰,否則這通常不是一個問題,因為所有緩沖區最后都會寫回磁盤,所以一切都很好。即使如此,絕 大多數的應用程序實際上並不關心寫入請求的順序。

 

延遲寫入必須探討的最后一個問題是匯報I/O錯誤。寫回磁盤期間可能會發生任何無法向發出寫入請求的進程匯報的I/O錯誤,例如磁盤驅動器故障。的 確,緩沖區與這些進程毫無關系。假如有多個進程“弄臟”(將數據寫入)單一緩沖區,而這些進程可能在數據寫入緩沖區之后並且在數據寫回磁盤之前先借宿了。

 

內核會試圖盡量降低延后寫入的風險,為了確保數據可以被及時寫出,內核未緩沖區設立了一個時間上限,而且會在時間超過上限之前寫出所有“臟”緩沖 區。用戶可通過/proc/sys/vm/dirty_expire_centiseconds來設定此值,此值以厘秒(百分之一秒)為單位。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM