本篇文章為大家展示了如何深入理解Linux VFS和Page Cache,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過(guò)這篇文章的詳細(xì)介紹希望你能有所收獲。
峨山縣網(wǎng)站制作公司哪家好,找成都創(chuàng)新互聯(lián)!從網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、響應(yīng)式網(wǎng)站等網(wǎng)站項(xiàng)目制作,到程序開發(fā),運(yùn)營(yíng)維護(hù)。成都創(chuàng)新互聯(lián)從2013年開始到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來(lái)保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選成都創(chuàng)新互聯(lián)。
VFS是虛擬文件系統(tǒng)層(進(jìn)程與文件系統(tǒng)之間的抽象層),與它相關(guān)的數(shù)據(jù)結(jié)構(gòu)只存在于物理內(nèi)存當(dāng)中。其目的是屏蔽下層具體文件系統(tǒng)操作的差異,為上層的操作提供一個(gè)統(tǒng)一接口,正是由于VFS的存在,Linux中允許多個(gè)不同的文件系統(tǒng)共存。
VFS中包含著向物理文件系統(tǒng)轉(zhuǎn)換的一系列數(shù)據(jù)結(jié)構(gòu),如VFS超級(jí)塊、VFS的Inode、各種操作函數(shù)的轉(zhuǎn)換入口等。Linux中VFS依靠四個(gè)主要的數(shù)據(jù)結(jié)構(gòu)來(lái)描述其結(jié)構(gòu)信息,分別為超級(jí)塊、索引結(jié)點(diǎn)、目錄項(xiàng)和文件對(duì)象,這些數(shù)據(jù)結(jié)構(gòu)大都會(huì)與磁盤上的對(duì)應(yīng)上。
超級(jí)塊(Super Block):超級(jí)塊對(duì)象表示一個(gè)文件系統(tǒng)。它存儲(chǔ)一個(gè)已安裝的文件系統(tǒng)的控制信息,包括文件系統(tǒng)名稱(比如Ext2)、文件系統(tǒng)的大小和狀態(tài)、塊設(shè)備的引用和元數(shù)據(jù)信息(比如空閑列表等等)。超級(jí)塊與磁盤上文件系統(tǒng)的超級(jí)塊對(duì)應(yīng)。
索引結(jié)點(diǎn)(Inode):索引結(jié)點(diǎn)對(duì)象存儲(chǔ)了文件的相關(guān)元數(shù)據(jù)信息,例如:文件大小、設(shè)備標(biāo)識(shí)符、用戶標(biāo)識(shí)符、用戶組標(biāo)識(shí)符等等。Inode分為兩種:一種是VFS的Inode,一種是具體文件系統(tǒng)的Inode。前者在內(nèi)存中,后者在磁盤中。所以每次其實(shí)是將磁盤中的Inode調(diào)進(jìn)填充內(nèi)存中的Inode,這樣才是算使用了磁盤文件Inode。當(dāng)創(chuàng)建一個(gè)文件的時(shí)候,就給文件分配了一個(gè)Inode。一個(gè)Inode只對(duì)應(yīng)一個(gè)實(shí)際文件,一個(gè)文件也會(huì)只有一個(gè)Inode(Unix/Linux系統(tǒng)中目錄也是一種文件,打開目錄實(shí)際上就是打開目錄文件。目錄文件的結(jié)構(gòu)非常簡(jiǎn)單,就是一系列目錄項(xiàng)(dirent)的列表。每個(gè)目錄項(xiàng),由兩部分組成:所包含文件的文件名,以及該文件名對(duì)應(yīng)的inode號(hào)碼)。
目錄項(xiàng)(Dentry):引入目錄項(xiàng)對(duì)象的概念主要是出于方便查找文件的目的。不同于前面的兩個(gè)對(duì)象,目錄項(xiàng)對(duì)象只存在于內(nèi)存中,實(shí)際對(duì)應(yīng)的是磁盤的目錄innode對(duì)象。VFS在查找的時(shí)候,根據(jù)一層一層的目錄項(xiàng)找到對(duì)應(yīng)的每個(gè)目錄項(xiàng)的Inode,那么沿著目錄項(xiàng)進(jìn)行操作就可以找到最終的文件。
文件對(duì)象(File):文件對(duì)象描述的是進(jìn)程已經(jīng)打開的文件。因?yàn)橐粋€(gè)文件可以被多個(gè)進(jìn)程打開,所以一個(gè)文件可以存在多個(gè)文件對(duì)象,但多個(gè)文件對(duì)象其對(duì)應(yīng)的索引節(jié)點(diǎn)和目錄項(xiàng)對(duì)象肯定是惟一的,關(guān)系如下圖:
由于進(jìn)程中File對(duì)象有獨(dú)立的文件偏移量(current file offset),因此多個(gè)進(jìn)程可以讀寫文件的不同位置的數(shù)據(jù),但是一般不建議這樣玩,因?yàn)橄到y(tǒng)不保證該情況下的寫的原子性,多進(jìn)程可以通過(guò)文件鎖實(shí)現(xiàn)對(duì)文件內(nèi)容的寫保護(hù)。
Page cache是通過(guò)將磁盤中的數(shù)據(jù)緩存到內(nèi)存中,從而減少磁盤I/O操作,從而提高性能。此外,還要確保在page cache中的數(shù)據(jù)更改時(shí)能夠被同步到磁盤上,后者被稱為page回寫(page writeback)。一個(gè)inode對(duì)應(yīng)一個(gè)page cache對(duì)象,一個(gè)page cache對(duì)象包含多個(gè)物理page。
當(dāng)內(nèi)核發(fā)起一個(gè)讀請(qǐng)求時(shí)(例如進(jìn)程發(fā)起read()請(qǐng)求),首先會(huì)檢查請(qǐng)求的數(shù)據(jù)是否緩存到了page cache中,如果有,那么直接從內(nèi)存中讀取,不需要訪問(wèn)磁盤,這被稱為cache命中(cache hit)。如果cache中沒(méi)有請(qǐng)求的數(shù)據(jù),即cache未命中(cache miss),就必須從磁盤中讀取數(shù)據(jù)。然后內(nèi)核將讀取的數(shù)據(jù)緩存到cache中,這樣后續(xù)的讀請(qǐng)求就可以命中cache了。page可以只緩存一個(gè)文件部分的內(nèi)容,不需要把整個(gè)文件都緩存進(jìn)來(lái)。
當(dāng)內(nèi)核發(fā)起一個(gè)寫請(qǐng)求時(shí)(例如進(jìn)程發(fā)起write()請(qǐng)求),同樣是直接往cache中寫入,此時(shí)不會(huì)立即同步到磁盤,而是將寫入的page設(shè)置為臟頁(yè),并將其加入dirty list中,內(nèi)核會(huì)負(fù)責(zé)定期同步到磁盤保持二者一執(zhí)行。
page cache另一個(gè)主要工作是回收page釋放內(nèi)存空間,此時(shí)會(huì)選擇合適的page進(jìn)行釋放,如果是臟頁(yè)會(huì)先同步到磁盤然后釋放。此時(shí)是如何選擇cache頁(yè)的呢?Linux使用的策略是基于LRU改進(jìn)的Two-List策略:
Two-List策略維護(hù)了兩個(gè)list,active list 和 inactive list。在active list上的page被認(rèn)為是hot的,不能釋放。只有inactive list上的page可以被釋放的。首次緩存的數(shù)據(jù)的page會(huì)被加入到inactive list中,已經(jīng)在inactive list中的page如果再次被訪問(wèn),就會(huì)移入active list中。兩個(gè)鏈表都使用了偽LRU算法維護(hù),新的page從尾部加入,移除時(shí)從頭部移除,就像隊(duì)列一樣。如果active list中page的數(shù)量遠(yuǎn)大于inactive list,那么active list頭部的頁(yè)面會(huì)被移入inactive list中,從而位置兩個(gè)表的平衡。
觸發(fā)臟頁(yè)回寫到磁盤時(shí)機(jī)如下:
用戶進(jìn)程調(diào)用sync() 和 fsync()系統(tǒng)調(diào)用;
空閑內(nèi)存低于特定的閾值(threshold);
Dirty數(shù)據(jù)在內(nèi)存中駐留的時(shí)間超過(guò)一個(gè)特定的閾值。
注意這里的page cache的臟頁(yè)回寫機(jī)制可以和mmap的臟頁(yè)回寫機(jī)制做下對(duì)比,mmap會(huì)在一定時(shí)間后系統(tǒng)自動(dòng)回寫臟頁(yè)面到磁盤,也就是說(shuō)mamp中修改過(guò)的臟頁(yè)面并不會(huì)立即更新回文件中,而是有一段時(shí)間的延遲,可以調(diào)用msync()來(lái)強(qiáng)制同步, 這樣所寫的內(nèi)容就能立即保存到文件里了。
上述內(nèi)容就是如何深入理解Linux VFS和Page Cache,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。