第三章 數據緩衝區高速緩衝

對文件系統的一切存取操作,內核都能通過每次直接從磁盤上讀或寫入磁盤實現,但這樣的方式受到磁盤傳輸速率的限制,比如讀寫速度較慢的磁盤會使系統的響應時間加長、吞吐率降低。爲了解決多次讀寫磁盤所花費的大量時間開銷,內核通過保持一個稱謂數據緩衝區高速緩衝(buffer cache)的內部數據緩衝區來減小對磁盤的讀寫頻率。


緩衝頭部

內核體系結構中高速緩衝模塊的位置是在文件子系統與設備驅動程序之間。緩衝區是磁盤塊在內存中的拷貝,在同一時刻絕對不允許將一個磁盤塊映射到多個緩衝區中,換言之,一個磁盤塊只能映射到一個緩衝區中。一個緩衝區由兩部分組成:

  1. 磁盤數據存儲器數組

  2. 標識該緩衝區的緩衝頭部

    緩衝區頭部
    (1)設備號:邏輯文件系統號
    (2)塊號:磁盤邏輯塊號
    (3)狀態字節:概括緩衝區當前狀態
    (4)指針

緩衝池的結構

內核按最近最少使用算法(NRU)把數據存放於緩衝池中。
緩衝池包含兩個重要的數據結構:
空閒表:標識空閒的緩衝區,以雙向循環鏈表鏈接。
散列隊列:每個緩衝區總是存在於一個散列隊列中。
再次強調,沒有多個緩衝區同時包含一個磁盤塊數據的情況。
總結:緩衝池的磁盤塊,存在且僅存在於一個散列隊列中,並且僅在那個散列隊列中駐留一段時間。若緩衝區爲空閒狀態,便可以存在於空閒表中。

緩衝區的檢索

當存取一個磁盤塊時,內核使用適當的設備號和塊號的組合去找相應的緩衝區,而不是搜索整個緩衝區池。它把緩衝區組織成一個個隊列,成爲散列隊列,散列函數的參數爲設備號和塊號。

設備號決定從哪個文件系統上讀取磁盤塊; 塊號決定從該文件系統上的哪個磁盤塊讀取數據。

如果一個進程要從一個文件中讀數據,則內核需判定哪一個文件系統包含該文件,以及該文件系統中的哪一塊包含該數據。現在確定了文件系統後,內核需要選擇從哪一個特定的磁盤塊上讀取數據。此時,內核首先檢查該塊是否在緩衝區池中,若不在,則分配給該磁盤塊一個空閒的緩衝區;進程向磁盤塊寫入數據時,操作類似:若該磁盤塊不在緩衝區池中,則爲該磁盤塊分配一個空閒緩衝區。讀寫磁盤塊時使用算法getblk來對池中緩衝區進行分配。

緩衝區的讀寫

爲了讀一個磁盤塊,進程使用算法getblk在高速緩衝中搜索這個磁盤塊。如果它在高速緩衝中,則內核可不必從磁盤上讀取該塊,通過算法bread讀取含有數據的緩衝區中的內容;如果它不在高速緩衝中,則內核調用磁盤驅動程序,用以安排一個讀請求,然後進入睡眠,等待I/O事件的完成。


內核只在邏輯上涉及文件系統,不實現邏輯設備與物理設備的映射,而磁盤驅動程序實現邏輯設備和物理設備之間的地址轉換。


讀磁盤塊:在一個進程順序地讀一個文件的時候,較高層次的內核模塊(比如文件子系統)可能會預期到對另一個磁盤塊的需要,因而該模塊異步地請求第二個I/O。爲了做到這點內核執行提前讀磁盤塊算法breada。個人理解:進程在等待第一個讀請求的事件的睡眠中,內核預期到對下一個讀操作,因而喚醒進程進行下一次的讀操作。異步讀的時候,內核並不等待第一個讀操作完成而提前執行下一次的讀操作。(不知正確與否)
寫磁盤塊:內核首先告知磁盤驅動程序說自己有一個緩衝區的內容應該被輸出。磁盤驅動程序調度到該塊上一遍進行I/O操作。如果寫操作是同步的,則調用寫操作的進程進入睡眠直至I/O完成才能被喚醒;如果寫操作是異步的,則內核開始寫入磁盤,但是進程的喚醒不一定等待I/O完成。當I/O完成時,內核通過算法brelse釋放該緩衝區。
注:延遲寫和異步寫的區別。

  • 異步寫時內核立即開始這一寫操作,但並不等待這一寫操作的完成。寫操作完成後,內核將釋放該緩衝區。

  • 延遲寫時內核則儘可能長時間地推遲寫磁盤的操作。

高速緩衝的優點和缺點

  • 緩衝區提供了同一的磁盤存取方法,內核不需要知道I/O的原因。即是說,不論是文件中的數據、索引節點中數據、超級塊中數據,內核都是利用緩衝區來進行讀寫(如果數據不在緩衝區中,則爲該磁盤塊分配一個緩衝區)。
  • 高速緩衝的使用可以減少磁盤的訪問次數,從而提高整個系統的吞吐量,減少響應時間。
  • 緩衝區算法有助於確保文件系統的完整性。
  • 由於延遲寫使得內核沒有立即把數據寫到磁盤上,因此當系統崩潰時可能造成數據丟失。
  • 高速緩衝的使用使得進程讀寫數據時增加了一次將磁盤數據拷貝到緩衝區或將緩衝區拷貝到磁盤的過程。在I/O量較大的系統中,這樣的過程所耗費的時間是遠小於進程每次從磁盤塊上讀取數據所耗費的時間的。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章