1. 程式人生 > 其它 >Linux 檔案讀寫機制

Linux 檔案讀寫機制

技術標籤:Linux

01. 基本概念

快取

快取是用來減少高速裝置訪問低速裝置所需平均時間的元件,檔案讀寫涉及到計算機記憶體和磁碟,記憶體操作速度遠遠大於磁碟,如果每次呼叫read、write都去直接操作磁碟,一方面速度會被限制,一方面也會降低磁碟使用壽命,因此不管是對磁碟的讀操作還是寫操作,作業系統都會將資料先快取起來。

Page Cache

頁快取(Page Cache)是位於記憶體與檔案之間的緩衝區,它實際上也是一塊記憶體區域,所有的檔案IO(包括網路檔案)都是直接和頁快取互動,作業系統通過一系列的資料結構,比如inode, address_space, struct page,實現將一個檔案對映到頁的級別。很大一部分程度上,檔案讀寫的優化就是對頁快取使用的優化。

Dirty Page

頁快取對應檔案中的一塊區域,如果頁快取和對應的檔案區域內容不一致,則該頁快取叫做髒頁(Dirty Page)。對頁快取進行修改或者新建頁快取,只要沒有刷磁碟,都會產生髒頁。

在這裡插入圖片描述

[[email protected] ~]# cat /proc/meminfo | grep -E '^Cached|^Dirty'

在這裡插入圖片描述

一些可以改變作業系統對髒頁的回寫行為的引數

[[email protected] ~]# sysctl -a 2>/dev/null | grep dirty
vm.dirty_background_ratio = 5
vm.dirty_background_bytes = 0
vm.
dirty_ratio = 10 vm.dirty_bytes = 0 vm.dirty_writeback_centisecs = 500 vm.dirty_expire_centisecs = 3000
  • vm.dirty_background_ratio是記憶體可以填充髒頁的百分比,當髒頁總大小達到這個比例後,系統後臺程序就會開始將髒頁刷磁碟(vm.dirty_background_bytes類似,只不過是通過位元組數來設定)

  • vm.dirty_ratio是絕對的髒資料限制,記憶體裡的髒資料百分比不能超過這個值。如果髒資料超過這個數量,新的IO請求將會被阻擋,直到髒資料被寫進磁碟

  • vm.dirty_writeback_centisecs

    指定多長時間做一次髒資料寫回操作,單位為百分之一秒

  • vm.dirty_expire_centisecs指定髒資料能存活的時間,單位為百分之一秒,比如這裡設定為30秒,在作業系統進行寫回操作時,如果髒資料在記憶體中超過30秒時,就會被寫回磁碟

  • 這些引數可以通過 sudo sysctl -w vm.dirty_background_ratio=5 這樣的命令來修改,需要root許可權,也可以在root使用者下執行 echo 5 > /proc/sys/vm/dirty_background_ratio 來修改

02. 檔案讀寫流程

在有了頁快取和髒頁的概念後,我們再來看檔案的讀寫流程

讀檔案

  • 使用者發起read操作
  • 作業系統查詢頁快取
  • 若未命中,則產生缺頁異常,然後建立頁快取,並從磁碟讀取相應頁填充頁快取
  • 若命中,則直接從頁快取返回要讀取的內容
  • 使用者read呼叫完成

寫檔案

  • 使用者發起write操作
  • 作業系統查詢頁快取
  • 若未命中,則產生缺頁異常,然後建立頁快取,將使用者傳入的內容寫入頁快取
  • 若命中,則直接將使用者傳入的內容寫入頁快取
  • 使用者write呼叫完成
  • 頁被修改後成為髒頁,作業系統有兩種機制將髒頁寫回磁碟
  • 使用者手動呼叫fsync()
  • 由pdflush程序定時將髒頁寫回磁碟

頁快取和磁碟檔案是有對應關係的,這種關係由作業系統維護,對頁快取的讀寫操作是在核心態完成,對使用者來說是透明的

03. 檔案讀寫的優化思路

不同的優化方案適應於不同的使用場景,比如檔案大小,讀寫頻次等,這裡我們不考慮修改系統引數的方案,修改系統引數總是有得有失,需要選擇一個平衡點,這和業務相關度太高,比如是否要求資料的強一致性,是否容忍資料丟失等等。優化的思路有以下兩個考慮點。

  • 最大化利用頁快取

  • 減少系統api呼叫次數

第一點很容易理解,儘量讓每次IO操作都命中頁快取,這比操作磁碟會快很多,第二點提到的系統api主要是read和write,由於系統呼叫會從使用者態進入核心態,並且有些還伴隨著記憶體資料的拷貝,因此在有些場景下減少系統呼叫也會提高效能。