日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

23 | 基础篇:Linux 文件系统是怎么工作的?

發布時間:2024/9/3 linux 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 23 | 基础篇:Linux 文件系统是怎么工作的? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
通過前面 CPU 和內存模塊的學習,我相信,你已經掌握了 CPU 和內存的性能分析以及優化思路。從這一節開始,我 們將進入下一個重要模塊——文件系統和磁盤的 I/O 性能。同 CPU、內存一樣,磁盤和文件系統的管理,也是操作系統最核心的功能。磁盤為系統提供了最基本的持久化存儲。文件系統則在磁盤的基礎上,提供了一個用來管理文件的樹狀結構。那么,磁盤和文件系統是怎么工作的呢?又有哪些指標可以衡量它們的性能呢?今天,我就帶你先來看看,Linux 文件系統的工作原理。磁盤的工作原理,我們下一節再來學習。

索引節點和目錄項

文件系統,本身是對存儲設備上的文件,進行組織管理的機制。組織方式不同,就會形成不同的文件系統。你要記住最重要的一點,在 Linux 中一切皆文件。不僅普通的文件和目錄,就連塊設備、套接字、管道等,也都要通過統一的文件系統來管理。為了方便管理,Linux 文件系統為每個文件都分配兩個數據結構,索引節點(index node)和目錄項(directory entry)。它們主要用來記錄文件的元信息和目錄結構。
  • 索引節點,簡稱為 inode,用來記錄文件的元數據,比如 inode 編號、文件大小、訪問權限、修改日期、數據的位置等。索引節點和文件一一對應,它跟文件內容一樣,都會被持久化存儲到磁盤中。所以記住,索引節點同樣占用磁盤空間。
  • 目錄項,簡稱為 dentry,用來記錄文件的名字、索引節點指針以及與其他目錄項的關聯關系。多個關聯的目錄項,就構成了文件系統的目錄結構。不過,不同于索引節點,目錄項是由內核維護的一個內存數據結構,所以通常也被叫做目錄項緩存。
換句話說,索引節點是每個文件的唯一標志,而目錄項維護的正是文件系統的樹狀結構。目錄項和索引節點的關系是多對一,你可以簡單理解為,一個文件可以有多個別名。舉個例子,通過硬鏈接為文件創建的別名,就會對應不同的目錄項,不過這些目錄項本質上還是鏈接同一個文件,所以,它們的索引節點相同。索引節點和目錄項紀錄了文件的元數據,以及文件間的目錄關系,那么具體來說,文件數據到底是怎么存儲的呢?是不是直接寫到磁盤中就好了呢?實際上,磁盤讀寫的最小單位是扇區,然而扇區只有 512B 大小,如果每次都讀寫這么小的單位,效率一定很低。所以,文件系統又把連續的扇區組成了邏輯塊,然后每次都以邏輯塊為最小單元,來管理數據。常見的邏輯塊大小為 4KB,也就是由連續的 8 個扇區組成。為了幫助你理解目錄項、索引節點以及文件數據的關系,我畫了一張示意圖。你可以對照著這張圖,來回憶剛剛講過的內容,把知識和細節串聯起來。不過,這里有兩點需要你注意。第一,目錄項本身就是一個內存緩存,而索引節點則是存儲在磁盤中的數據。在前面的 Buffer 和 Cache 原理中,我曾經提到過,為了協調慢速磁盤與快速 CPU 的性能差異,文件內容會緩存到頁緩存 Cache 中。那么,你應該想到,這些索引節點自然也會緩存到內存中,加速文件的訪問。第二,磁盤在執行文件系統格式化時,會被分成三個存儲區域,超級塊、索引節點區和數據塊區。其中,
  • 超級塊,存儲整個文件系統的狀態。
  • 索引節點區,用來存儲索引節點。
  • 數據塊區,則用來存儲文件數據。

虛擬文件系統

目錄項、索引節點、邏輯塊以及超級塊,構成了 Linux 文件系統的四大基本要素。不過,為了支持各種不同的文件系統,Linux 內核在用戶進程和文件系統的中間,又引入了一個抽象層,也就是虛擬文件系統 VFS(Virtual File System)。VFS 定義了一組所有文件系統都支持的數據結構和標準接口。這樣,用戶進程和內核中的其他子系統,只需要跟 VFS 提供的統一接口進行交互就可以了,而不需要再關心底層各種文件系統的實現細節。這里,我畫了一張 Linux 文件系統的架構圖,幫你更好地理解系統調用、VFS、緩存、文件系統以及塊存儲之間的關系。

文件系統可以分為三類

通過這張圖,你可以看到,在 VFS 的下方,Linux 支持各種各樣的文件系統,如 Ext4、XFS、NFS 等等。按照存儲位置的不同,這些文件系統可以分為三類。
  • 第一類是基于磁盤的文件系統,也就是把數據直接存儲在計算機本地掛載的磁盤中。常見的 Ext4、XFS、OverlayFS 等,都是這類文件系統。
  • 第二類是基于內存的文件系統,也就是我們常說的虛擬文件系統。這類文件系統,不需要任何磁盤分配存儲空間,但會占用內存。我們經常用到的 /proc 文件系統,其實就是一種最常見的虛擬文件系統。此外,/sys 文件系統也屬于這一類,主要向用戶空間導出層次化的內核對象。
  • 第三類是網絡文件系統,也就是用來訪問其他計算機數據的文件系統,比如 NFS、SMB、iSCSI 等。
這些文件系統,要先掛載到 VFS 目錄樹中的某個子目錄(稱為掛載點),然后才能訪問其中的文件。拿第一類,也就是基于磁盤的文件系統為例,在安裝系統時,要先掛載一個根目錄(/),在根目錄下再把其他文件系統(比如其他的磁盤分區、/proc 文件系統、/sys 文件系統、NFS 等)掛載進來。

文件系統 I/O

把文件系統掛載到掛載點后,你就能通過掛載點,再去訪問它管理的文件了。VFS 提供了一組標準的文件訪問接口。這些接口以系統調用的方式,提供給應用程序使用。就拿 cat 命令來說,它首先調用 open() ,打開一個文件;然后調用 read() ,讀取文件的內容;最后再調用 write() ,把文件內容輸出到控制臺的標準輸出中: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);文件讀寫方式的各種差異,導致 I/O 的分類多種多樣。最常見的有,緩沖與非緩沖 I/O、直接與非直接 I/O、阻塞與非阻塞 I/O、同步與異步 I/O 等。 接下來,我們就詳細看這四種分類。

是否利用標準庫緩存

第一種,根據是否利用標準庫緩存,可以把文件 I/O 分為緩沖 I/O 與非緩沖 I/O。
  • 緩沖 I/O,是指利用標準庫緩存來加速文件的訪問,而標準庫內部再通過系統調度訪問文件。
  • 非緩沖 I/O,是指直接通過系統調用來訪問文件,不再經過標準庫緩存。
注意,這里所說的“緩沖”,是指標準庫內部實現的緩存。比方說,你可能見到過,很多程序遇到換行時才真正輸出,而換行前的內容,其實就是被標準庫暫時緩存了起來。無論緩沖 I/O 還是非緩沖 I/O,它們最終還是要經過系統調用來訪問文件。而根據上一節內容,我們知道,系統調用后,還會通過頁緩存,來減少磁盤的 I/O 操作。

是否利用操作系統的頁緩存

第二,根據是否利用操作系統的頁緩存,可以把文件 I/O 分為直接 I/O 與非直接 I/O。
  • 直接 I/O,是指跳過操作系統的頁緩存,直接跟文件系統交互來訪問文件。
  • 非直接 I/O 正好相反,文件讀寫時,先要經過系統的頁緩存,然后再由內核或額外的系統調用,真正寫入磁盤。
想要實現直接 I/O,需要你在系統調用中,指定 O_DIRECT 標志。如果沒有設置過,默認的是非直接 I/O。不過要注意,直接 I/O、非直接 I/O,本質上還是和文件系統交互。如果是在數據庫等場景中,你還會看到,跳過文件系統讀寫磁盤的情況,也就是我們通常所說的裸 I/O。

應用程序是否阻塞自身運行

第三,根據應用程序是否阻塞自身運行,可以把文件 I/O 分為阻塞 I/O 和非阻塞 I/O:
  • 所謂阻塞 I/O,是指應用程序執行 I/O 操作后,如果沒有獲得響應,就會阻塞當前線程,自然就不能執行其他任務。
  • 所謂非阻塞 I/O,是指應用程序執行 I/O 操作后,不會阻塞當前的線程,可以繼續執行其他的任務,隨后再通過輪詢或者事件通知的形式,獲取調用的結果。
比方說,訪問管道或者網絡套接字時,設置 O_NONBLOCK 標志,就表示用非阻塞方式訪問;而如果不做任何設置,默認的就是阻塞訪問。

是否等待響應結果

第四,根據是否等待響應結果,可以把文件 I/O 分為同步和異步 I/O:
  • 所謂同步 I/O,是指應用程序執行 I/O 操作后,要一直等到整個 I/O 完成后,才能獲得 I/O 響應。
  • 所謂異步 I/O,是指應用程序執行 I/O 操作后,不用等待完成和完成后的響應,而是繼續執行就可以。等到這次 I/O 完成后,響應會用事件通知的方式,告訴應用程序。
舉個例子,在操作文件時,如果你設置了 O_SYNC 或者 O_DSYNC 標志,就代表同步 I/O。如果設置了 O_DSYNC,就要等文件數據寫入磁盤后,才能返回;而 O_SYNC,則是在 O_DSYNC 基礎上,要求文件元數據也要寫入磁盤后,才能返回。再比如,在訪問管道或者網絡套接字時,設置了 O_ASYNC 選項后,相應的 I/O 就是異步 I/O。這樣,內核會再通過 SIGIO 或者 SIGPOLL,來通知進程文件是否可讀寫。你可能發現了,這里的好多概念也經常出現在網絡編程中。比如非阻塞 I/O,通常會跟 select/poll 配合,用在網絡套接字的 I/O 中。你也應該可以理解,“Linux 一切皆文件”的深刻含義。無論是普通文件和塊設備、還是網絡套接字和管道等,它們都通過統一的 VFS 接口來訪問。

性能觀測

學了這么多文件系統的原理,你估計也是迫不及待想上手,觀察一下文件系統的性能情況了。接下來,打開一個終端,SSH 登錄到服務器上,然后跟我一起來探索,如何觀測文件系統的性能。

容量

對文件系統來說,最常見的一個問題就是空間不足。當然,你可能本身就知道,用 df 命令,就能查看文件系統的磁盤空間使用情況。比如:$ df /dev/sda1 Filesystem 1K-blocks Used Available Use% Mounted on /dev/sda1 30308240 3167020 27124836 11% /你可以看到,我的根文件系統只使用了 11% 的空間。這里還要注意,總空間用 1K-blocks 的數量來表示,你可以給 df 加上 -h 選項,以獲得更好的可讀性:$ df -h /dev/sda1 Filesystem Size Used Avail Use% Mounted on /dev/sda1 29G 3.1G 26G 11% /不過有時候,明明你碰到了空間不足的問題,可是用 df 查看磁盤空間后,卻發現剩余空間還有很多。這是怎么回事呢?不知道你還記不記得,剛才我強調的一個細節。除了文件數據,索引節點也占用磁盤空間。你可以給 df 命令加上 -i 參數,查看索引節點的使用情況,如下所示:$ df -i /dev/sda1 Filesystem Inodes IUsed IFree IUse% Mounted on /dev/sda1 3870720 157460 3713260 5% /索引節點的容量,(也就是 Inode 個數)是在格式化磁盤時設定好的,一般由格式化工具自動生成。當你發現索引節點空間不足,但磁盤空間充足時,很可能就是過多小文件導致的。所以,一般來說,刪除這些小文件,或者把它們移動到索引節點充足的其他磁盤中,就可以解決這個問題。

緩存

在前面 Cache 案例中,我已經介紹過,可以用 free 或 vmstat,來觀察頁緩存的大小。復習一下,free 輸出的 Cache,是頁緩存和可回收 Slab 緩存的和,你可以從 /proc/meminfo ,直接得到它們的大小:$ cat /proc/meminfo | grep -E "SReclaimable|Cached" Cached: 748316 kB SwapCached: 0 kB SReclaimable: 179508 kB話說回來,文件系統中的目錄項和索引節點緩存,又該如何觀察呢?實際上,內核使用 Slab 機制,管理目錄項和索引節點的緩存。/proc/meminfo 只給出了 Slab 的整體大小,具體到每一種 Slab 緩存,還要查看 /proc/slabinfo 這個文件。比如,運行下面的命令,你就可以得到,所有目錄項和各種文件系統索引節點的緩存情況:$ cat /proc/slabinfo | grep -E '^#|dentry|inode' # name <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail> xfs_inode 0 0 960 17 4 : tunables 0 0 0 : slabdata 0 0 0 ... ext4_inode_cache 32104 34590 1088 15 4 : tunables 0 0 0 : slabdata 2306 2306 0hugetlbfs_inode_cache 13 13 624 13 2 : tunables 0 0 0 : slabdata 1 1 0 sock_inode_cache 1190 1242 704 23 4 : tunables 0 0 0 : slabdata 54 54 0 shmem_inode_cache 1622 2139 712 23 4 : tunables 0 0 0 : slabdata 93 93 0 proc_inode_cache 3560 4080 680 12 2 : tunables 0 0 0 : slabdata 340 340 0 inode_cache 25172 25818 608 13 2 : tunables 0 0 0 : slabdata 1986 1986 0 dentry 76050 121296 192 21 1 : tunables 0 0 0 : slabdata 5776 5776 0這個界面中,dentry 行表示目錄項緩存,inode_cache 行,表示 VFS 索引節點緩存,其余的則是各種文件系統的索引節點緩存。

slabtop?

/proc/slabinfo 的列比較多,具體含義你可以查詢 man slabinfo。在實際性能分析中,我們更常使用 slabtop ,來找到占用內存最多的緩存類型。比如,下面就是我運行 slabtop 得到的結果:# 按下 c 按照緩存大小排序,按下 a 按照活躍對象數排序 $ 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_cache 58260 55397 0% 0.13K 1942 30 7768K kernfs_node_cache 485 413 0% 5.69K 97 5 3104K task_struct 1472 1397 0% 2.00K 92 16 2944K kmalloc-2048從這個結果你可以看到,在我的系統中,目錄項和索引節點占用了最多的 Slab 緩存。不過它們占用的內存其實并不大,加起來也只有 23MB 左右。

小結

今天,我帶你梳理了 Linux 文件系統的工作原理。文件系統,是對存儲設備上的文件,進行組織管理的一種機制。為了支持各類不同的文件系統,Linux 在各種文件系統實現上,抽象了一層虛擬文件系統(VFS)。VFS 定義了一組所有文件系統都支持的數據結構和標準接口。這樣,用戶進程和內核中的其他子系統,就只需要跟 VFS 提供的統一接口進行交互。為了降低慢速磁盤對性能的影響,文件系統又通過頁緩存、目錄項緩存以及索引節點緩存,緩和磁盤延遲對應用程序的影響。在性能觀測方面,今天主要講了容量和緩存的指標。下一節,我們將會學習 Linux 磁盤 I/O 的工作原理,并掌握磁盤 I/O 的性能觀測方法。

思考

最后,給你留一個思考題。在實際工作中,我們經常會根據文件名字,查找它所在路徑,比如:$ find / -name file-name今天的問題就是,這個命令,會不會導致系統的緩存升高呢?如果有影響,又會導致哪種類型的緩存升高呢?你可以結合今天內容,自己先去操作和分析,看看觀察到的結果跟你分析的是否一樣。課后題:這個命令,會不會導致系統的緩存升高呢?--> 會的如果有影響,又會導致哪種類型的緩存升高呢?--> /xfs_inode/ proc_inode_cache/dentry/inode_cache實驗步驟:1. 清空緩存:echo 3 > /proc/sys/vm/drop_caches ; sync2. 執行find : find / -name test3. 發現更新top 4 項是:OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME37400 37400 100% 0.94K 2200 17 35200K xfs_inode36588 36113 98% 0.64K 3049 12 24392K proc_inode_cache104979 104979 100% 0.19K 4999 21 19996K dentry18057 18057 100% 0.58K 1389 13 11112K inode_cachefind / -name 這個命令是全盤掃描(既包括內存文件系統又包含本地的xfs【我的環境沒有mount 網絡文件系統】),所以 inode cache & dentry & proc inode cache 會升高。另外,執行過了一次后再次執行find 就機會沒有變化了,執行速度也快了很多,也就是下次的find大部分是依賴cache的結果。

總結

以上是生活随笔為你收集整理的23 | 基础篇:Linux 文件系统是怎么工作的?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。