首先,我們來看一下磁盤的內部結構:
磁盤是由盤面+讀寫磁頭+主軸+組合臂+磁臂組成,我們忽略機械組件,主要研究讀寫磁頭(讀取和寫入數據)和盤面兩(存儲數據)
然后,我們再來了解一下關於磁盤的一些名詞:
磁道:我們可以把盤面當成是由無數個大小不一樣的圓圈組成,盤面上一圈一圈的就叫磁道
柱面:所有的盤面上同一位置的磁道會形成一個圓柱體,我們把它叫做柱面
扇區:每個磁道上面,可以分成一個一個的扇區,扇區是存儲數據的最小單元
之后,我們來看一下磁盤是如何工作的:
旋轉:磁盤運行的時候,是由主軸帶着盤面飛速旋轉,轉速越快的磁盤,讀寫的速度就會越快
尋道時間:當我們從磁盤上讀數據的時候,我們會告訴磁頭,我要取x盤面y磁道z扇區上面的數據(或者叫x柱面y磁頭z扇區),然后對應的磁頭就會指到該磁道上面,我們把這個過程叫做”尋道時間”
旋轉時間:磁頭找到該磁道以后,再由主軸帶動旋轉道對應的扇面,我們把這個過程叫做”旋轉時間“
讀取時間:所有磁盤讀取數據的時間就是尋道時間加旋轉時間
下面,我們再來看一下什么是”塊“:
為了使我們告知磁盤去尋找磁盤位置的時候更加方便,我們發明了LBA(Logical Block Address)的尋址方式,把磁盤邏輯上分成一個個”塊“,給這些塊依次編號,比如:1、2、3...,n;我們在尋找磁盤位置的時候,只需要把”塊“的編號告訴磁盤,然后磁盤會在內部將”塊“編號轉換成盤面+磁道+扇區來讀取寫入數據,格式化的過程就是將磁盤進行分”塊“
接下來,我們來看一下扇區和塊之間的關系:
扇區是磁盤存儲數據的最小單位,磁盤本身並沒有塊的概念,我們可以把塊看成是邏輯上的磁盤單位,不同的文件系統中,塊的大小是不同的
在linux系統中,我們通過下面的命令,可以查看扇區的大小:fdisk -l | grep Sector, 查看塊的大小:tune2fs -l /dev/vda1 | grep "Block size",ext4文件系統中,block的大小是4096byte(4k),則一個block包含8個扇區
下面,我們來思考一下,當我們想存一張48k大小的照片,流程會是什么樣的呢:
有一種方法是這樣的:
我們命令硬盤 ,我需要12個塊來存數據,你把塊的編號返回我,之后磁盤返回空閑塊的編號給我,分別是3,9,11,24,33...,我們根據磁盤返回給我們的編號,將數據存入磁盤,然后記下這些塊的編號,以便在下次需要讀取圖片的時候使用
用這個方法,一兩條數據還好,要是成千上萬條,那還不崩潰了。
實際上我們現在使用的方法是這個樣子的:
找到一個目錄,然后把圖片放進去就可以了,就這么方便,我們下一次讀取的時候,只需要記住文件的目錄和文件名就好了,剩下的工作就交給操作系統來完成了,操作系統在這個過程中,都做了哪些事情呢
我們接着來看,當我們讀取寫入文件的時候,操作系統幫我做了哪些事情呢:
我們創建一個文件以后,操作系統記錄文件對應的塊編號,比如文件img.jpg占據磁盤塊1~12,但是操作系統具體是如何管理文件對應的塊的呢,它也想了很多辦法。
方法一:采用連續的塊來存儲文件,這樣做的好處是,訪問文件的效率會很好,但是不連續的塊無法使用,會造成磁盤嚴重的浪費。
方法二:采用鏈式的方法存儲文件,文件從第一塊磁盤開始,形成一條鏈,這樣就解決了磁盤浪費的情況,但是讀取的效率又慢了很多。
方法三:專門在磁盤中划分出一些特殊的磁盤塊,這些塊不存儲真實的數據,專門存放文件對應的存放數據塊的編號,我們把這樣的磁盤塊叫做inode索引塊,這樣,當我們讀取文件的時候,先去inode索引塊中查找對應的數據塊,然后再去取數據。這個方法是不是好了很多呢
我們接受了方法三的方式,那么我們來看一下inode節點里面都放了些什么東西:
每一個文件都對應了一個inode塊:inode塊里面不僅存儲了真實數據存放的數據塊的編號,還記錄了文件的權限,所有者,創建時間等等信息。
接下來,我們來看一下inode塊可能會帶來什么問題:
我們來舉個栗子:假設我們的inode的大小是4096byte,存放非數據塊信息用掉了512byte,剩下的3584byte可以用來存放數據塊對應的信息,每個數據塊編號的存儲需要32byte,也就是這個inode可以存儲3584/32=112個編號,及112個數據塊,112個數據塊可以存放112*4096byte大小的數據,但是文件大小要是超出這個大小怎么辦呢,那inode豈不是放不下這些信息了嗎
針對上面的問題,我們來看一下什么是間接塊:
間接塊的誕生,就是解決大文件的inode問題,如下圖,我們使用一個位置,來記錄指向另一個存放文件信息的塊,這個叫做一次間接塊,還可以以同樣的方式做出二次、三次間接塊,這樣就解決了大文件存儲的問題。
知道了文件的索引塊,我們來看一下目錄的inode索引塊:
目錄同樣有inode索引塊,但是目錄里面指向的磁盤塊里面存放的是子目錄和文件對應的文件inode索引塊的編號。
我們來看一個例子,如果我們要查看/tmp/test.log文件流程是什么樣的呢:
首先我們找到/目錄的inode---找到/目錄磁盤塊---找到tmp目錄inode----找到tmp磁盤塊---找到test.log的inode---找到對應的數據塊
我們來看一下,如果要刪除/tmp/test.log,我們需要做些什么呢:
在目錄的磁盤塊中刪除文件指向記錄,刪除test.log的inode,刪除數據盤中的數據
下面,我們來看一下文件時如何管理空閑塊的:
我們在寫入數據的時候需要知道哪些塊時空閑可用的,怎么樣來管理這些空閑的塊呢,位圖法出來了,我們找一個塊,每一位都代表一個塊編號,1表示使用,0表示空閑。
接下來,我們來看一下ext2文件系統對磁盤的布局組成:
MBR:主要由引導代碼和磁盤分區表組成,分區表里面記錄的每個分區的起始位置和結束位置
塊組:每個分區又會被分成多個快組,快組的結構都是一樣的,由超級塊、快組描述、塊位圖、inode位圖、inode塊、數據塊組成
超級塊:超級塊里面存着快組的一些信息,如:磁盤的塊數、每個磁盤塊的大小、空閑的inode和磁盤塊個數等
磁盤塊位圖、inode位圖、inode塊、數據塊這些不用介紹我們也知道是干什么的了。
至此,整個文件系統初略的架構我們大致就梳理清楚了。