柚子快報激活碼778899分享:運維 Linux:認識文件系統(tǒng)
柚子快報激活碼778899分享:運維 Linux:認識文件系統(tǒng)
一、認識硬件——磁盤
1.1 物理構(gòu)成
? ? ?磁盤是唯一的一個機械設備,也是一個外設!
? ? ?以前的老式電腦上裝的就是機械磁盤,現(xiàn)在由于用戶對使用計算機的速度要求越來越高,現(xiàn)在我們普通人使用的電腦基本上都是用的SSD固態(tài)硬盤,SSD固態(tài)硬盤并沒有像機械磁盤那樣的機械運動,讀寫速度更快,且具有體積小、低功耗、耐用性好、無噪音等特點!且未來還有很大的研究空間!所以在桌面領域幾乎取代了機械磁盤!
? ? ?但是企業(yè)級存儲更傾向于使用機械硬盤,由于其成本低、容量大的特點更有利于進行大規(guī)模的數(shù)據(jù)存儲,所以他其實很難被淘汰!?
1、寫入磁盤工作原理:二進制序列會通過磁頭的充放電(任何硬件都只認識二進制序列,因為本質(zhì)上是用線連接的),將數(shù)據(jù)寫到盤片上。
2、 一些特點:
(1)我們的計算機內(nèi)部的信息流動是以電子或者光電信號的形式傳遞(非常快),而磁盤是機械運動相比之下速度很慢!!
(2)盤片高速旋轉(zhuǎn),磁頭左右轉(zhuǎn)動,磁頭是一面一個且和盤面不接觸!
(3)磁盤在設計的時候必須保證無塵環(huán)境且密封完好,因為有灰塵的話可能會導致盤面刮花造成數(shù)據(jù)丟失。
(4)內(nèi)存是掉電易失存儲介質(zhì),盤片是永久性存儲介質(zhì)。
?3、注:磁盤是有壽命的,大公司磁盤快報廢的時候并不敢直接把磁盤給丟掉,因為里面存儲了大量的用戶數(shù)據(jù)(磁盤密封性好且不易被銷毀),所以相關的安全部門對大公司的磁盤銷毀工作時有嚴格的要求的!
1.2 存儲構(gòu)成
磁頭的左右擺動——>定位磁道(柱面)?
磁頭不動的時候,盤片的旋轉(zhuǎn)——>定位扇區(qū)??
所以磁盤被訪問的最基本單位是扇區(qū) ——> 512字節(jié)/4KB
——>因此我們可以把磁盤看做由無數(shù)個扇區(qū)構(gòu)成的存儲介質(zhì) !
——>所以我們要把數(shù)據(jù)存到磁盤,首先就是定位一個扇區(qū):(1)先找到哪一面(定位磁頭)(2)哪一個磁道(3)哪一個扇區(qū)
1.3 邏輯抽象
? ? ? ? 我們把假設把磁帶攤開,從邏輯上我們就可以把他看做是線性的!我們就可以用一個數(shù)組把扇區(qū)組織起來,每個下標對應著一個扇區(qū)(我們把邏輯扇區(qū)地址叫做LBA地址)!
問題1:那么我們?nèi)绾瓮ㄟ^下標找到我們要寫入的扇區(qū)呢??
問題2: 為什么扇區(qū)大小不均勻的但是LBA地址是均勻??
——>因為磁道是從中間向外輻射的,所以里面的磁道有多少個扇區(qū),外面的磁道就有多少個扇區(qū),只不過里面磁道的扇區(qū)會小一點(扇區(qū)大小不均勻)? ?但其實可以通過調(diào)整密度來變得均勻(里面的01序列稠密一點,外面的稀疏一點)?
? ? ? ? 現(xiàn)在的磁盤其實也是可以做到讓外面扇區(qū)較大的多存點數(shù)據(jù),但是這樣的話相關的算法就得更改?。?
?1.4 回歸硬件
?所以我們究竟是如何和硬件交互的呢???
不僅CPU有寄存器,其他外設也有寄存器,包括磁盤??!
CPU向磁盤發(fā)送IO方向的請求時——>
1、控制寄存器(告訴磁盤是打算讀還是打算寫)?
2、數(shù)據(jù)寄存器(告訴磁盤要寫入哪些數(shù)據(jù))
3、地址寄存器(告訴磁盤要寫的LBA地址,磁盤自己通過CHS尋址)
4、結(jié)果寄存器(CPU獲取IO請求是否成功的狀態(tài),比如可能空間不足寫入失?。?
二、文件系統(tǒng)?
? ? ? ? 通過邏輯抽象,我們可以把對扇區(qū)的地址抽象成線性的LBA地址,但是具體磁盤有多大呢?已經(jīng)用了多少扇區(qū)?哪些扇區(qū)還沒被使用?哪些扇區(qū)存的是屬性?哪些扇區(qū)存的是內(nèi)容?要往哪個扇區(qū)去寫入??——>諸如以上問題,注定了我們的操作系統(tǒng)必須想辦法把磁盤空間組織起來?。?/p>
? ? 首先是磁盤分區(qū),我們可以把一個磁盤分成多個分區(qū)。
?而每個分區(qū),都可以用以下的區(qū)域來表示
?Boot Block:?是文件系統(tǒng)中的一個特殊塊,位于文件系統(tǒng)的起始位置。 它包含了引導加載程序(Boot Loader)所需的信息,用于引導操作系統(tǒng)的啟動過程。
?Block group:每個分區(qū)被分成了一個個的block,該block的大小是由格式化確定的,不可被修改,每個block由可以細分為6個區(qū)域。
?Linux中,文件的屬性和內(nèi)容是分開存儲的!!
?2.1 inode??
? ? inode:存儲的是單個文件的全部屬性(128字節(jié)) ,一般而言,一個文件只有一個inode!
?Linux系統(tǒng)里標記文件的唯一標識用的是inode,且文件的屬性中不包含文件的名稱!!
通過ls -li 可以觀察到文件的inode編號?
其實這個信息除了通過這種方式來讀取,還有一個stat命令能夠看到更多信息?
?2.2 Data Block
? ? ?Data Block:存文件內(nèi)容的區(qū)域,以塊的形式呈現(xiàn),常見的是4KB大小,一般而言一個塊只有自己的數(shù)據(jù)!
? ? ?一個文件只有一個inode,但如果是個大文件可能會有很多個塊。所以在inode結(jié)構(gòu)體內(nèi)部會有一個block數(shù)組,存儲的是數(shù)據(jù)塊的塊號。
問題:那難道是文件內(nèi)容需要多少個數(shù)據(jù)塊,block數(shù)組就需要有多大么???
——>并不是的,block數(shù)組內(nèi)部除了一部分是直接索引(存儲文件塊號,可直接找到文件內(nèi)容),還有一小部分是二級索引(該塊號不會存儲文件內(nèi)容而是繼續(xù)存儲文件的塊號)
2.3 Bitmap?
我怎么知道,哪些塊被使用過,哪些塊沒被使用過呢???
塊位圖(Block Bitmap):Block Bitmap中記錄著Data Block中哪個數(shù)據(jù)塊已經(jīng)被占用,哪個數(shù)據(jù)塊沒有被占用
inode那么多,我怎么知道要給該文件分配哪個呢??
inode位圖(inode Bitmap):每個bit表示一個inode是否空閑可用。
問題1: 為什么我們下載一個文件需要很久,但是刪除的時候卻很快呢??
?——>刪除一個文件的時候,并不會把塊(文件內(nèi)容)清空,而僅僅只是把對應比特標志位給修改了,表明該塊是空閑可用的。?
問題2:如果我們想恢復一個被刪除的文件,要怎么辦呢???
——> 如果我們不小心誤刪的一個文件,如果這個文件很重要,最好的辦法就是什么都不做然后找專業(yè)的人去恢復(一般來說恢復其實就是得找到該文件的inode編號,比如通過Linux的日志信息找到被刪文件的inode,但是具體怎么恢復得依靠一些專業(yè)的東西!),因為雖然內(nèi)容還在,但是他的位圖信息表明是可以被使用的,所以你如果亂操作可能會導致文件內(nèi)容被覆蓋。
?2.4?GDT和超級塊
GDT(Group Descriptor Table):塊組描述符,描述塊組屬性信息(該block組的分配信息和使用情況)。
超級塊(Super Block):存放文件系統(tǒng)本身的結(jié)構(gòu)信息。記錄的信息主要有:bolck 和 inode的總量, 未使用的block和inode的數(shù)量,一個block和inode的大小,最近一次掛載的時間,最近一次寫入數(shù)據(jù)的時間,最近一次檢驗磁盤的時間等其他文件系統(tǒng)的相關信息。Super Block的信息被破壞,可以說整個 文件系統(tǒng)結(jié)構(gòu)就被破壞了 (整個分區(qū)的相關信息)
? ? ? ? 因為超級快是在組里面存在的,但是記錄了整個分區(qū)的信息,所以并不需要每個組都有,?其實理論上來說有一個就夠了(太多會影響速度),但是由于他非常重要,一旦損壞就會造成文件系統(tǒng)崩潰,所以一般來說一個分區(qū)里面會有個別組有超級快,這樣即使一個超級塊崩了,也可以通過其他超級塊區(qū)對文件系統(tǒng)做修正??!
問題:超級塊決定了文件系統(tǒng)能否正常運行,塊又那么多,操作系統(tǒng)是如何定位超級塊的呢??
?——> 魔數(shù),一個隨機值,在超級塊中的位置是確定的,只要我們操作系統(tǒng)去讀該塊的規(guī)定偏移量位置看看是否存在魔數(shù),就可以確定該塊是不是超級塊??!
2.5 格式化
? ? ? ?每個分區(qū)在使用之前,就必須提前將部分文件系統(tǒng)的屬性信息提前設置到對應的分區(qū)中,方便我們后續(xù)使用這個分區(qū)或者分組?。?/p>
? ? ? ?對磁盤做格式化可以幫助我們讓磁盤恢復到完全沒有被使用過的狀態(tài)。?
?三、對目錄的理解
3.1 新建和刪除文件,系統(tǒng)做了什么?
?1、新建文件:系統(tǒng)會在某個路徑下去創(chuàng)建,路徑幫助我們確定在哪一個分區(qū),讀取了超級塊后確定了一個block,然后通過查該block的GDT知道該分區(qū)的inode還有很多沒有被使用,于是到inodebitmap位圖結(jié)構(gòu)里找到了沒有用過的inode,然后分配給該文件,分配好之后把自己的屬性往里面填,這樣就算新建成功了??!
? ?如果還打算寫入的話,先確認一下要寫入內(nèi)容的大小,確定一下需要幾個塊,然后到blockbitmap里面找到?jīng)]被使用的塊,把塊號填到inode結(jié)構(gòu)體里面的block數(shù)組里,然后再把文件內(nèi)容寫進這些塊里面
2、刪除文件:先找到分區(qū),再找到inode,然后把對應inodebitmap和blockbitmap的位置置0。其實文件還在,只不過對應的塊可以被覆蓋?。?/p>
?我們會發(fā)現(xiàn),無論是什么操作,最重要的就是如何去找到文件的inode,可以我們?nèi)绾沃酪粋€文件的inode呢??其實使用者壓根沒關心過inode,我們只關心文件名?。?/p>
?3.2 目錄文件
目錄也是文件,也有自己的inode ,也是有內(nèi)容+屬性構(gòu)成!
?重點:目錄文件的文件內(nèi)容放的是文件的文件名+對應文件的inode映射關系!!
?問題1:為什么一個目錄下不能有同名文件??
——>因為文件名和inode是key和value的關系,key值必須唯一。
問題2:為什么沒有w無法創(chuàng)建文件??
——>w意味著無法寫,所以我們就無法將文件名和inode的映射關系寫進去,因此無法創(chuàng)建文件。
問題3:為什么沒r無法查看文件??
——>r意味著無法讀,所以我們也看不到文件名和inode的映射關系,找不到inode就找不到文件。
問題4:為什么沒有x無法進入目錄??
——>x意味著沒有操作權限,要進入一個目錄必須cd目錄名,并且將當前目錄名更新到環(huán)境變量PWD中,所以無法進行該操作的話我們就無法進入。
?問題5:通過讀取目錄文件內(nèi)容可以找到文件的inode,那么目錄的inode如何查找呢??
——>你當前的目錄其實也是別的目錄的子目錄,所以就得遞歸往上找,一直找到根目錄,然后再從根目錄往下找回來,讀取每個目錄的數(shù)據(jù)塊,直到找到該目錄的inode.所以訪問文件必須帶路徑??!
3.3 dentry緩存(擴展)
? ? ? ?找目錄的inode要遞歸向上找到根目錄,然后再找回來,難度不會很慢么??確實會的,所以Linux提供了dentry緩存,將常用文件的inode信息緩存起來?。?
? ? ? ? dentry緩存,簡稱dcache,是Linux為了提高目錄項對象的處理效率而設計的。它是一個slab cache,保存在全局變量dentry_cache中,用于保存目錄項的緩存。dentry結(jié)構(gòu)是一種含有指向父節(jié)點和子節(jié)點指針的雙向結(jié)構(gòu),多個這樣的雙向結(jié)構(gòu)構(gòu)成一個內(nèi)存里面的樹狀結(jié)構(gòu),也就是文件系統(tǒng)的目錄結(jié)構(gòu)在內(nèi)存中的緩存了。
linux 內(nèi)核 目錄項高速緩存 dentry cache 簡介-CSDN博客
四、軟硬鏈接?
建立方式:
4.1 如何理解硬鏈接?
硬鏈接不是一個獨立的文件,因為他沒有獨立的inode??!
——>所謂的建立硬鏈接,本質(zhì)上就是在特定目錄的數(shù)據(jù)塊中新增文件名和指向的文件inode編號的映射關系(有點像起別名的感覺,可以讓多個文件名指向一個inode)。?
?
問題1:為什么dir的引用計數(shù)是2??
——>因為 .? 是dir的一個硬鏈接
問題2:為什么dir的上級目錄引用計數(shù)是3?
——>因為 dir中的 ..是上級目錄的一個硬鏈接?
總結(jié):
(1)無論他的引用計數(shù)是多少,-2就是他當前子目錄的數(shù)目(比如21,那么他的子目錄就是19)
(2)所以刪除文件并不是直接把該文件的位圖清空,本質(zhì)上是先把目錄里該文件的inode映射關系去掉,然后再到inode里面把引用計數(shù)--? ?引用計數(shù)為0時才是把文件的位圖清空。
問題3:為什么Linux不允許對目錄建立硬鏈接??(重點?。。?/p>
???????
——>為了防止出現(xiàn)環(huán)的題,b比方說我們要找一個目錄的inode,會向上索引找到根目錄,再向下找回來,如果恰好這個過程中出現(xiàn)了 上級目錄的硬鏈接,那么就會回退回去,造成死循環(huán)??!
問題4:可是目錄內(nèi)部不是有. 和 .. 的硬鏈接嗎??(重點?。。?/p>
——> (1) . 和 .. 是操作系統(tǒng)創(chuàng)建的,他不讓你創(chuàng)建是為了你好,擔心你創(chuàng)建之后出現(xiàn)環(huán)的問題,其實. 和..按照道理也會有環(huán)的問題,但是操作系統(tǒng)提前規(guī)定好了 .和..不會被做搜索,這是強制規(guī)定的!所以不會有環(huán)的問題! (2)其實操作系統(tǒng)干嘛要多此一舉搞個. 和 ..呢??不就是為了方便讓用戶使用相對路徑么??? 由于目錄文件的inode需要遞歸向上索引才能找到,所以我們總是需要給想要找的文件加上絕對路徑,現(xiàn)在操作系統(tǒng)給我們. 和 .. ,我們就可以用相對路徑了!? ??
硬鏈接應用場景:通常用來做路徑定位?。】梢酝ㄟ^硬鏈接進行目錄切換?。ú怀S茫?
4.2 如何理解軟鏈接?
? ? ? 軟連接是一個獨立的文件,有獨立的inode,也有獨立的數(shù)據(jù)塊?,他的內(nèi)容里面保存的是指向的文件的路徑。(相當于windows的快捷方式)
?
?應用場景:當一個可執(zhí)行文件在路徑深處時,我們要找到他比較麻煩,如果我們在當前路徑使用,就可以在當前路徑建立一個該文件的軟連接。(可執(zhí)行程序隨便放都行,只要有軟鏈接,較常用)
?五、文件系統(tǒng)和內(nèi)存系統(tǒng)的關聯(lián)
5.1 硬件和內(nèi)存交互的基本單位
物理內(nèi)存是以4KB為基本單位的(由操作系統(tǒng)決定的)? ??
物理內(nèi)存交互的單位叫做頁框,而磁盤交互的單位叫做頁幀
?問題:為什么是4KB而不是要多少給多少呢??難道我訪問100字節(jié)不比訪問4KB快嗎??
——>理論上是這樣的,但是100字節(jié)可能在4KB的不同位置,需要訪問的話還需要對磁盤做更精細的計算(磁盤速度太慢了),甚至是文件系統(tǒng)也需要更精細的方法,操作系統(tǒng)文:你能保證你后幾秒不用上下文數(shù)據(jù)嗎??反正4kB和100字節(jié)效率差不是很多,我都給你拿過來,說不定你用得上呢?。ǜ鶕?jù)局部性原理:程序傾向于訪問近期或者近鄰的數(shù)據(jù),這是計算機性能優(yōu)化的重要原則,合理運用可以整體提速?。?/p>
?總結(jié):(1)硬件:減少IO的次數(shù)——減少訪問外設的次數(shù)
(2)軟件:基于局部性原理而產(chǎn)生的預加載——整體提速
5.2 操作系統(tǒng)如何管理內(nèi)存
? ? ? ?虛擬地址是操作系統(tǒng)提供的,我們用戶只能看到純的虛擬地址,具體這個虛擬地址具體映射到物理內(nèi)存的哪個位置,我們并不關心也并不知道,這是操作系統(tǒng)幫我們決定好的,所以操作系統(tǒng)必然可以看得到物理地址?。?/p>
? ? ? ? 那么操作系統(tǒng)要如何去管理我們的內(nèi)存呢??
?Page的配置不能太大,因為這樣的話會占據(jù)大量的空間。
?flag:檢查當前page的狀態(tài)(比如說當前檢測到我們要訪問的內(nèi)容并沒有被加載到內(nèi)存中,所以這個時候就會發(fā)生缺頁中斷)?
count:引用計數(shù)(可以通過引用計數(shù)知道當前有多少個進程在共享我這個page,當有進程需要去修改內(nèi)部的數(shù)據(jù)的時候,就會發(fā)生寫時拷貝)
所有申請內(nèi)存的工作,本質(zhì)上都是訪問Page數(shù)組?。。ǜ鶕?jù)一個隨機地址判斷這個地址屬于哪個Page的方法:1KB=2^10字節(jié)? 所以4KB=2^12字節(jié)? 恰好在16進制地址中就是后三位數(shù)字,所以我們?nèi)魏我粋€地址只要 & 0xFFFF F000 ,就可以找到該地址對應的Page)?
5.3 文件頁緩沖區(qū)
在Linux中,我們每一個進程打開的每一個文件都具有自己的inod和文件頁緩沖區(qū)!!
? ? ? 在我們的file結(jié)構(gòu)體貍貓有一個address_spqce結(jié)構(gòu)體,里面又有一個page_tree,里面又有一個?radix_tree_node節(jié)點?
?page_tree這個結(jié)構(gòu)有點類似于B樹。他不斷延伸最后會找到我們想要尋找的Page結(jié)構(gòu)體!
內(nèi)存管理,并不是直接讓那個我們?nèi)ピL問page數(shù)組,而是通過一些配套的算法。?
5.4 字典樹的理解
? ? ? 以上是一顆相對簡單的字典樹(組合式的KV模型),比方說我們想要找cba,我們就可以按照這顆樹索引下去,找到我們想要找到的內(nèi)容(某個對象數(shù)據(jù))?
?為什么操作系統(tǒng)要用字典樹這個結(jié)構(gòu)來管理我們的page呢??
——>因為文件的內(nèi)容按照4KB是有偏移量的。(雖然我們的塊是4KB大小,但是我們不一定是在開頭去讀取或?qū)懭?,而操作系統(tǒng)通過字典樹這種組合式的KV結(jié)構(gòu)來幫助我們定位具體的位置)
5.5 串聯(lián)進程管理、文件管理、內(nèi)存管理
? ? ? ? ?首先我們創(chuàng)建了一個進程,創(chuàng)建了一個PCB結(jié)構(gòu)體,然后還會順便創(chuàng)建一張文件描述符表,我們調(diào)用C接口去打開寫入文件的時候,該文件會在該文件描述符表中分配一個位置,然后創(chuàng)建一個file結(jié)構(gòu)體,里面分配了inode,但是文件的內(nèi)容會先寫入在C層的緩沖區(qū),?當滿足刷新策略的時候,再通過一些方式將其刷新到我們的page中(內(nèi)核緩沖區(qū))。然后最后再刷新到磁盤中。所以這個過程數(shù)據(jù)被拷貝了3次
? ? ? 當我們的進程將數(shù)據(jù)交給內(nèi)存后,其實他就不管了,所以我們的操作系統(tǒng)必須關心內(nèi)存要如何刷新到磁盤上,且可能同一時間有大量的IO請求,因此我們的操作系統(tǒng)也要關心先執(zhí)行哪個請求。所以這就涉及到IO子系統(tǒng)(操作系統(tǒng)和驅(qū)動做交互的系統(tǒng))?
? 我們的IO請求會將相關的一些需求和配置寫到一個request結(jié)構(gòu)體里,然后再由操作系統(tǒng)做管理
——>因為我們的不同的IO請求可能是向不同的扇區(qū)寫入,所以我們肯定希望比較接近的扇區(qū)在一起被寫入,這樣減少磁頭定位能夠提高整體效率,所以我們會用一個隊列把request管理起來,然后設計一些IO排序和IO合并算法,來給IO請求整體提速!!
? ? ?
? ? ? ?在我們開機的時候,因為物理內(nèi)存經(jīng)常需要跟磁盤做交互,所以會提前把一些訪問物理內(nèi)存所需要的區(qū)域會被預先加載進去,尤其是文件系統(tǒng)的相關功能。
——>說明操作系統(tǒng)真的幫助我們做了很多事情?。?
?5.6 slab分配器和伙伴系統(tǒng)(擴展)
從我們創(chuàng)建進程開始,或者是申請文件,我們就會有各種各樣的結(jié)構(gòu)體不斷地被創(chuàng)建和釋放
? ? ? 所以當我們的內(nèi)核數(shù)據(jù)結(jié)構(gòu)想要釋放的時候,操作系統(tǒng)并不會直接釋放,而是會把一些高頻使用的內(nèi)核數(shù)據(jù)結(jié)構(gòu)體通過某些機制暫時緩存起來,當你下次需要的時候你就不需要跟內(nèi)存模塊做申請,而是直接把之前緩存里面的內(nèi)核數(shù)據(jù)結(jié)構(gòu)拿出來初始化即可!
slap分配器:Linux 內(nèi)核 | 內(nèi)存管理——slab 分配器 - 知乎 (zhihu.com)?
伙伴系統(tǒng):一篇看懂!伙伴系統(tǒng)之伙伴系統(tǒng)概述--Linux內(nèi)存管理 - 知乎 (zhihu.com)
?
柚子快報激活碼778899分享:運維 Linux:認識文件系統(tǒng)
參考鏈接
本文內(nèi)容根據(jù)網(wǎng)絡資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。
轉(zhuǎn)載請注明,如有侵權,聯(lián)系刪除。