操作系統-番外-日誌結構文件系統LFS

引言

過去幾十年CPU速度的增長是巨大的,但是磁盤的訪問速度卻增長較慢。內存近些年發展也很快,可以提供較大的空間存儲程序的工作集,因此磁盤傳輸主要是被寫操作支配。因此如何提升寫效率是有效利用磁盤的關鍵。

日誌結構文件系統是用順序寫,因爲省去了絕大部分seek操作,因此大大提升了寫的性能。還有一個好處就是系統崩潰恢復,日誌結構文件系統只需要檢查最近的部分日誌

日誌結構文件系統實現

基本假設
  • 大部分的讀請求都從緩存中讀取
  • 大部分磁盤訪問都是寫請求
段概念
  • 段定義:雖然磁盤順序寫效率高,考慮一下,如果有一個文件執行寫操作就寫,但是如果中間間隔一會兒寫另一個文件,那麼中間磁盤已經旋轉。要想獲得高效率,必須連續順序寫,因此需要在內存中緩存修改的塊,直到達到一定數量的時候執行一次寫操作,這個大塊叫做

  • 段佈局:段中不僅包含了數據塊,也包括i-node塊,段的開頭還包括一個段summary塊,包含了垃圾回收需要的關鍵信息,後邊詳細解釋
    在這裏插入圖片描述

  • 緩存大小:TpositionT_{position}代表寫操作前旋轉和尋道開銷時間,磁盤傳輸速率RpeakR_{peak}MB/s,因此傳輸DDMB需要的時間TwriteT_{write}

    Twrite=Tposition+DRpeakT_{write} = T_{position} + \frac{D}{R_{peak}}

    寫效率

    Reffective=DTwrite=DTposition+DRpeakR_{effective} = \frac{D}{T_{write}} = \frac{D}{T_{position} + \frac{D}{R_{peak}}}

    寫效率是以傳輸速率爲基準,用F(0<F<1)表示

    Reffective=DTposition+DRpeak=F×RpeakR_{effective} = \frac{D}{T_{position} + \frac{D}{R_{peak}}} = F \times R_{peak}

    D=F×Rpeak×(Tposition+DRpeak)D = F \times R_{peak} \times (T_{position} + \frac{D}{R_{peak}})

    變換得到

    D=F1F×Rpeak×TpositionD = \frac{F}{1-F} \times R_{peak} \times T_{position}

    假設要得到90%的效率,假設TpositionT_{position}爲0.01秒,磁盤傳輸速率爲100MB/s,因此計算D爲9MB,因此緩存大小爲9MB

I-node查找
  • i-node查找問題:因爲i-node信息現在存放在各個段中,這就引入了一個新文件,如何查找i-node,如果遍歷查找肯定不行效率太低。引入了一個新的結構imap,imap是一個簡單的數組結構index爲k的元素存放着第k個i-node在磁盤的地址,imap信息常駐在內存中,因此查詢i-node的位置是很快的

  • imap存儲問題:imap也是需要存儲的,這裏假設在磁盤固定位置存儲imap,因爲imap頻繁的被修改,因此會導致頻繁的寫回磁盤,每當文件修改時,imap也需要隨後更新,這會導致額外的seek開銷。所以LFS將imap信息和i-node一樣存在段中,存在i-node右邊,如下圖
    在這裏插入圖片描述

  • imap查找問題:imap存儲在段中,也出現了i-node查找一樣的問題,爲了解決這個問題,LFS用一個固定的空間來存放指向imap地址的區域叫作checkpoint region (CR),CR存放了指向最新的imap地址的指針,在查找imap之前會首先加載CR,CR通常是週期性的更新,並不會某一個imap更新就立馬寫回磁盤
    在這裏插入圖片描述

  • read操作流程,假設此時內存還是空的
    在這裏插入圖片描述

目錄實現
  • 目錄結構:一個目錄名映射i-node編號

  • 目錄存儲問題:和i-node一樣存在段中,其索引存在段中imap結構中並且緩存在內存中,其結構例子如下,文件foo在目錄dir中,通過dir在imap找到存儲dir目錄的i-node例子中A3,然後在i-nodeA3中找到目錄數據在塊A2,在A2中查找到foo文件對應k號i-node,然後在imap中查找到k號i-node在A1,最終找到文件foo的數據在塊A0中
    在這裏插入圖片描述

垃圾回收
  • 垃圾產生的原因

    1. 文件更新導致的老的數據塊和i-node塊無效,如下圖
      在這裏插入圖片描述

    2. 文件增加導致的老的i-node塊無效,如下圖
      在這裏插入圖片描述

  • 垃圾回收流程

    讀出舊的段,將段中有效的塊複製到內存緩存中,當量達到一個段大小時,像普通修改文件那樣以日誌方式寫入磁盤,舊的段便釋放了,下圖大概描述了垃圾回收的流程,假設讀入segment 1和segment 2然後整理出有效的塊並剛好組成一個段,寫入磁盤,因此清理點就後移2個段,而寫入點後移一個,當寫入點達到磁盤最大值時,指針又移到磁盤開始位置,因此在LFS文件系統中,磁盤被抽象成一個大環形數組結構
    在這裏插入圖片描述

  • 如何分辨垃圾

    前邊我們提到過段summary塊,這個塊主要記錄了段內塊的摘要信息,每個塊所屬的i-node和offset。如何確定哪些塊是垃圾呢?我們加載段到內存,然後根據段summary信息,查看一個塊所屬的i-node號,然後從imap中查詢最新的i-node存放地址,加載到內存中然後找到offset對應的地址是否爲段中塊的地址,如果是,那麼這個塊是活躍的;如果不是那麼這個塊是垃圾
    在這裏插入圖片描述

  • 何時清理

    1. 定期
    2. 空閒時
    3. 磁盤滿了,不得不清理
崩潰恢復
  • 保證CR原子寫:有兩個CR,分佈在磁盤兩端,交替寫入,寫入時會先寫一個頭,裏邊包含一個時間戳,然後開始寫CR body,當寫完最後一個塊時再寫入時間戳,如果是原子寫入的,那麼兩個時間戳是一致的

  • 第一種場景:因爲CR是週期性寫入,所以可能丟失數據,這種場景解決方式很簡單,丟棄最後一個CR後的更新

  • 第二種場景:CR的寫入不是原子的,解決方式如上述的保證CR原子寫的基礎上,當系統崩潰時,查找最新一個時間戳一致的CR

總結

LFS是一個優秀的文件系統,它的思想是先進的,並且和現在正逐漸流行的SSD不謀而合。並且它的思想影響非常廣,LSM是一個很多存儲引擎廣泛使用的文件結構,比如BigTable、HBase、Cassandra、LevelDB、SQLite、mangodb3.0的Wired Tiger存儲引擎。並且還影響了很多後續的文件系統,比如號稱下一代Linux文件系統btrfs、針對NAND SSD的文件系統F2FS,其基礎都是LFS,學習LFS對於理解這些很有幫助

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章