成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

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

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

 和 CPU、內存一樣,磁盤和文件系統(tǒng)的管理,也是操作系統(tǒng)最核心的功能。

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

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

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

索引節(jié)點和目錄項

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

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

為了方便管理,Linux 文件系統(tǒng)為每個文件都分配兩個數據結構,索引節(jié)點(index node)和目錄項(directory entry)。它們主要用來記錄文件的元信息和目錄結構。

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

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

換句話說,索引節(jié)點是每個文件的唯一標志,而目錄項維護的正是文件系統(tǒng)的樹狀結構。目錄項和索引節(jié)點的關系是多對一,你可以簡單理解為,一個文件可以有多個別名。

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

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

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

為了幫助我們理解目錄項、索引節(jié)點以及文件數據的關系,畫了一張示意圖。我們可以對照著這張圖,來回憶剛剛講過的內容,把知識和細節(jié)串聯(lián)起來。

不過,這里有兩點需要我們注意:

第一,目錄項本身就是一個內存緩存,而索引節(jié)點則是存儲在磁盤中的數據。在前面的 Buffer 和 Cache 原理中,我曾經提到過,為了協(xié)調慢速磁盤與快速 CPU 的性能差異,文 件內容會緩存到頁緩存 Cache 中。那么,我們也應該想到,這些索引節(jié)點自然也會緩存到內存中,加速文件的訪問。

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

據塊區(qū)。其中,

超級塊,存儲整個文件系統(tǒng)的狀態(tài)。

索引節(jié)點區(qū),用來存儲索引節(jié)點。

數據塊區(qū),則用來存儲文件數據。

虛擬文件系統(tǒng)

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

VFS 定義了一組所有文件系統(tǒng)都支持的數據結構和標準接口。這樣,用戶進程和內核中的其他子系統(tǒng),只需要跟 VFS 提供的統(tǒng)一接口進行交互就可以了,而不需要再關心底層各種文件系統(tǒng)的實現細節(jié)。

這里,下圖是 Linux 文件系統(tǒng)的架構圖,幫我們更好地理解系統(tǒng)調用、VFS、緩存、文 件系統(tǒng)以及塊存儲之間的關系。

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

第一類是基于磁盤的文件系統(tǒng),也就是把數據直接存儲在計算機本地掛載的磁盤中。常見的 Ext4、XFS、OverlayFS 等,都是這類文件系統(tǒng)。

第二類是基于內存的文件系統(tǒng),也就是我們常說的虛擬文件系統(tǒng)。這類文件系統(tǒng),不需要任何磁盤分配存儲空間,但會占用內存。我們經常用到的 /proc 文件系統(tǒng),其實就是 一種最常見的虛擬文件系統(tǒng)。此外,/sys 文件系統(tǒng)也屬于這一類,主要向用戶空間導出層次化的內核對象。

第三類是網絡文件系統(tǒng),也就是用來訪問其他計算機數據的文件系統(tǒng),比如 NFS、 SMB、iSCSI 等。

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

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

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

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

  1. int open(const char *pathname, int flags, mode_t mode);   
  2. ssize_t read(int fd, void *buf, size_t count);  
  3. 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,是指利用標準庫緩存來加速文件的訪問,而標準庫內部再通過系統(tǒng)調度訪問文件。

非緩沖 I/O,是指直接通過系統(tǒng)調用來訪問文件,不再經過標準庫緩存。

注意,這里所說的“緩沖”,是指標準庫內部實現的緩存。比方說,你可能見到過,很多程序遇到換行時才真正輸出,而換行前的內容,其實就是被標準庫暫時緩存了起來。

無論緩沖 I/O 還是非緩沖 I/O,它們最終還是要經過系統(tǒng)調用來訪問文件。我們知道,系統(tǒng)調用后,還會通過頁緩存,來減少磁盤的 I/O 操作。

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

直接 I/O,是指跳過操作系統(tǒng)的頁緩存,直接跟文件系統(tǒng)交互來訪問文件。

非直接 I/O 正好相反,文件讀寫時,先要經過系統(tǒng)的頁緩存,然后再由內核或額外的系統(tǒng)調用,真正寫入磁盤。

想要實現直接 I/O,需要你在系統(tǒng)調用中,指定 O_DIRECT 標志。如果沒有設置過,默認 的是非直接 I/O。

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

第三,根據應用程序是否阻塞自身運行,可以把文件 I/O 分為阻塞 I/O 和非阻塞 I/O

所謂阻塞 I/O,是指應用程序執(zhí)行 I/O 操作后,如果沒有獲得響應,就會阻塞當前線程,自然就不能執(zhí)行其他任務。

所謂非阻塞 I/O,是指應用程序執(zhí)行 I/O 操作后,不會阻塞當前的線程,可以繼續(xù)執(zhí)行其他的任務,隨后再通過輪詢或者事件通知的形式,獲取調用的結果。

比方說,訪問管道或者網絡套接字時,設置 O_NONBLOCK 標志,就表示用非阻塞方式訪問;而如果不做任何設置,默認的就是阻塞訪問。

第四,根據是否等待響應結果,可以把文件 I/O 分為同步和異步 I/O

所謂同步 I/O,是指應用程序執(zhí)行 I/O 操作后,要一直等到整個 I/O 完成后,才能獲得 I/O 響應。

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

例如,在操作文件時,如果設置了 O_SYNC 或者 O_DSYNC 標志,就代表同步 I/O。如果設置了 O_DSYNC,就要等文件數據寫入磁盤后,才能返回;而 O_SYNC,則是在 O_DSYNC 基礎上,要求文件元數據也要寫入磁盤后,才能返回。

再比如,在訪問管道或者網絡套接字時,設置了 O_ASYNC 選項后,相應的 I/O 就是異步I/O。這樣,內核會再通過 SIGIO 或者 SIGPOLL,來通知進程文件是否可讀寫。

我們可能發(fā)現了,這里的好多概念也經常出現在網絡編程中。比如非阻塞 I/O,通常會跟 select/poll 配合,用在網絡套接字的 I/O 中。

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

性能觀測

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

容量

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

  1. df /dev/vda1  
  2. 文件系統(tǒng)           1K-塊         已用         可用        已用%    掛載點  
  3. /dev/vda1      104846316     28228044     76618272      27%     / 

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

  1. df -h /dev/vda1  
  2.  文件系統(tǒng)         容量     已用     可用   已用%   掛載點  
  3. /dev/vda1       100G     27G      74G   27%     / 

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

其實除了文件數據,索引節(jié)點也占用磁盤空間。可以給 df 命令加上 -i 參數,查看索引節(jié)點的使用情況,如下所示: 

  1. df -h -i /dev/vda1  
  2. 文件系統(tǒng)         Inode    已用(I)   可用(I)   已用(I)%  掛載點  
  3. /dev/vda1        50M     162K     50M        1%       / 

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

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

緩存

可以用 free 或 vmstat,來觀察頁緩存的大小。free 輸出的 Cache,是頁緩存和可回收 Slab 緩存的和,你可以從 /proc/meminfo ,直接得到它們的大小: 

  1. cat /proc/meminfo | grep -E "SReclaimable|Cached"  
  2. Cached:          2014100 kB  
  3. SwapCached:         5316 kB  
  4. SReclaimable:     216128 kB 

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

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

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

  1. # name <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunab  
  2. cat /proc/slabinfo | grep -E '^#|dentry|inode'  
  3. # name            <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail> 
  4. ovl_inode             66     66    736   22    4 : tunables    0    0    0 : slabdata      3      3      0 
  5. fuse_inode             0      0    832   19    4 : tunables    0    0    0 : slabdata      0      0      0 
  6. xfs_inode         100470 110736   1024   16    4 : tunables    0    0    0 : slabdata   6921   6921      0 
  7. mqueue_inode_cache     64     64   1024   16    4 : tunables    0    0    0 : slabdata      4      4      0 
  8. hugetlbfs_inode_cache     48     48    680   24    4 : tunables    0    0    0 : slabdata      2      2      0  
  9. sock_inode_cache    4581   4807    704   23    4 : tunables    0    0    0 : slabdata    209    209      0  
  10. shmem_inode_cache   1816   2541    760   21    4 : tunables    0    0    0 : slabdata    121    121      0  
  11. proc_inode_cache   10210  13024    728   22    4 : tunables    0    0    0 : slabdata    592    592      0  
  12. inode_cache        36498  38832    656   24    4 : tunables    0    0    0 : slabdata   1618   1618      0  
  13. dentry            150086 183204    192   21    1 : tunables    0    0    0 : slabdata   8724   8724      0 

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

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

比如,下面就是運行 slabtop 得到的結果: 

  1. # 按下 c 按照緩存大小排序,按下 a 按照活躍對象數排序   
  2. slabtop  
  3. Active / Total Objects (% used)    : 991123 / 1087653 (91.1%)  
  4.  Active / Total Slabs (% used)      : 40627 / 40627 (100.0%)  
  5.  Active / Total Caches (% used)     : 103 / 138 (74.6%)  
  6.  Active / Total Size (% used)       : 329426.37K / 371563.66K (88.7%)  
  7.  Minimum / Average / Maximum Object : 0.01K / 0.34K / 8.00K  
  8.  OBJS  ACTIVE   USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE    NAME                   
  9.  183204 150026   81%    0.19K   8724      21       34896K    dentry  
  10.  38832  36498   93%    0.64K   1618      24       25888K    inode_cache ...  
  11.   6174   6009   97%    0.19K   294      21       1176K    cred_jar  
  12.   6066   5878   96%    0.44K   337      18       2696K    xfrm_dst_cache  
  13.   5950   5950   100%   0.02K   35      170      140K     avtab_node  
  14.   4807   4581   95%    0.69K   209      23       3344K    sock_inode_cache  
  15.   3948   3812   96%    1.12K   141      28       4512K    signal_cache  
  16.   3744   3680   98%    0.25K   234      16       936K     skbuff_head_cache  
  17.   3634   3634   100%   0.09K   79      46       316K     trace_event_file 

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

總結

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

VFS 定義了一組所有文件系統(tǒng)都支持的數據結構和標準接口。這樣,用戶進程和內核中的其他子系統(tǒng),就只需要跟 VFS 提供的統(tǒng)一接口進行交互。

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

 

責任編輯:龐桂玉 來源: 程序員GitHub
相關推薦

2019-06-04 14:15:08

JavaScript V8前端

2019-07-22 15:29:53

JavaScriptGitHub語言

2019-04-26 13:55:02

Istio微服務架構

2021-02-19 20:38:01

互聯(lián)網衛(wèi)星系統(tǒng)

2011-02-28 09:51:43

內省

2011-02-16 16:13:40

Debian

2021-05-19 14:48:58

Linux文件fd

2021-03-12 10:28:36

996職場數據

2021-06-11 11:34:37

臉書Facebook商業(yè)帝國

2020-06-11 09:18:34

動靜分離架構架構設計開發(fā)

2018-07-05 16:15:26

緩存數據cache miss

2010-08-24 09:19:59

2015-08-26 09:54:19

物聯(lián)網

2011-08-04 13:24:28

IT運維

2012-05-28 22:49:50

PureView

2022-06-13 09:51:35

UWB超寬帶無線載波通信技術

2015-12-14 15:34:35

開源投資創(chuàng)業(yè)

2023-12-26 01:24:45

Jedis連接池參數

2019-05-27 15:30:44

Node.jsJavaScript前端

2015-09-29 09:47:14

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 精品欧美激情精品一区 | 色狠狠桃花综合 | 亚洲精品久久久9婷婷中文字幕 | 亚洲一级av毛片 | 成人免费淫片aa视频免费 | 久久精品视频免费观看 | 中文字幕在线视频观看 | 国产精品久久久久影院色老大 | 在线观看亚洲欧美 | 全免费a级毛片免费看视频免 | 欧美一级免费黄色片 | 精品国产黄色片 | 成人二区 | 国产精品国产精品国产专区不片 | 欧美一区二区三区久久精品 | 欧美成人一区二区 | 国产精品久久久久久久久免费桃花 | 成人福利在线 | 久草综合在线 | www.日本国产 | 日本久久视频 | 成人自拍视频 | 国产一区二区在线91 | 中文字幕一区二区三区四区五区 | 91久久久久久久久久久 | 毛色毛片免费看 | 成人3d动漫一区二区三区91 | 久久99精品久久久久婷婷 | 999久久久久久久久6666 | 欧美视频在线看 | 亚洲精品视频免费看 | 久草精品视频 | 精品一二三区视频 | 色爱综合网 | 日本高清视频在线播放 | 91在线视频免费观看 | 日韩第一区 | 天天操天天摸天天爽 | 国产大片黄色 | 亚洲成人免费在线观看 | 精品入口麻豆88视频 |