引言
過去幾十年CPU速度的增長是巨大的,但是磁盤的訪問速度卻增長較慢。內存近些年發展也很快,可以提供較大的空間存儲程序的工作集,因此磁盤傳輸主要是被寫操作支配。因此如何提升寫效率是有效利用磁盤的關鍵。
日誌結構文件系統是用順序寫,因爲省去了絕大部分seek操作,因此大大提升了寫的性能。還有一個好處就是系統崩潰恢復,日誌結構文件系統只需要檢查最近的部分日誌
日誌結構文件系統實現
基本假設
- 大部分的讀請求都從緩存中讀取
- 大部分磁盤訪問都是寫請求
段概念
-
段定義:雖然磁盤順序寫效率高,考慮一下,如果有一個文件執行寫操作就寫,但是如果中間間隔一會兒寫另一個文件,那麼中間磁盤已經旋轉。要想獲得高效率,必須連續順序寫,因此需要在內存中緩存修改的塊,直到達到一定數量的時候執行一次寫操作,這個大塊叫做段
-
段佈局:段中不僅包含了數據塊,也包括i-node塊,段的開頭還包括一個段summary塊,包含了垃圾回收需要的關鍵信息,後邊詳細解釋
-
緩存大小:代表寫操作前旋轉和尋道開銷時間,磁盤傳輸速率MB/s,因此傳輸MB需要的時間
寫效率
寫效率是以傳輸速率爲基準,用F(0<F<1)表示
變換得到
假設要得到90%的效率,假設爲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中
垃圾回收
-
垃圾產生的原因
-
文件更新導致的老的數據塊和i-node塊無效,如下圖
-
文件增加導致的老的i-node塊無效,如下圖
-
-
垃圾回收流程
讀出舊的段,將段中有效的塊複製到內存緩存中,當量達到一個段大小時,像普通修改文件那樣以日誌方式寫入磁盤,舊的段便釋放了,下圖大概描述了垃圾回收的流程,假設讀入segment 1和segment 2然後整理出有效的塊並剛好組成一個段,寫入磁盤,因此清理點就後移2個段,而寫入點後移一個,當寫入點達到磁盤最大值時,指針又移到磁盤開始位置,因此在LFS文件系統中,磁盤被抽象成一個大環形數組結構
-
如何分辨垃圾
前邊我們提到過段summary塊,這個塊主要記錄了段內塊的摘要信息,每個塊所屬的i-node和offset。如何確定哪些塊是垃圾呢?我們加載段到內存,然後根據段summary信息,查看一個塊所屬的i-node號,然後從imap中查詢最新的i-node存放地址,加載到內存中然後找到offset對應的地址是否爲段中塊的地址,如果是,那麼這個塊是活躍的;如果不是那麼這個塊是垃圾
-
何時清理
- 定期
- 空閒時
- 磁盤滿了,不得不清理
崩潰恢復
-
保證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對於理解這些很有幫助