以下由linux系統教學欄位介紹給大家總結關於Linux磁碟快取的相關知識,希望對需要的朋友有幫助!
前言
最近遇到了一起跟磁碟相關的線上故障,藉此總結一下之前不太了解的Linux磁碟快取相關的知識。
總的來說磁碟快取出現的原因大概有兩個:第一是存取磁碟的速度遠慢於存取記憶體的速度,透過在記憶體中快取磁碟內容可以提高存取速度;第二是根據程式的局部性原理,資料一旦被訪問過,就很有可能在短時間內再次被訪問,所以在記憶體中快取磁碟內容可以提高程式運行速度。
局部性原理
程式局部性原理:程式在執行時呈現出局部性規律,即在一段時間內,整個程式的執行僅限於程式中的某一部分。相應地,執行所存取的儲存空間也局限於某個記憶體區域,具體來說,局部性通常有兩種形式:時間局部性和空間局部性。
時間局部性:被引用過一次的記憶體位置在未來會被多次引用。
空間局部性:如果一個記憶體的位置被引用,那麼將來他附近的位置也會被引用。
頁快取
Linux系統中為了減少對磁碟的IO操作,會將開啟的磁碟內容進行緩存,而快取的地方則是物理內存,進而將對磁碟的存取轉換成對記憶體的訪問,有效提高程式的速度。 Linux的快取方式是利用實體記憶體快取磁碟上的內容,稱為頁面快取(page cache)。
頁快取是由記憶體中的實體頁面組成的,其內容對應磁碟上的實體區塊。頁面快取的大小會根據系統的記憶體空閒大小進行動態調整,它可以透過佔用記憶體以擴張大小,也可以自我收縮以緩解記憶體使用壓力。
在虛擬記憶體機制出現以前,作業系統使用區塊快取系列,但是在虛擬記憶體出現以後,作業系統管理IO的粒度更大,因此採用了頁快取機制,頁快取是基於頁的、面向檔案的快取機制。
頁快取的讀取
Linux系統在讀取檔案時,會優先從頁快取讀取檔案內容,如果頁快取不存在,系統會先從磁碟讀取檔案內容更新到頁快取中,然後再從頁面快取讀取檔案內容並返回。
大致過程如下:
進程呼叫函式庫函數read發起讀取檔請求
核心檢查已開啟的文件列表,呼叫檔案系統提供的read介面
找到檔案對應的inode,然後計算要讀取的具體的頁
頁快取的寫入
因為頁快取的存在,當一個行程呼叫write時,檔案的更新只是被寫到了檔案的頁快取中,讓後將對應的頁標記為dirty,整個過程就結束了。 Linux核心會在週期性地將髒頁寫回磁碟,然後清理掉dirty標識。 由於寫入作業只會將變更寫入頁緩存,因此進程並不會因此為阻塞直到磁碟IO發生,如果此時電腦崩潰,寫入作業的變更可能並沒有發生在磁碟上。所以對於一些要求比較嚴格的寫入操作,例如資料系統,就需要主動呼叫fsync等操作及時將變更同步到磁碟上。讀取操作則不同,read通常會阻塞直到進程讀取到數據,而為了減少讀取操作的這種延遲,Linux系統還是用了「預讀」的技術,也就是從磁碟讀取資料時,核心將會多讀取一些頁到頁快取中。回寫線程
頁快取的回寫是由核心中的單獨的執行緒來完成的,回寫執行緒會在以下3種情況下進行回寫:名稱 | 版本 | 說明 |
---|---|---|
bdflush | 2.6版本以前 | bdflush 核心線程在後台運行,系統中只有一個bdflush 線程,當記憶體消耗到特定閥值以下時,bdflush 線程被喚醒。 kupdated 週期性的運行,寫回髒頁。但是整個系統僅僅只有一個 bdflush 線程,當系統回寫任務較重時,bdflush 線程可能會阻塞在某個磁碟的I/O上,導致其他磁碟的I/O回寫操作不能及時執行。 |
pdflush | 2.6版本引入 | pdflush 執行緒數目是動態的,取決於系統的I/O負載。它是面向系統中所有磁碟的全域任務的。但由於 pdflush 是面向所有磁碟的,所以有可能出現多個 pdflush 執行緒全部阻塞在某個擁塞的磁碟上,同樣導致其他磁碟的I/O回寫不能及時執行。 |
flusher執行緒 | 2.6.32版本以後引入 | flusher 執行緒的數目不是唯一的,同時flusher執行緒不是針對所有磁碟的,而是每個flusher執行緒對應一個磁碟 |
頁快取的回收
Linux中頁快取的替換邏輯是一個修改過的LRU實現,也稱為雙股策略。和以前不同,Linux維護的不再是一個LRU鍊錶,而是維護兩個鍊錶:活躍鍊錶和非活躍鍊錶。處於活躍鍊錶上的頁面被認為是「熱」的且不會被換出,而在非活躍鍊錶上的頁面則是可以被換出的。在活躍鍊錶中的頁面必須在其被存取時就處於非活躍鍊錶中。兩個鍊錶都被偽LRU規則維護:頁面從尾部加入,從頭部移除,如同隊列。兩個鍊錶需要維持平衡–如果活躍鍊錶變得過多而超過了非活躍鍊錶,那麼活躍鍊錶的頭頁將被重新移回到非活躍鍊錶中,一遍能再被回收。雙鍊錶策略解決了傳統LRU演算法中對僅一次訪問的窘境。而且也更加簡單的實作了偽LRU語意。這種雙鍊錶方式也稱為LRU/2。更普遍的是n個鍊錶,故稱LRU/n。
【推薦學習:《linux影片教學》】
#總結
在這次遇到的線上故障中,根本原因在於在業務邏輯中使用了臨時文件做緩存,一個臨時文件創建後如果在短時間內刪除,這時候對這個文件的操作都是在頁緩存內進行,不會實際回寫到磁碟。當程式出現問題回應變慢時,臨時檔案存活時間變長,就可能會使其被回寫到磁碟上,導致磁碟壓力過大,進而影響整個系統。
以上是總結Linux磁碟快取相關知識的詳細內容。更多資訊請關注PHP中文網其他相關文章!