Linux下的磁碟快取

2022-08-02 09:48:21 字數 3000 閱讀 9369

**:

前段時間在開發乙個使用ssd做快取的系統,在高速寫入資料時會出現大量的磁碟快取。太多的磁碟快取如果沒有及時的寫入磁碟中,在機器出現問題時是非常危險的,這樣會導致很多的資料丟失,但是如果實時的將資料刷入磁碟中,這樣寫入效率有太低了。為了弄明白linux系統的這種磁碟寫入特性,最近深入的學習了一下。

vfs(virtual file system)的存在使得linux可以相容不同的檔案系統,例如ext3、ext4、xfs、ntfs等等,其不僅具有為所有的檔案系統實現乙個通用的外界面的作用,還具有另乙個與系統效能相關的重要作用——快取。vfs中引入了高速磁碟快取的機制,這屬於一種軟體機制,允許核心將原本存在磁碟上的某些資訊儲存在ram中,以便對這些資料的進一步訪問能快速進行,而不必慢速訪問磁碟本身。高速磁碟快取可大致分為以下三種:

正是由於快取的引入,所以vfs檔案系統採用了檔案資料延遲寫的技術,因此,如果在呼叫系統介面寫入資料時沒有使用同步寫模式,那麼大多數據將會先儲存在快取中,待等到滿足某些條件時才將資料刷入磁碟裡。

核心是如何將資料刷入磁碟的呢?在看完以下兩點後就能得到答案。

1. 把髒頁寫入磁碟

正如我們所了解的,核心不斷用包含塊裝置資料的頁填充頁快取記憶體。只要程序修改了資料,相應的頁就被標記為臟頁,即把它的pg_dirty標誌位置。

unix系統允許把髒緩衝區寫入塊裝置的操作延遲執行,因為這種策略可以顯著地提高系統的效能。對快取記憶體中的頁的幾次寫操作可能只需對相應的磁碟塊進行一次緩慢的物理更新就可以滿足。此外,寫操作沒有讀操作那麼緊迫,因為程序通常是不會因為延遲寫而掛起,而大部分情況都因為延遲讀而掛起。正是由於延遲寫,使得任一物理塊裝置平均為讀請求提供服務將多於寫請求。

乙個髒頁可能直到最後一刻(即直到系統關閉時)都一直逗留在主存中。然而,從延遲寫策略的侷限性來看,它有兩個主要的缺點:

一、如果發生了硬體錯誤或者電源掉電的情況,那麼就無法再獲得ram的內容,因此,從系統啟動以來對檔案進行的很多修改就丟失了。

二、頁快取記憶體的大小(由此存放它所需的ram的大小)就可要很大——至少要與所訪問塊裝置的大小不同。

因此,在下列條件下把髒頁重新整理(寫入)到磁碟:

緩衝區頁的引入是問題更加複雜。與每個緩衝區頁相關的緩衝區首部使核心能夠了解每個獨立塊緩衝區的狀態。如果至少有乙個緩衝區首部的pg_dirty標誌被置位,就應該設定相應緩衝區頁的pg_dirty標誌。當核心選擇要重新整理的緩衝區時,它掃瞄相應的緩衝區首部,並只把髒塊的內容有效的寫到磁碟。一旦核心把緩衝區的所有髒頁重新整理到磁碟,就把頁的pg_dirty標誌清0。

2. pdflush核心執行緒

早期版本的linux使用bdfllush核心執行緒系統地掃瞄頁快取記憶體以搜尋要重新整理的髒頁,並且使用另乙個核心執行緒kupdate來保證所有的頁不會「髒」太長時間。linux 2.6用一組通用核心執行緒pdflush替代上述兩個執行緒。

這些核心執行緒結構靈活,它們作用於兩個引數:乙個指向執行緒要執行的函式的指標和乙個函式要用的引數。系統中pdflush核心執行緒的數量是要動態調整的:pdflush執行緒太少時就建立,太多時就殺死。因為這些核心執行緒所執行的函式可以阻塞,所以建立多個而不是乙個pdflush核心執行緒可以改善系統效能。

根據下面的原則控制pdflush執行緒的產生和消亡:

所有的pdflush核心執行緒都有pdflush_work描述符,其資料結構如下:

型別字段

說明struct task_struct

who指向核心執行緒描述符的指標

void (*) (unsigned long)

fn核心執行緒所執行的**函式

unsigned long

arg0

給**函式的引數

struct list head

list

pdflush_list鍊錶的鏈結

unsigned long

when_i_went_to_sleep

當核心執行緒可用時的時間(以jiffies表示)

當系統沒有要重新整理的髒頁時,pdflush執行緒會自動處於睡眠狀態,最後由pdflush_operation()函式來喚醒。那麼在這個過程中pdflush核心執行緒主要完成了哪些工作呢?其中一些工作與髒資料的重新整理有關。尤其是pdflush通常執行下面的**函式之一:

1. background_writeout(): 系統地掃瞄頁快取記憶體以搜尋要重新整理的髒頁。

為了得到需要重新整理的髒頁,就要徹底的搜尋與在磁碟上有映像的索引節點相應的所有address_space物件(是一棵搜尋樹)。由於頁快取記憶體可能有大量的頁,如果用乙個單獨的執行流來掃瞄整個快取記憶體,會令cpu和磁碟長時間繁忙,因此,linux使用一種複雜的機制把對頁快取記憶體的掃瞄劃分為幾個執行流。當記憶體不足或者使用者顯式的(使用者態程序發出sync()系統呼叫等)呼叫請求重新整理操作時會執行wakeup_bdflush()函式。wakeup_bdflush()函式會呼叫pdflush_operation()喚醒pdflush核心執行緒,並委託它執行**函式background_writeout()。background_writeout()函式有效的從頁快取記憶體中獲得指定數量的髒頁,並把它寫回磁碟。此外,執行background_writeout()函式的pdflush核心執行緒只有在滿足以下兩個條件下才能被喚醒:一是對頁快取記憶體中的頁內容進行了修改,二是引起髒頁部分增加到超過某個髒背景閾值。背景閾值通常設定為系統中所有頁的10%,不過可以通過修改檔案/proc/sys/vm/dirty_background_ratio來調整該值。

2. wb_kupdate():檢查頁快取記憶體中是否有「髒」了很久時間的頁,避免當一些頁很久沒有被重新整理時發生飢餓危險。

核心在初始化期間會建立wb_timer動態定時器,其的定時間距為dirty_writeback_centisecs檔案中所規定的幾百分之一秒(通常是500分之一秒,不過可以通過修改/proc/sys/vm/dirty_writeback_centisecs檔案調整該值)。定時器函式會呼叫pdflush_operation()函式,然後將wb_kupdate()函式的位址傳入。wb_kupdate()函式遍歷頁快取記憶體搜尋陳舊的髒索引節點,把已保持髒狀態時間超過30秒的頁都寫到磁碟,之後重置定時器。

linux下的磁碟掛載

將新的磁碟安裝在伺服器上後,怎麼掛載到現在的伺服器上呢?1.查詢是否已經分配磁碟 fdisk l這裡因為測試,只是掛載了10g的硬碟 2.發現有磁碟 dev sdb。然後使用fdisk命令建立分割槽 3.輸入m查詢幫助 主要資訊 n 新建分割槽 w 確定分割槽 q 退出分割槽 4.查詢是否已經分配磁...

Linux下的磁碟管理和磁碟配額

磁碟基礎 檢測並確認新硬碟 規劃硬碟中的分割槽 建立檔案系統 格式化 掛載 解除安裝檔案系統 硬碟的物理結構 1.碟片 硬碟有多個碟片,每碟片2面 2.磁頭 每面乙個磁頭 硬碟的資料結構 1.扇區 碟片被分為多個扇形區域,每個扇區存放512位元組的資料 2.磁軌 同一碟片不同半徑的同心圓 3.柱面 ...

Linux系統下的磁碟管理

我們都知道windows系統下有磁碟管理功能,相對應的,linux系統下也會有磁碟管理功能。該部分內容需要準備乙個空的u盤,因為之後我們需要格式化該u盤,並且要保證u盤格式為fat格式,最好為fat32 注意 當u盤插入電腦時,我們需要選擇將u盤接入到linux系統下,而不是windows系統下。d...