最近
個月以來
Linux已經鞏固了其作為服務器操作系統的地位
就像集群(cluster)對於企業級的應用很重要那樣
日志文件系統(journaling file system)也是同樣重要的
為什麼日志文件系統很重要呢?它是怎樣工作的呢?有哪些日志文件系統可以用於Linux?
日志文件系統比傳統的文件系統安全
因為它用獨立的日志文件跟蹤磁盤內容的變化
就像關系型數據庫(RDBMS)
日志文件系統可以用事務處理的方式
提交或撤消文件系統的變化
Ext
不能滿足要求
盡管Linux可以支持種類繁多的文件系統
但是幾乎所有的Linux發行版都用ext
作為默認的文件系統
Linux可以支持的文件系統有
FAT
VFAT
HPFS(OS/
)
NTFS(Windows NT)
Sun的UFS
等等
ext
的設計者主要考慮的是文件系統的效率和性能方面的問題
ext
在寫入文件內容的同時並沒有同時寫入文件的meta
data(和文件有關的信息
例如
權限
所有者以及創建和訪問時間)
換句話說
Linux先寫入文件的內容
然後等到有空的時候才寫入文件的meta
data
如果在寫入文件內容之後但在寫入文件的meta
data之前
突然斷電了
文件系統就會處於不一致的狀態
在一個需要大量文件操作的系統中(例如
像Hotmail這樣的免費的Web e
mail)
出現這種情況會導致很嚴重的後果
日志文件系統可以幫助解決這個問題
假定你正在更新一個目錄項(directory entry)
你已經在這個巨大的目錄項的第五個文件塊(block)中改變了
個文件項(file entry)
當正在寫這個文件塊的時候突然間斷電了
這個文件塊還沒有寫完
也就是被損壞了
重新啟動的時候
Linux(就像其它的Unix)會運行一個叫做
fsck
(file system check)的程序
掃描整個文件系統
保證所有的文件塊都被正確地分配或使用
它將找到這個被損壞的目錄項並試圖修復它
但是不能夠保證fsck一定能夠修復損壞
修復不了是經常的事
所以
當出現上面那種情況
目錄項中所有的文件項可能會丟失
也就造成文件的丟失
如果文件系統很大
fsck掃描要費很長時間
在一個有數十億個文件的計算機上
fsck可能要運行
個小時以上
在這段時間內
系統是不可用的
也就是導致了很長的當機時間
日志文件系統可以避免這種情況
文件系統是怎樣工作的?
文件系統通過為每個文件分配文件塊的方式把數據存儲在存儲設備中
這樣就要維護每一個文件的文件塊的分配信息
而分配信息本身也要存在磁盤上
DOS和Windows的用戶可能還記得FAT這種文件系統吧
不同的文件系統用不同的方法分配和讀取文件塊
有兩種常用的文件系統的分配策略
塊分配(block allocation)和擴展分配(extent allocation)
塊分配當文件變大的時候每一次都為這個文件分配磁盤空間
而擴展分配則是當某個文件的磁盤空間不夠的時候
一次性為它分配一連串連續的塊
傳統的Unix文件系統使用的塊分配的機制提供了一個靈活而高效的文件塊分配策略
磁盤上的文件塊根據需要分配給文件
這樣可以減少存儲空間的浪費
當一個文件慢慢變大的時候
就會造成文件中文件塊的不連續
這就導致了過多的磁盤尋道時間
當讀取一個文件的時候有可能要隨機而不是連續地讀取文件塊
這樣的效率很低
可以通過優化文件塊的分配策略(盡可能為文件分配連續的塊)來避免文件塊的隨機分配
通過使用聰明的塊分配策略
可以實現塊的連續分配
這樣就可以減少磁盤的尋道時間
但是
當整個文件系統的文件塊的分配形成碎片的時候
就再也不可能連續分配了
每一次當文件擴展的時候
塊分配的算法就要寫入一些關於新分配的塊所在位置的信息
如果每一次文件擴展的時候只增加一個塊
那麼就需要很多額外的磁盤I/O用來寫入文件塊的結構信息
文件塊的結構信息也就是上面說的meta
data
meta
data總是一起同時地寫入存儲設備的
這就意味著改變文件大小的操作要等到所有的meta
data的操作都完成之後才能進行
因此
meta
data的操作會顯著地降低整個文件系統的性能
基於擴展(Extent
based)的分配方式
擴展分配方式一次性為文件分配很多連續的塊
當創建一個文件的時候
很多文件塊同時被分配
當文件擴展的時候
也一次分配很多塊
文件系統的meta
data在文件創建的時候被寫入
當文件的大小沒有超過所有已分配的文件塊的大小
就不用寫入meta
data
(直到需要再分配文件塊的時候)
這樣可以優化磁盤尋道的方式
可以成組地分配塊
有利於一次寫一大批數據到存儲設備中
這樣就可以減少SCSI設備寫數據的時間
基於擴展分配的文件系統在讀取順序文件的時候有很好的性能
因為文件塊都是成組連續分配的
但是
如果I/O操作是隨機的
基於擴展分配的文件系統的好處就非常有限了
例如
當我們要連續地讀取一個基於擴展分配的文件的時候
我們只要讀起始塊號和文件長度就行了
然後
就可以連續地讀取所有的文件塊了
這樣在順序讀取文件的時候
讀meta
data的開銷就很小
反之
如果隨機地讀取文件
我們就要先查找每一個所需塊的塊地址然後再讀取塊的內容
這樣就和塊分配方式很象了
在ext
文件系統中
對寫性能的增強是通過盡量延遲寫的時間
這樣就能一次寫一大批數據而不是每次寫一小點
隨之而來的就是系統效率的提高
同樣
當讀的時候
ext
也是一次讀取一整組的塊
也就是采用預讀策略
這樣就能提高ext
文件系統的讀性能
大量減少每次讀取少量數據的I/O操作
文件塊的組或塊簇(block cluster)的大小是在編譯的時候確定的
怎樣設定簇的大小不是這篇文章所要介紹的內容
但是
可以這麼說
簇的大小對文件系統的性能確實有很大的影響
而且簇的大小也是文件系統設計的時候需要考慮的一個很重要的方面
象Veritas這樣的擴展分配的文件系統和象ext
這樣的
成簇寫
(write
clustering)的文件系統
在默認情況下都使用
字節的塊而不用
k字節的塊
如果ext
用
k而不是
k字節的塊
大概會有
%的性能提升
但是
為了減少被浪費的空間ext
文件系統的設計者建議使用
k字節的塊
日志文件系統是怎樣解決問題的?
先提醒你一下
這節標題可能容易導致誤解
日志文件系統確實解決了上面提到的一些問題
但是又帶來了新問題
日志文件的設計思想是跟蹤文件系統的變化而不是文件系統的內容
為了更好地解釋這個問題
下面我用ext
文件系統和日志文件系統舉一個例子
當我們改變文件
test
file
的內容的時候會出現什麼情況?先假定
test
file
的inode有四個數據塊
用來保存
test
file
文件的數據塊的塊號分別為
和
(因為在
和
之間的塊已經分配給其它文件了
所以這些塊不連續)
當硬盤要先找到
讀兩塊
在跳到
再讀兩塊
才能讀取整個文件
假定你改變了第三塊
文件系統會讀取第三塊
改變它
然後重新寫入第三塊
這一塊還在
這個位置
如果你往文件中添加了一些內容
就要從別的地方另外分配一些空余的塊
如果在日志文件系統中
情況就有所不同
日志文件系統不會改變第
塊的內容
它會把
test
file
的inode的一個拷貝和新的第三塊保存到磁盤上
在內存中的inode列表需要更新
讓
test
file
使用新的inode
所有的變化
添加和改變需要被記錄到一個文件系統中被稱為
日志
的那部分中去
每隔一段時間
文件系統在
檢查點
(check point)回更新在磁盤上的inode
並且釋放文件中用不到的那些舊塊(例如
test
file
文件最初的第三塊)
在系統崩潰之後
日志文件系統很快就能恢復
它需要恢復的只是日志中記錄下來的很少的幾塊
當斷電之後
fsck
只要用幾秒鐘的掃描時間
這就是我所說的解決了一些問題!
但是
文件系統為得到額外的安全也是要付出代價的
這就是系統開銷
每一次更新和大多數的
日志
操作都需要寫同步
這樣就需要更多的磁盤I/O操作
系統管理員就面臨這樣一個問題
為了有一個更安全的文件系統值不值得犧牲一部分性能?
大多數系統管理員會根據實際情況作出決定
沒有必要把
/usr
目錄放在日志文件系統上因為
/usr
目錄大部分是只讀的操作
但是
可以考慮把
/var
或包含e
mail spool文件的目錄放在日志文件系統上
幸運的是在Linux系統中可以根據需要混合使用這些文件系統
日志文件系統還有一個問題就是更容易產生碎片
因為它的文件分配方式與眾不同
很容易在文件系統中到處產生碎片
ext
文件系統也會產生碎片但是可能不會有這麼嚴重
每個月定期把文件系統備份到磁帶中然後重新恢復
不僅可以解決這問題
而且可以檢查備份/恢復的過程是否正確
想得到一些好處
總是要付出一些代價的
不是嗎?
可供選擇的Linux日志文件系統
當我寫這篇文章的時候
有兩個日志文件系統還在開發
有三個日志文件系統可供使用
SGI的xfs()日志文件系統和Veritas()的文件系統和卷管理(volume manager)
這兩個文件系統在五個月前就發布了
但是現在還不能得到源代碼
SGI的xfs是基於Irix(SGI的Unix)上已經實現的xfs
SGI已經宣布xfs為Open Source的軟件
兩個馬上就可以得到的日志文件系統是reiserfs和IBM的jfs
這兩文件系統都是開放源代碼的而且很多有天賦的人在開發這兩個文件系統
jfs(Journaled File System Technology for Linux)的開發者包括AIX(IBM的Unix)的jfs的主要開發者
在A
From:http://tw.wingwit.com/Article/program/Oracle/201311/16650.html