自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

我一頓操作把電腦弄崩了?。。?shù)據(jù)全沒了?。?!我該怎么辦?

開發(fā) 后端
能夠使文件系統(tǒng)工作是一回事,能夠使文件系統(tǒng)高效、穩(wěn)定的工作是另一回事,下面我們就來探討一下文件系統(tǒng)的管理和優(yōu)化。

能夠使文件系統(tǒng)工作是一回事,能夠使文件系統(tǒng)高效、穩(wěn)定的工作是另一回事,下面我們就來探討一下文件系統(tǒng)的管理和優(yōu)化。

[[320214]]

一、磁盤空間管理

文件通常存在磁盤中,所以如何管理磁盤空間是一個操作系統(tǒng)的設(shè)計者需要考慮的問題。在文件上進(jìn)行存有兩種策略:「分配 n 個字節(jié)的連續(xù)磁盤空間;或者把文件拆分成多個并不一定連續(xù)的塊」。在存儲管理系統(tǒng)中,主要有分段管理和 分頁管理 兩種方式。

正如我們所看到的,按連續(xù)字節(jié)序列存儲文件有一個明顯的問題,當(dāng)文件擴大時,有可能需要在磁盤上移動文件。內(nèi)存中分段也有同樣的問題。不同的是,相對于把文件從磁盤的一個位置移動到另一個位置,內(nèi)存中段的移動操作要快很多。因此,幾乎所有的文件系統(tǒng)都把文件分割成固定大小的塊來存儲。

1. 塊大小

一旦把文件分為固定大小的塊來存儲,就會出現(xiàn)問題,塊的大小是多少?按照「磁盤組織方式,扇區(qū)、磁道和柱面顯然都可以作為分配單位」。在分頁系統(tǒng)中,分頁大小也是主要因素。

擁有大的塊尺寸意味著每個文件,甚至 1 字節(jié)文件,都要占用一個柱面空間,也就是說小文件浪費了大量的磁盤空間。另一方面,小塊意味著大部分文件將會跨越多個塊,因此需要多次搜索和旋轉(zhuǎn)延遲才能讀取它們,從而降低了性能。因此,如果分配的塊太大會浪費空間;分配的塊太小會浪費時間。

2. 記錄空閑塊

一旦指定了塊大小,下一個問題就是怎樣跟蹤空閑塊。有兩種方法被廣泛采用,如下圖所示

第一種方法是采用磁盤塊鏈表,鏈表的每個塊中包含極可能多的空閑磁盤塊號。對于 1 KB 的塊和 32 位的磁盤塊號,空閑表中每個塊包含有 255 個空閑的塊號??紤] 1 TB 的硬盤,擁有大概十億個磁盤塊。為了存儲全部地址塊號,如果每塊可以保存 255 個塊號,則需要將近 400 萬個塊。通常,空閑塊用于保存空閑列表,因此存儲基本上是空閑的。

另一種空閑空間管理的技術(shù)是位圖(bitmap),n 個塊的磁盤需要 n 位位圖。在位圖中,空閑塊用 1 表示,已分配的塊用 0 表示。對于 1 TB 硬盤的例子,需要 10 億位表示,即需要大約 130 000 個 1 KB 塊存儲。很明顯,和 32 位鏈表模型相比,位圖需要的空間更少,因為每個塊使用 1 位。只有當(dāng)磁盤快滿的時候,鏈表需要的塊才會比位圖少。

如果空閑塊是長期連續(xù)的話,那么空閑列表可以改成記錄連續(xù)分塊而不是單個的塊。每個塊都會使用 8位、16位、32 位的計數(shù)來與每個塊相聯(lián),來記錄連續(xù)空閑塊的數(shù)量。最好的情況是一個空閑塊可以用兩個數(shù)字來表示:「第一個空閑塊的地址和空閑塊的計數(shù)」。另一方面,如果磁盤嚴(yán)重碎片化,那么跟蹤連續(xù)分塊要比跟蹤單個分塊運行效率低,因為不僅要存儲地址,還要存儲數(shù)量。

這種情況說明了一個操作系統(tǒng)設(shè)計者經(jīng)常遇到的一個問題。有許多數(shù)據(jù)結(jié)構(gòu)和算法可以用來解決問題,但是選擇一個最好的方案需要數(shù)據(jù)的支持,而這些數(shù)據(jù)是設(shè)計者無法預(yù)先擁有的。只有在系統(tǒng)部署完畢真正使用使用后才會獲得。

現(xiàn)在,回到空閑鏈表的方法,只有一個指針塊保存在內(nèi)存中。創(chuàng)建文件時,所需要的塊從指針塊中取出。當(dāng)它用完時,將從磁盤中讀取一個新的指針塊。類似地,刪除文件時,文件的塊將被釋放并添加到主存中的指針塊中。當(dāng)塊被填滿時,寫回磁盤。

在某些特定的情況下,這個方法導(dǎo)致了不必要的磁盤 IO,如下圖所示

上面內(nèi)存中的指針塊僅有兩個空閑塊,如果釋放了一個含有三個磁盤塊的文件,那么該指針塊就會溢出,必須將其寫入磁盤,那么就會產(chǎn)生如下圖的這種情況。

如果現(xiàn)在寫入含有三個塊的文件,已滿的指針不得不再次讀入,這將會回到上圖 a 中的情況。如果有三個塊的文件只是作為臨時文件被寫入,在釋放它時,需要進(jìn)行另一次磁盤寫操作以將完整的指針塊寫回到磁盤。簡而言之,當(dāng)指針塊幾乎為空時,一系列短暫的臨時文件可能會「導(dǎo)致大量磁盤 I/O」。

避免大部分磁盤 I/O 的另一種方法是拆分完整的指針塊。這樣,當(dāng)釋放三個塊時,變化不再是從 a - b,而是從 a - c,如下圖所示

現(xiàn)在,系統(tǒng)可以處理一系列臨時文件,而不需要進(jìn)行任何磁盤 I/O。如果內(nèi)存中指針塊滿了,就寫入磁盤,半滿的指針塊從磁盤中讀入。這里的思想是:要保持磁盤上的大多數(shù)指針塊為滿的狀態(tài)(減少磁盤的使用),但是在內(nèi)存中保留了一個半滿的指針塊。這樣,就可以既處理文件的創(chuàng)建又同時可以處理文件的刪除操作,而不會為空閑表進(jìn)行磁盤 I/O。

對于位圖,會在內(nèi)存中只保留一個塊,只有在該塊滿了或空了的情形下,才到磁盤上取另一個塊。通過在位圖的單一塊上進(jìn)行所有的分配操作,磁盤塊會緊密的聚集在一起,從而減少了磁盤臂的移動。由于位圖是一種固定大小的數(shù)據(jù)結(jié)構(gòu),所以如果內(nèi)核是分頁的,就可以把位圖放在虛擬內(nèi)存中,在需要時將位圖的頁面調(diào)入。

二、磁盤配額

為了防止一些用戶占用太多的磁盤空間,多用戶操作通常提供一種磁盤配額(enforcing disk quotas)的機制。系統(tǒng)管理員為每個用戶分配「最大的文件和塊分配」,并且操作系統(tǒng)確保用戶不會超過其配額。我們下面會談到這一機制。

在用戶打開一個文件時,操作系統(tǒng)會找到文件屬性和磁盤地址,并把它們送入內(nèi)存中的打開文件表。其中一個屬性告訴文件所有者是誰。任何有關(guān)文件的增加都會記到所有者的配額中。

第二張表包含了每個用戶當(dāng)前打開文件的配額記錄,即使是其他人打開該文件也一樣。如上圖所示,該表的內(nèi)容是從被打開文件的所有者的磁盤配額文件中提取出來的。當(dāng)所有文件關(guān)閉時,該記錄被寫回配額文件。

當(dāng)在打開文件表中建立一新表項時,會產(chǎn)生一個指向所有者配額記錄的指針。每次向文件中添加一個塊時,文件所有者所用數(shù)據(jù)塊的總數(shù)也隨之增加,并會同時增加硬限制和軟限制的檢查。可以超出軟限制,但硬限制不可以超出。當(dāng)已達(dá)到硬限制時,再往文件中添加內(nèi)容將引發(fā)錯誤。同樣,對文件數(shù)目也存在類似的檢查。

什么是硬限制和軟限制?「硬限制是軟限制的上限」。軟限制是為會話或進(jìn)程實際執(zhí)行的限制。這允許管理員(或用戶)將硬限制設(shè)置為允許它們希望允許的最大使用上限。然后,其他用戶和進(jìn)程可以根據(jù)需要使用軟限制將其資源使用量自限制到更低的上限。

當(dāng)一個用戶嘗試登陸,系統(tǒng)將檢查配額文件以查看用戶是否超出了文件數(shù)量或磁盤塊數(shù)量的軟限制。如果違反了任一限制,則會顯示警告,保存的警告計數(shù)減 1,如果警告計數(shù)為 0 ,表示用戶多次忽略該警告,因而將不允許該用戶登錄。要想再得到登錄的許可,就必須與系統(tǒng)管理員協(xié)商。

如果用戶在退出系統(tǒng)時消除所超過的部分,他們就可以再一次終端會話期間超過其軟限制,但「無論什么情況下都不會超過硬限制」。

三、文件系統(tǒng)備份

文件系統(tǒng)的毀壞要比計算機的損壞嚴(yán)重很多。無論是硬件還是軟件的故障,只要計算機文件系統(tǒng)被破壞,要恢復(fù)起來都是及其困難的,甚至是不可能的。因為文件系統(tǒng)無法抵御破壞,因而我們要在文件系統(tǒng)在被破壞之前做好數(shù)據(jù)備份,但是備份也不是那么容易,下面我們就來探討備份的過程。

許多人認(rèn)為為文件系統(tǒng)做備份是不值得的,并且很浪費時間,直到有一天他們的磁盤壞了,他們才意識到事情的嚴(yán)重性。相對來說,公司在這方面做的就很到位。磁帶備份主要要處理好以下兩個潛在問題中的一個:

  • 從意外的災(zāi)難中恢復(fù):這個問題主要是由于外部條件的原因造成的,比如磁盤破裂,水災(zāi)火災(zāi)等。
  • 從錯誤的操作中恢復(fù):第二個問題通常是由于用戶意外的刪除了原本需要還原的文件。這種情況發(fā)生的很頻繁,使得 Windows 的設(shè)計者們針對 刪除 命令專門設(shè)計了特殊目錄,這就是 回收站(recycle bin),也就是說,在刪除文件的時候,文件本身并不真正從磁盤上消失,而是被放置到這個特殊目錄下,等以后需要的時候可以還原回去。文件備份更主要是指這種情況,能夠允許幾天之前,幾周之前的文件從原來備份的磁盤進(jìn)行還原。

做文件備份很耗費時間而且也很浪費空間,這會引起下面幾個問題。首先,是要「備份整個文件還是僅備份一部分呢」?一般來說,只是備份特定目錄及其下的全部文件,而不是備份整個文件系統(tǒng)。

其次,對上次未修改過的文件再進(jìn)行備份是一種浪費,因而產(chǎn)生了一種增量轉(zhuǎn)儲(incremental dumps) 的思想。最簡單的增量轉(zhuǎn)儲的形式就是周期性的做全面的備份,而每天只對增量轉(zhuǎn)儲完成后發(fā)生變化的文件做單個備份。

周期性:比如一周或者一個月

稍微好一點的方式是只備份最近一次轉(zhuǎn)儲以來更改過的文件。當(dāng)然,這種做法極大的縮減了轉(zhuǎn)儲時間,但恢復(fù)起來卻更復(fù)雜,因為「最近的全面轉(zhuǎn)儲先要全部恢復(fù),隨后按逆序進(jìn)行增量轉(zhuǎn)儲」。為了方便恢復(fù),人們往往使用更復(fù)雜的轉(zhuǎn)儲模式。

第三,既然待轉(zhuǎn)儲的往往是海量數(shù)據(jù),那么在將其寫入磁帶之前對文件進(jìn)行壓縮就很有必要。但是,如果在備份過程中出現(xiàn)了文件損壞的情況,就會導(dǎo)致破壞壓縮算法,從而使整個磁帶無法讀取。所以在備份前是否進(jìn)行文件壓縮需慎重考慮。

第四,對正在使用的文件系統(tǒng)做備份是很難的。如果在轉(zhuǎn)儲過程中要添加,刪除和修改文件和目錄,則轉(zhuǎn)儲結(jié)果可能不一致。因此,因為轉(zhuǎn)儲過程中需要花費數(shù)個小時的時間,所以有必要在晚上將系統(tǒng)脫機進(jìn)行備份,然而這種方式的接受程度并不高。所以,人們修改了轉(zhuǎn)儲算法,記下文件系統(tǒng)的瞬時快照,即復(fù)制關(guān)鍵的數(shù)據(jù)結(jié)構(gòu),然后需要把將來對文件和目錄所做的修改復(fù)制到塊中,而不是到處更新他們。

磁盤轉(zhuǎn)儲到備份磁盤上有兩種方案:「物理轉(zhuǎn)儲和邏輯轉(zhuǎn)儲」。物理轉(zhuǎn)儲(physical dump) 是從磁盤的 0 塊開始,依次將所有磁盤塊按照順序?qū)懭氲捷敵龃疟P,并在復(fù)制最后一個磁盤時停止。這種程序的萬無一失性是其他程序所不具備的。

第二個需要考慮的是「壞塊的轉(zhuǎn)儲」。制造大型磁盤而沒有瑕疵是不可能的,所以也會存在一些壞塊(bad blocks)。有時進(jìn)行低級格式化后,壞塊會被檢測出來并進(jìn)行標(biāo)記,這種情況的解決辦法是用磁盤末尾的一些空閑塊所替換。

然而,一些塊在格式化后會變壞,在這種情況下操作系統(tǒng)可以檢測到它們。通常情況下,它可以通過創(chuàng)建一個由所有壞塊組成的文件來解決問題,確保它們不會出現(xiàn)在空閑池中并且永遠(yuǎn)不會被分配。「那么此文件是完全不可讀的」。如果磁盤控制器將所有的壞塊重新映射,物理轉(zhuǎn)儲還是能夠正常工作的。

Windows 系統(tǒng)有分頁文件(paging files) 和 休眠文件(hibernation files) 。它們在文件還原時不發(fā)揮作用,同時也不應(yīng)該在第一時間進(jìn)行備份。

物理轉(zhuǎn)儲和邏輯轉(zhuǎn)儲

物理轉(zhuǎn)儲的主要優(yōu)點是簡單、極為快速(基本上是以磁盤的速度運行),缺點是全量備份,不能跳過指定目錄,也不能增量轉(zhuǎn)儲,也不能恢復(fù)個人文件的請求。因此句「大多數(shù)情況下不會使用物理轉(zhuǎn)儲,而使用邏輯轉(zhuǎn)儲」。

邏輯轉(zhuǎn)儲(logical dump)從一個或幾個指定的目錄開始,遞歸轉(zhuǎn)儲自指定日期開始后更改的文件和目錄。因此,在邏輯轉(zhuǎn)儲中,轉(zhuǎn)儲磁盤上有一系列經(jīng)過仔細(xì)識別的目錄和文件,這使得根據(jù)請求輕松還原特定文件或目錄。

既然邏輯轉(zhuǎn)儲是最常用的方式,那么下面就讓我們研究一下邏輯轉(zhuǎn)儲的通用算法。此算法在 UNIX 系統(tǒng)上廣為使用,如下圖所示

邏輯轉(zhuǎn)儲算法

待轉(zhuǎn)儲的文件系統(tǒng),其中方框代表目錄,圓圈代表文件。黃色的項目表是自上次轉(zhuǎn)儲以來修改過。每個目錄和文件都被標(biāo)上其 inode 號。

此算法會轉(zhuǎn)儲位于修改文件或目錄路徑上的所有目錄(也包括未修改的目錄),原因有兩個。第一是能夠在不同電腦的文件系統(tǒng)中恢復(fù)轉(zhuǎn)儲的文件。通過這種方式,轉(zhuǎn)儲和重新存儲的程序能夠用來在兩個電腦之間傳輸整個文件系統(tǒng)。第二個原因是能夠?qū)蝹€文件進(jìn)行增量恢復(fù)。

邏輯轉(zhuǎn)儲算法需要維持一個 inode 為索引的位圖(bitmap),每個 inode 包含了幾位。隨著算法的進(jìn)行,位圖中的這些位會被設(shè)置或清除。算法的執(zhí)行分成四個階段。第一階段從起始目錄(本例為根目錄)開始檢查其中所有的目錄項。對每一個修改過的文件,該算法將在位圖中標(biāo)記其 inode。算法還會標(biāo)記并遞歸檢查每一個目錄(不管是否修改過)。

在第一階段結(jié)束時,所有修改過的文件和全部目錄都在位圖中標(biāo)記了,如下圖所示

邏輯轉(zhuǎn)儲算法

理論上來說,第二階段再次遞歸遍歷目錄樹,并去掉目錄樹中任何不包含被修改過的文件或目錄的標(biāo)記。本階段執(zhí)行的結(jié)果如下

邏輯轉(zhuǎn)儲算法

注意,inode 編號為 10、11、14、27、29 和 30 的目錄已經(jīng)被去掉了標(biāo)記,因為它們所包含的內(nèi)容沒有修改。它們也不會轉(zhuǎn)儲。相反,inode 編號為 5 和 6 的目錄本身盡管沒有被修改過也要被轉(zhuǎn)儲,因為在新的機器上恢復(fù)當(dāng)日的修改時需要這些信息。為了提高算法效率,可以將這兩階段的目錄樹遍歷合二為一。

現(xiàn)在已經(jīng)知道了哪些目錄和文件必須被轉(zhuǎn)儲了,這就是上圖 b 中標(biāo)記的內(nèi)容,第三階段算法將以節(jié)點號為序,掃描這些 inode 并轉(zhuǎn)儲所有標(biāo)記為需轉(zhuǎn)儲的目錄,如下圖所示

邏輯轉(zhuǎn)儲算法

為了進(jìn)行恢復(fù),每個被轉(zhuǎn)儲的目錄都用目錄的屬性(所有者、時間)作為前綴。

邏輯轉(zhuǎn)儲算法

最后,在第四階段,上圖中被標(biāo)記的文件也被轉(zhuǎn)儲,同樣,由其文件屬性作為前綴。至此,轉(zhuǎn)儲結(jié)束。

從轉(zhuǎn)儲磁盤上還原文件系統(tǒng)非常簡單。一開始,需要在磁盤上創(chuàng)建空文件系統(tǒng)。然后恢復(fù)最近一次的完整轉(zhuǎn)儲。由于磁帶上最先出現(xiàn)目錄,所以首先恢復(fù)目錄,給出文件系統(tǒng)的框架(skeleton),然后恢復(fù)文件系統(tǒng)本身。在完整存儲之后是第一次增量存儲,然后是第二次重復(fù)這一過程,以此類推。

盡管邏輯存儲十分簡單,但是也會有一些棘手的問題。首先,既然空閑塊列表并不是一個文件,那么在所有被轉(zhuǎn)儲的文件恢復(fù)完畢之后,就需要從零開始重新構(gòu)造。

另外一個問題是關(guān)于鏈接。如果文件鏈接了兩個或者多個目錄,而文件只能還原一次,那么并且所有指向該文件的目錄都必須還原。

還有一個問題是,UNIX 文件實際上包含了許多 空洞(holes)。打開文件,寫幾個字節(jié),然后找到文件中偏移了一定距離的地址,又寫入更多的字節(jié),這么做是合法的。但兩者之間的這些塊并不屬于文件本身,從而也不應(yīng)該在其上進(jìn)行文件轉(zhuǎn)儲和恢復(fù)。

最后,無論屬于哪一個目錄,「特殊文件,命名管道以及類似的文件」都不應(yīng)該被轉(zhuǎn)儲。

四、文件系統(tǒng)的一致性

影響可靠性的一個因素是文件系統(tǒng)的一致性。許多文件系統(tǒng)讀取磁盤塊、修改磁盤塊、再把它們寫回磁盤。如果系統(tǒng)在所有塊寫入之前崩潰,文件系統(tǒng)就會處于一種不一致(inconsistent)的狀態(tài)。如果某些尚未寫回的塊是索引節(jié)點塊,目錄塊或包含空閑列表的塊,則此問題是很嚴(yán)重的。

為了處理文件系統(tǒng)一致性問題,大部分計算機都會有應(yīng)用程序來檢查文件系統(tǒng)的一致性。例如,UNIX 有 fsck;Windows 有 sfc,每當(dāng)引導(dǎo)系統(tǒng)時(尤其是在崩潰后),都可以運行該程序。

可以進(jìn)行兩種一致性檢查:「塊的一致性檢查和文件的一致性檢查」。為了檢查塊的一致性,應(yīng)用程序會建立兩張表,每個包含一個計數(shù)器的塊,最初設(shè)置為 0 。第一個表中的計數(shù)器跟蹤該塊在文件中出現(xiàn)的次數(shù),第二張表中的計數(shù)器記錄每個塊在空閑列表、空閑位圖中出現(xiàn)的頻率。

然后檢驗程序使用原始設(shè)備讀取所有的 inode,忽略文件的結(jié)構(gòu),只返回從零開始的所有磁盤塊。從 inode 開始,很容易找到文件中的塊數(shù)量。每當(dāng)讀取一個塊時,該塊在第一個表中的計數(shù)器 + 1,應(yīng)用程序會檢查空閑塊或者位圖來找到?jīng)]有使用的塊??臻e列表中塊的每次出現(xiàn)都會導(dǎo)致其在第二表中的計數(shù)器增加。

如果文件系統(tǒng)一致,則每一個塊或者在第一個表計數(shù)器為 1,或者在第二個表計數(shù)器中為 1,如下圖所示

文件系統(tǒng)的一致性

但是當(dāng)系統(tǒng)崩潰后,這兩張表可能如下所示

文件系統(tǒng)的一致性

其中,磁盤塊 2 沒有出現(xiàn)在任何一張表中,這稱為 塊丟失(missing block)。盡管塊丟失不會造成實際的損害,但它的確浪費了磁盤空間,減少了磁盤容量。塊丟失的問題很容易解決,文件系統(tǒng)檢驗程序把他們加到空閑表中即可。

有可能出現(xiàn)的另外一種情況如下所示

文件系統(tǒng)的一致性

其中,塊 4 在空閑表中出現(xiàn)了 2 次。這種解決方法也很簡單,只要重新建立空閑表即可。

最糟糕的情況是在兩個或者多個文件中出現(xiàn)同一個數(shù)據(jù)塊,如下所示

文件系統(tǒng)的一致性

比如上圖的磁盤塊 5,如果其中一個文件被刪除,塊 5 會被添加到空閑表中,導(dǎo)致一個塊同時處于使用和空閑的兩種狀態(tài)。如果刪除這兩個文件,那么在空閑表中這個磁盤塊會出現(xiàn)兩次。

文件系統(tǒng)檢驗程序采取的處理方法是,先分配一磁盤塊,把塊 5 中的內(nèi)容復(fù)制到空閑塊中,然后把它插入到其中一個文件中。這樣文件的內(nèi)容未改變,雖然這些內(nèi)容可以肯定是不對的,但至少保證了文件的一致性。這一錯誤應(yīng)該報告給用戶,由用戶檢查受檢情況。

除了檢查每個磁盤塊計數(shù)的正確性之外,文件系統(tǒng)還會檢查目錄系統(tǒng)。這時候會用到一張計數(shù)器表,但這時是一個文件(而不是一個塊)對應(yīng)于一個計數(shù)器。程序從根目錄開始檢驗,沿著目錄樹向下查找,檢查文件系統(tǒng)的每個目錄。對每個目錄中的文件,使其計數(shù) + 1。

注意,由于存在硬連接,一個文件可能出現(xiàn)在兩個或多個目錄中。而遇到符號鏈接是不計數(shù)的,不會對目標(biāo)文件的計數(shù)器 + 1。

在檢驗程序完成后,會得到一張由 inode 索引的表,說明每個文件和目錄的包含關(guān)系。檢驗程序會將這些數(shù)字與存儲在文件 inode 中的鏈接數(shù)目做對比。如果 inode 節(jié)點的鏈接計數(shù)大于目錄項個數(shù),這時即使所有文件從目錄中刪除,這個計數(shù)仍然不是 0 ,inode 不會被刪除。這種錯誤不嚴(yán)重,卻因為存在不屬于任何目錄的文件而浪費了磁盤空間。

另一種錯誤則是潛在的風(fēng)險。如果同一個文件鏈接兩個目錄項,但是 inode 鏈接計數(shù)只為 1,如果刪除了任何一個目錄項,對應(yīng) inode 鏈接計數(shù)變?yōu)? 0。當(dāng) inode 計數(shù)為 0 時,文件系統(tǒng)標(biāo)志 inode 為 未使用,并釋放全部的塊。這會導(dǎo)致其中一個目錄指向未使用的 inode,而很有可能其塊馬上就被分配給其他文件。

五、文件系統(tǒng)性能

訪問磁盤的效率要比內(nèi)存慢的多,是時候又祭出這張圖了

從內(nèi)存讀一個 32 位字大概是 10ns,從硬盤上讀的速率大概是 100MB/S,對每個 32 位字來說,效率會慢了四倍,另外,還要加上 5 - 10 ms 的尋道時間等其他損耗,如果只訪問一個字,內(nèi)存要比磁盤快百萬數(shù)量級。所以磁盤優(yōu)化是很有必要的,下面我們會討論幾種優(yōu)化方式

1. 高速緩存

最常用的減少磁盤訪問次數(shù)的技術(shù)是使用 塊高速緩存(block cache) 或者 緩沖區(qū)高速緩存(buffer cache)。高速緩存指的是一系列的塊,它們在邏輯上屬于磁盤,但實際上基于性能的考慮被保存在內(nèi)存中。

管理高速緩存有不同的算法,常用的算法是:檢查全部的讀請求,查看在高速緩存中是否有所需要的塊。如果存在,可執(zhí)行讀操作而無須訪問磁盤。如果檢查塊不再高速緩存中,那么首先把它讀入高速緩存,再復(fù)制到所需的地方。之后,對同一個塊的請求都通過高速緩存來完成。

高速緩存的操作如下圖所示

由于在高速緩存中有許多塊,所以需要某種方法快速確定所需的塊是否存在。常用方法是將設(shè)備和磁盤地址進(jìn)行散列操作,然后,在散列表中查找結(jié)果。具有相同散列值的塊在一個鏈表中連接在一起(這個數(shù)據(jù)結(jié)構(gòu)是不是很像 HashMap?),這樣就可以沿著沖突鏈查找其他塊。

如果高速緩存已滿,此時需要調(diào)入新的塊,則要把原來的某一塊調(diào)出高速緩存,如果要調(diào)出的塊在上次調(diào)入后已經(jīng)被修改過,則需要把它寫回磁盤。這種情況與分頁非常相似,所有常用的頁面置換算法我們之前已經(jīng)介紹過,如果有不熟悉的小伙伴可以參考 https://mp.weixin.qq.com/s/5-k2BJDgEp9symxcSwoprw。比如 「FIFO 算法、第二次機會算法、LRU 算法、時鐘算法、老化算法等」。它們都適用于高速緩存。

2. 塊提前讀

第二個明顯提高文件系統(tǒng)的性能是,在需要用到塊之前,試圖提前將其寫入高速緩存,從而提高命中率。許多文件都是順序讀取。如果請求文件系統(tǒng)在某個文件中生成塊 k,文件系統(tǒng)執(zhí)行相關(guān)操作并且在完成之后,會檢查高速緩存,以便確定塊 k + 1 是否已經(jīng)在高速緩存。如果不在,文件系統(tǒng)會為 k + 1 安排一個預(yù)讀取,因為文件希望在用到該塊的時候能夠直接從高速緩存中讀取。

當(dāng)然,塊提前讀取策略只適用于實際順序讀取的文件。對隨機訪問的文件,提前讀絲毫不起作用。甚至還會造成阻礙。

3. 減少磁盤臂運動

高速緩存和塊提前讀并不是提高文件系統(tǒng)性能的唯一方法。另一種重要的技術(shù)是「把有可能順序訪問的塊放在一起,當(dāng)然最好是在同一個柱面上,從而減少磁盤臂的移動次數(shù)」。當(dāng)寫一個輸出文件時,文件系統(tǒng)就必須按照要求一次一次地分配磁盤塊。如果用位圖來記錄空閑塊,并且整個位圖在內(nèi)存中,那么選擇與前一塊最近的空閑塊是很容易的。如果用空閑表,并且鏈表的一部分存在磁盤上,要分配緊鄰的空閑塊就會困難很多。

不過,即使采用空閑表,也可以使用 塊簇 技術(shù)。即不用塊而用連續(xù)塊簇來跟蹤磁盤存儲區(qū)。如果一個扇區(qū)有 512 個字節(jié),有可能系統(tǒng)采用 1 KB 的塊(2 個扇區(qū)),但卻按每 2 塊(4 個扇區(qū))一個單位來分配磁盤存儲區(qū)。這和 2 KB 的磁盤塊并不相同,因為在高速緩存中它仍然使用 1 KB 的塊,磁盤與內(nèi)存數(shù)據(jù)之間傳送也是以 1 KB 進(jìn)行,但在一個空閑的系統(tǒng)上順序讀取這些文件,尋道的次數(shù)可以減少一半,從而使文件系統(tǒng)的性能大大改善。若考慮旋轉(zhuǎn)定位則可以得到這類方法的變體。在分配塊時,系統(tǒng)盡量把一個文件中的連續(xù)塊存放在同一個柱面上。

在使用 inode 或任何類似 inode 的系統(tǒng)中,另一個性能瓶頸是,讀取一個很短的文件也需要兩次磁盤訪問:「一次是訪問 inode,一次是訪問塊」。通常情況下,inode 的放置如下圖所示

其中,全部 inode 放在靠近磁盤開始位置,所以 inode 和它所指向的塊之間的平均距離是柱面組的一半,這將會需要較長時間的尋道時間。

一個簡單的改進(jìn)方法是,在磁盤中部而不是開始處存放 inode ,此時,在 inode 和第一個塊之間的尋道時間減為原來的一半。另一種做法是:將磁盤分成多個柱面組,每個柱面組有自己的 inode,數(shù)據(jù)塊和空閑表,如上圖 b 所示。

當(dāng)然,只有在磁盤中裝有磁盤臂的情況下,討論尋道時間和旋轉(zhuǎn)時間才是有意義的?,F(xiàn)在越來越多的電腦使用 固態(tài)硬盤(SSD),對于這些硬盤,由于采用了和閃存同樣的制造技術(shù),使得隨機訪問和順序訪問在傳輸速度上已經(jīng)較為相近,傳統(tǒng)硬盤的許多問題就消失了。但是也引發(fā)了新的問題。

4. 磁盤碎片整理

在初始安裝操作系統(tǒng)后,文件就會被不斷的創(chuàng)建和清除,于是磁盤會產(chǎn)生很多的碎片,在創(chuàng)建一個文件時,它使用的塊會散布在整個磁盤上,降低性能。刪除文件后,回收磁盤塊,可能會造成空穴。

磁盤性能可以通過如下方式恢復(fù):移動文件使它們相互挨著,并把所有的至少是大部分的空閑空間放在一個或多個大的連續(xù)區(qū)域內(nèi)。Windows 有一個程序 defrag 就是做這個事兒的。Windows 用戶會經(jīng)常使用它,SSD 除外。

磁盤碎片整理程序會在讓文件系統(tǒng)上很好地運行。Linux 文件系統(tǒng)(特別是 ext2 和 ext3)由于其選擇磁盤塊的方式,在磁盤碎片整理上一般不會像 Windows 一樣困難,因此很少需要手動的磁盤碎片整理。而且,固態(tài)硬盤并不受磁盤碎片的影響,事實上,在固態(tài)硬盤上做磁盤碎片整理反倒是多此一舉,不僅沒有提高性能,反而磨損了固態(tài)硬盤。所以碎片整理只會縮短固態(tài)硬盤的壽命。

責(zé)任編輯:趙寧寧 來源: Java建設(shè)者
相關(guān)推薦

2021-09-13 10:25:35

開發(fā)技能代碼

2018-08-20 19:39:14

區(qū)塊鏈職業(yè)崗位

2022-02-06 00:16:53

加密貨幣比特幣以太坊

2018-04-12 17:00:07

云計算燒烤SaaS

2021-10-14 11:11:58

WiFi電腦網(wǎng)絡(luò)

2021-12-09 11:46:53

DockerIPLinux

2012-12-03 09:37:39

ForefrontExchange

2022-05-17 10:41:20

接口JSON數(shù)據(jù)

2020-07-21 10:05:48

技術(shù)研發(fā)指標(biāo)

2017-12-21 20:01:38

潤乾報表

2024-11-11 14:57:56

JWTSession微服務(wù)

2018-09-26 08:16:25

2021-02-22 17:13:47

HTTP1.1協(xié)議

2020-12-21 15:40:25

技術(shù)研發(fā)管理

2019-06-03 10:53:49

MySQL硬盤數(shù)據(jù)庫

2021-12-07 11:46:33

KubernetesEvicted PodLinux

2015-11-06 10:14:36

APP虛擬服務(wù)器

2022-11-18 07:40:57

2019-06-06 10:04:45

重構(gòu)代碼原代碼

2021-01-30 09:50:54

MySQL密碼服務(wù)器
點贊
收藏

51CTO技術(shù)棧公眾號