亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網(wǎng)為廣大站長提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.430618.com 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

磁盤為系統(tǒng)提供了最基本的持久化存儲。

文件系統(tǒng)則在磁盤的基礎(chǔ)上,提供了一個用來管理文件的樹狀結(jié)構(gòu)。

那么,磁盤和文件系統(tǒng)是怎么工作的呢?又有哪些指標(biāo)可以衡量它們的性能呢?

索引節(jié)點(diǎn)和目錄項(xiàng)

文件系統(tǒng),本身是對存儲設(shè)備上的文件,進(jìn)行組織管理的機(jī)制。組織方式不同,就會形成不同的文件系統(tǒng)。

你要記住最重要的一點(diǎn),在 linux 中一切皆文件。不僅普通的文件和目錄,就連塊設(shè)備、套接字、管道等,也都要通過統(tǒng)一的文件系統(tǒng)來管理。

為了方便管理,Linux 文件系統(tǒng)為每個文件都分配兩個數(shù)據(jù)結(jié)構(gòu),索引節(jié)點(diǎn)(indexnode)和目錄項(xiàng)(directory entry)。它們主要用來記錄文件的元信息和目錄結(jié)構(gòu)。

索引節(jié)點(diǎn),簡稱為 inode,用來記錄文件的元數(shù)據(jù),比如 inode 編號、文件大小、訪問權(quán)限、修改日期、數(shù)據(jù)的位置等。索引節(jié)點(diǎn)和文件一一對應(yīng),它跟文件內(nèi)容一樣,都會被持久化存儲到磁盤中。所以記住,索引節(jié)點(diǎn)同樣占用磁盤空間。

目錄項(xiàng),簡稱為 dentry,用來記錄文件的名字、索引節(jié)點(diǎn)指針以及與其他目錄項(xiàng)的關(guān)聯(lián)關(guān)系。多個關(guān)聯(lián)的目錄項(xiàng),就構(gòu)成了文件系統(tǒng)的目錄結(jié)構(gòu)。不過,不同于索引節(jié)點(diǎn),目錄項(xiàng)是由內(nèi)核維護(hù)的一個內(nèi)存數(shù)據(jù)結(jié)構(gòu),所以通常也被叫做目錄項(xiàng)緩存。

換句話說,索引節(jié)點(diǎn)是每個文件的唯一標(biāo)志,而目錄項(xiàng)維護(hù)的正是文件系統(tǒng)的樹狀結(jié)構(gòu)。目錄項(xiàng)和索引節(jié)點(diǎn)的關(guān)系是多對一,你可以簡單理解為,一個文件可以有多個別名。

舉個例子,通過硬鏈接為文件創(chuàng)建的別名,就會對應(yīng)不同的目錄項(xiàng),不過這些目錄項(xiàng)本質(zhì)上還是鏈接同一個文件,所以,它們的索引節(jié)點(diǎn)相同。

索引節(jié)點(diǎn)和目錄項(xiàng)紀(jì)錄了文件的元數(shù)據(jù),以及文件間的目錄關(guān)系,那么具體來說,文件數(shù)據(jù)到底是怎么存儲的呢?是不是直接寫到磁盤中就好了呢?

實(shí)際上,磁盤讀寫的最小單位是扇區(qū),然而扇區(qū)只有 512B 大小,如果每次都讀寫這么小的單位,效率一定很低。所以,文件系統(tǒng)又把連續(xù)的扇區(qū)組成了邏輯塊,然后每次都以邏輯塊為最小單元,來管理數(shù)據(jù)。常見的邏輯塊大小為 4KB,也就是由連續(xù)的 8 個扇區(qū)組成。

為了幫助你理解目錄項(xiàng)、索引節(jié)點(diǎn)以及文件數(shù)據(jù)的關(guān)系,我畫了一張示意圖。你可以對照著這張圖,來回憶剛剛講過的內(nèi)容,把知識和細(xì)節(jié)串聯(lián)起來。

Linux文件系統(tǒng)是怎么工作的?

 

不過,這里有兩點(diǎn)需要你注意。

第一,目錄項(xiàng)本身就是一個內(nèi)存緩存,而索引節(jié)點(diǎn)則是存儲在磁盤中的數(shù)據(jù)。在前面的Buffer 和 Cache 原理中,我曾經(jīng)提到過,為了協(xié)調(diào)慢速磁盤與快速 CPU 的性能差異,文件內(nèi)容會緩存到頁緩存 Cache 中。

那么,你應(yīng)該想到,這些索引節(jié)點(diǎn)自然也會緩存到內(nèi)存中,加速文件的訪問。

第二,磁盤在執(zhí)行文件系統(tǒng)格式化時,會被分成三個存儲區(qū)域,超級塊、索引節(jié)點(diǎn)區(qū)和數(shù)據(jù)塊區(qū)。其中,

  • 超級塊,存儲整個文件系統(tǒng)的狀態(tài)。
  • 索引節(jié)點(diǎn)區(qū),用來存儲索引節(jié)點(diǎn)。
  • 數(shù)據(jù)塊區(qū),則用來存儲文件數(shù)據(jù)。

虛擬文件系統(tǒng)

目錄項(xiàng)、索引節(jié)點(diǎn)、邏輯塊以及超級塊,構(gòu)成了 Linux 文件系統(tǒng)的四大基本要素。不過,為了支持各種不同的文件系統(tǒng),Linux 內(nèi)核在用戶進(jìn)程和文件系統(tǒng)的中間,又引入了一個抽象層,也就是虛擬文件系統(tǒng) VFS(Virtual File System)。

VFS 定義了一組所有文件系統(tǒng)都支持的數(shù)據(jù)結(jié)構(gòu)和標(biāo)準(zhǔn)接口。這樣,用戶進(jìn)程和內(nèi)核中的其他子系統(tǒng),只需要跟 VFS 提供的統(tǒng)一接口進(jìn)行交互就可以了,而不需要再關(guān)心底層各種文件系統(tǒng)的實(shí)現(xiàn)細(xì)節(jié)。

這里,我畫了一張 Linux 文件系統(tǒng)的架構(gòu)圖,幫你更好地理解系統(tǒng)調(diào)用、VFS、緩存、文件系統(tǒng)以及塊存儲之間的關(guān)系。

Linux文件系統(tǒng)是怎么工作的?

 

通過這張圖,你可以看到,在 VFS 的下方,Linux 支持各種各樣的文件系統(tǒng),如 Ext4、XFS、NFS 等等。按照存儲位置的不同,這些文件系統(tǒng)可以分為三類。

  • 第一類是基于磁盤的文件系統(tǒng),也就是把數(shù)據(jù)直接存儲在計(jì)算機(jī)本地掛載的磁盤中。常見的 Ext4、XFS、OverlayFS 等,都是這類文件系統(tǒng)。
  • 第二類是基于內(nèi)存的文件系統(tǒng),也就是我們常說的虛擬文件系統(tǒng)。這類文件系統(tǒng),不需要任何磁盤分配存儲空間,但會占用內(nèi)存。我們經(jīng)常用到的 /proc 文件系統(tǒng),其實(shí)就是一種最常見的虛擬文件系統(tǒng)。此外,/sys 文件系統(tǒng)也屬于這一類,主要向用戶空間導(dǎo)出層次化的內(nèi)核對象。
  • 第三類是網(wǎng)絡(luò)文件系統(tǒng),也就是用來訪問其他計(jì)算機(jī)數(shù)據(jù)的文件系統(tǒng),比如 NFS、SMB、iSCSI 等。

這些文件系統(tǒng),要先掛載到 VFS 目錄樹中的某個子目錄(稱為掛載點(diǎn)),然后才能訪問其中的文件。拿第一類,也就是基于磁盤的文件系統(tǒng)為例,在安裝系統(tǒng)時,要先掛載一個根目錄(/),在根目錄下再把其他文件系統(tǒng)(比如其他的磁盤分區(qū)、/proc 文件系統(tǒng)、/sys 文件系統(tǒng)、NFS 等)掛載進(jìn)來。

文件系統(tǒng)I/O

把文件系統(tǒng)掛載到掛載點(diǎn)后,你就能通過掛載點(diǎn),再去訪問它管理的文件了。VFS 提供了一組標(biāo)準(zhǔn)的文件訪問接口。這些接口以系統(tǒng)調(diào)用的方式,提供給應(yīng)用程序使用。

就拿 cat 命令來說,它首先調(diào)用 open() ,打開一個文件;然后調(diào)用 read() ,讀取文件的內(nèi)容;最后再調(diào)用 write(),把文件內(nèi)容輸出到控制臺的標(biāo)準(zhǔn)輸出中:

int open(const char *pathname, int flags, mode_t mode);
ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);

文件讀寫方式的各種差異,導(dǎo)致 I/O 的分類多種多樣。最常見的有,緩沖與非緩沖 I/O、直接與非直接 I/O、阻塞與非阻塞 I/O、同步與異步 I/O 等。 接下來,我們就詳細(xì)看這四種分類。

第一種,根據(jù)是否利用標(biāo)準(zhǔn)庫緩存,可以把文件 I/O 分為緩沖 I/O 與非緩沖 I/O。

緩沖 I/O,是指利用標(biāo)準(zhǔn)庫緩存來加速文件的訪問,而標(biāo)準(zhǔn)庫內(nèi)部再通過系統(tǒng)調(diào)度訪問文件。非緩沖 I/O,是指直接通過系統(tǒng)調(diào)用來訪問文件,不再經(jīng)過標(biāo)準(zhǔn)庫緩存。

注意,這里所說的“緩沖”,是指標(biāo)準(zhǔn)庫內(nèi)部實(shí)現(xiàn)的緩存。比方說,你可能見到過,很多程序遇到換行時才真正輸出,而換行前的內(nèi)容,其實(shí)就是被標(biāo)準(zhǔn)庫暫時緩存了起來。

無論緩沖 I/O 還是非緩沖 I/O,它們最終還是要經(jīng)過系統(tǒng)調(diào)用來訪問文件。

第二,根據(jù)是否利用操作系統(tǒng)的頁緩存,可以把文件 I/O 分為直接 I/O 與非直接 I/O。

直接 I/O,是指跳過操作系統(tǒng)的頁緩存,直接跟文件系統(tǒng)交互來訪問文件。非直接 I/O 正好相反,文件讀寫時,先要經(jīng)過系統(tǒng)的頁緩存,然后再由內(nèi)核或額外的系統(tǒng)調(diào)用,真正寫入磁盤。

想要實(shí)現(xiàn)直接 I/O,需要你在系統(tǒng)調(diào)用中,指定 O_DIRECT 標(biāo)志。如果沒有設(shè)置過,默認(rèn)的是非直接 I/O。

不過要注意,直接 I/O、非直接 I/O,本質(zhì)上還是和文件系統(tǒng)交互。如果是在數(shù)據(jù)庫等場景中,你還會看到,跳過文件系統(tǒng)讀寫磁盤的情況,也就是我們通常所說的裸 I/O。

第三,根據(jù)應(yīng)用程序是否阻塞自身運(yùn)行,可以把文件 I/O 分為阻塞 I/O 和非阻塞 I/O:

所謂阻塞 I/O,是指應(yīng)用程序執(zhí)行 I/O 操作后,如果沒有獲得響應(yīng),就會阻塞當(dāng)前線程,自然就不能執(zhí)行其他任務(wù)。所謂非阻塞 I/O,是指應(yīng)用程序執(zhí)行 I/O 操作后,不會阻塞當(dāng)前的線程,可以繼續(xù)執(zhí)行其他的任務(wù),隨后再通過輪詢或者事件通知的形式,獲取調(diào)用的結(jié)果。

比方說,訪問管道或者網(wǎng)絡(luò)套接字時,設(shè)置 O_NONBLOCK 標(biāo)志,就表示用非阻塞方式訪問;而如果不做任何設(shè)置,默認(rèn)的就是阻塞訪問。

第四,根據(jù)是否等待響應(yīng)結(jié)果,可以把文件 I/O 分為同步和異步 I/O:

所謂同步 I/O,是指應(yīng)用程序執(zhí)行 I/O 操作后,要一直等到整個 I/O 完成后,才能獲得I/O 響應(yīng)。所謂異步 I/O,是指應(yīng)用程序執(zhí)行 I/O 操作后,不用等待完成和完成后的響應(yīng),而是繼續(xù)執(zhí)行就可以。等到這次 I/O 完成后,響應(yīng)會用事件通知的方式,告訴應(yīng)用程序。

舉個例子,在操作文件時,如果你設(shè)置了 O_SYNC 或者 O_DSYNC 標(biāo)志,就代表同步I/O。如果設(shè)置了 O_DSYNC,就要等文件數(shù)據(jù)寫入磁盤后,才能返回;而 O_SYNC,則是在 O_DSYNC 基礎(chǔ)上,要求文件元數(shù)據(jù)也要寫入磁盤后,才能返回。

再比如,在訪問管道或者網(wǎng)絡(luò)套接字時,設(shè)置了 O_ASYNC 選項(xiàng)后,相應(yīng)的 I/O 就是異步I/O。這樣,內(nèi)核會再通過 SIGIO 或者 SIGPOLL,來通知進(jìn)程文件是否可讀寫。

你可能發(fā)現(xiàn)了,這里的好多概念也經(jīng)常出現(xiàn)在網(wǎng)絡(luò)編程中。比如非阻塞 I/O,通常會跟select/poll 配合,用在網(wǎng)絡(luò)套接字的 I/O 中。

你也應(yīng)該可以理解,“Linux 一切皆文件”的深刻含義。無論是普通文件和塊設(shè)備、還是網(wǎng)絡(luò)套接字和管道等,它們都通過統(tǒng)一的 VFS 接口來訪問。

性能觀測

學(xué)了這么多文件系統(tǒng)的原理,你估計(jì)也是迫不及待想上手,觀察一下文件系統(tǒng)的性能情況了。

接下來,打開一個終端,SSH 登錄到服務(wù)器上,然后跟我一起來探索,如何觀測文件系統(tǒng)的性能。

容量

對文件系統(tǒng)來說,最常見的一個問題就是空間不足。當(dāng)然,你可能本身就知道,用 df 命令,就能查看文件系統(tǒng)的磁盤空間使用情況。比如:

$ df /dev/sda1
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/sda1       30308240 3167020  27124836  11% /

你可以看到,我的根文件系統(tǒng)只使用了 11% 的空間。這里還要注意,總空間用 1K-blocks的數(shù)量來表示,你可以給 df 加上 -h 選項(xiàng),以獲得更好的可讀性:

$ df -h /dev/sda1
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        29G  3.1G   26G  11% /

不過有時候,明明你碰到了空間不足的問題,可是用 df 查看磁盤空間后,卻發(fā)現(xiàn)剩余空間還有很多。這是怎么回事呢?

不知道你還記不記得,剛才我強(qiáng)調(diào)的一個細(xì)節(jié)。除了文件數(shù)據(jù),索引節(jié)點(diǎn)也占用磁盤空間。你可以給 df 命令加上 -i 參數(shù),查看索引節(jié)點(diǎn)的使用情況,如下所示:

$ df -i /dev/sda1
Filesystem      Inodes  IUsed   IFree IUse% Mounted on
/dev/sda1      3870720 157460 3713260    5% /

索引節(jié)點(diǎn)的容量,(也就是 Inode 個數(shù))是在格式化磁盤時設(shè)定好的,一般由格式化工具自動生成。當(dāng)你發(fā)現(xiàn)索引節(jié)點(diǎn)空間不足,但磁盤空間充足時,很可能就是過多小文件導(dǎo)致的。

所以,一般來說,刪除這些小文件,或者把它們移動到索引節(jié)點(diǎn)充足的其他磁盤中,就可以解決這個問題。

緩存

在前面 Cache 案例中,我已經(jīng)介紹過,可以用 free 或 vmstat,來觀察頁緩存的大小。復(fù)習(xí)一下,free 輸出的 Cache,是頁緩存和可回收 Slab 緩存的和,你可以從/proc/meminfo ,直接得到它們的大小:

$ cat /proc/meminfo | grep -E "SReclaimable|Cached"
Cached:           748316 kB
SwapCached:            0 kB
SReclaimable:     179508 kB

話說回來,文件系統(tǒng)中的目錄項(xiàng)和索引節(jié)點(diǎn)緩存,又該如何觀察呢?

實(shí)際上,內(nèi)核使用 Slab 機(jī)制,管理目錄項(xiàng)和索引節(jié)點(diǎn)的緩存。/proc/meminfo 只給出了Slab 的整體大小,具體到每一種 Slab 緩存,還要查看 /proc/slabinfo 這個文件。

比如,運(yùn)行下面的命令,你就可以得到,所有目錄項(xiàng)和各種文件系統(tǒng)索引節(jié)點(diǎn)的緩存情況:

$ cat /proc/slabinfo | grep -E '^#|dentry|inode'
# name            <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunabxfs_inode              0      0    960   17    4 : tunables    0    0    0 : slabdata
...
ext4_inode_cache   32104  34590   1088   15    4 : tunables    0    0    0 : slabdatasock_inode_cache    1190   1242    704   23    4 : tunables    0    0    0 : slabdatashmem_inode_cache   1622   2139    712   23    4 : tunables    0    0    0 : slabdataproc_inode_cache    3560   4080    680   12    2 : tunables    0    0    0 : slabdatainode_cache        25172  25818    608   13    2 : tunables    0    0    0 : slabdatadentry             76050 121296    192   21    1 : tunables    0    0    0 : slabdata

這個界面中,dentry 行表示目錄項(xiàng)緩存,inode_cache 行,表示 VFS 索引節(jié)點(diǎn)緩存,其余的則是各種文件系統(tǒng)的索引節(jié)點(diǎn)緩存。

/proc/slabinfo 的列比較多,具體含義你可以查詢man slabinfo。在實(shí)際性能分析中,我們更常使用 slabtop,來找到占用內(nèi)存最多的緩存類型。

比如,下面就是我運(yùn)行 slabtop 得到的結(jié)果:

#按下c按照緩存大小排序,按下a按照活躍對象數(shù)排序
$ slabtop
Active / Total Objects (% used)    : 277970 / 358914 (77.4%)
Active / Total Slabs (% used)      : 12414 / 12414 (100.0%)
Active / Total Caches (% used)     : 83 / 135 (61.5%)
Active / Total Size (% used)       : 57816.88K / 73307.70K (78.9%)
                                                            Minimum / Average / Maximum Object : 0.01K / 0.20K / 22.88K
OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME
69804  23094   0%    0.19K   3324       21     13296K dentry
16380  15854   0%    0.59K   1260       13     10080K inode_cache58260  55397   0%    0.13K   1942       30      7768K kernfs_node_cache
485    413   0%    5.69K     97        5      3104K task_struct1472   1397   0%    2.00K     92       16      2944K kmalloc-2048

從這個結(jié)果你可以看到,在我的系統(tǒng)中,目錄項(xiàng)和索引節(jié)點(diǎn)占用了最多的 Slab 緩存。不過它們占用的內(nèi)存其實(shí)并不大,加起來也只有 23MB 左右。

總結(jié)

本文,我?guī)闶崂砹?Linux 文件系統(tǒng)的工作原理。

文件系統(tǒng),是對存儲設(shè)備上的文件,進(jìn)行組織管理的一種機(jī)制。為了支持各類不同的文件系統(tǒng),Linux 在各種文件系統(tǒng)實(shí)現(xiàn)上,抽象了一層虛擬文件系統(tǒng)(VFS)。

VFS 定義了一組所有文件系統(tǒng)都支持的數(shù)據(jù)結(jié)構(gòu)和標(biāo)準(zhǔn)接口。這樣,用戶進(jìn)程和內(nèi)核中的其他子系統(tǒng),就只需要跟 VFS 提供的統(tǒng)一接口進(jìn)行交互。

為了降低慢速磁盤對性能的影響,文件系統(tǒng)又通過頁緩存、目錄項(xiàng)緩存以及索引節(jié)點(diǎn)緩存,緩和磁盤延遲對應(yīng)用程序的影響。

在性能觀測方面,本文主要講了容量和緩存的指標(biāo)。下一節(jié),我們將會學(xué)習(xí) Linux 磁盤 I/O的工作原理,并掌握磁盤 I/O 的性能觀測方法。

分享到:
標(biāo)簽:文件系統(tǒng) Linux
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運(yùn)動步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定