<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          0.2秒居然復制了100G文件?

          共 4259字,需瀏覽 9分鐘

           ·

          2021-10-22 08:31

          點擊上方藍色字體,選擇“設為星標”


          回復”學習資料“獲取學習寶典


          文章轉自:OSC開源社區(qū)

          今天同事用 cp?命令,把他驚到了!背景是這樣的:他用 cp ?拷貝了一個 100 G的文件,竟然一秒不到就拷貝完成了!



          cp 引發(fā)的思考


          用 ls ?看一把文件,顯示文件確實是 100 G。

          sh-4.4#?ls?-lh
          -rw-r--r--?1?root?root?100G?Mar??6?12:22?test.txt


          但是 copy 起來為什么會這么快呢?

          sh-4.4#?time?cp?./test.txt?./test.txt.cp

          real?0m0.107s
          user?0m0.008s
          sys?0m0.085s


          一個 SATA 機械盤的寫能力能到 150 M/s (大部分的機械盤都是到不了這個值的)就算非常不錯了,正常情況下,copy 一個 100G 的文件至少要 682 秒 ( 100 G/ 150 M/s ),也就是 11 分鐘。


          實際情況卻是 cp 一秒沒到就完成了工作,驚呆了,為啥呢?更詭異的是:他的文件系統只有 40 G,為啥里面會有一個 100 G的文件呢?


          同事把我找來,看看這個詭異的問題。

          ①分析文件


          我讓他先用 du 命令看一下,卻只有 2M ,根本不是 100G,這是怎么回事?

          sh-4.4#?du?-sh?./test.txt
          2.0M?./test.txt


          再看 stat 命令顯示的信息:

          sh-4.4#?stat?./test.txt
          ??File:?./test.txt
          ??Size:?107374182400?Blocks:?4096???????IO?Block:?4096???regular?file
          Device:?78h/120d?Inode:?3148347?????Links:?1
          Access:?(0644/-rw-r--r--)??Uid:?(????0/????root)???Gid:?(????0/????root)
          Access:?2021-03-13?12:22:00.888871000?+0000
          Modify:?2021-03-13?12:22:46.562243000?+0000
          Change:?2021-03-13?12:22:46.562243000?+0000
          ?Birth:?-


          stat 命令輸出解釋:
          • Size 為 107374182400(知識點:單位是字節(jié)),也就是 100G。

          • Blocks 這個指標顯示為 4096(知識點:一個 Block 的單位固定是 512 字節(jié),也就是一個扇區(qū)的大小),這里表示為 2M。


          劃重點:
          • Size 表示的是文件大小,這個也是大多數人看到的大小。

          • Blocks 表示的是物理實際占用空間。


          同事問道:“文件大小和實際物理占用,這兩個竟然不是相同的概念 !為什么是這樣??”??


          “看來,我們必須得深入文件系統才能理解了,來,我給你好好講講。”

          文件系統


          文件系統聽起來很高大上,通俗話就用來存數據的一個容器而已,本質和你的行李箱、倉庫沒有啥區(qū)別,只不過文件系統存儲的是數字產品而已。


          我有一個視頻文件,我把這個視頻放到這個文件系統里,下次來拿,要能拿到我完整的視頻文件數據,這就是文件系統,對外提供的就是存取服務。


          現實的存取場景:例如你到火車站使用寄存服務,存行李的時候,是不是要登記一些個人信息?


          對吧,至少自己名字要寫上。可能還會給你一個牌子,讓你掛手上,這個東西就是為了標示每一個唯一的行李。


          取行李的時候,要報自己名字,有牌子的給他牌子,然后工作人員才能去特定的位置找到你的行李。

          劃重點:存的時候必須記錄一些關鍵信息(記錄 ID、給身份牌),取的時候才能正確定位到。

          ①文件系統


          回到我們的文件系統,對比上面的行李存取行為,可以做個簡單的類比:
          • 登記名字就是在文件系統記錄文件名

          • 生成的牌子就是元數據索引

          • 你的行李就是文件

          • 寄存室就是磁盤(容納東西的物理空間)

          • 管理員整套運行機制就是文件系統


          上面的對應并不是非常嚴謹,僅僅是幫助大家理解文件系統而已,讓大家知道其實文件系統是非常樸實的一個東西,思想都來源于生活。

          ②空間管理


          現在思考文件系統是怎么管理空間的?如果,一個連續(xù)的大磁盤空間給你使用,你會怎么使用這段空間呢?


          直觀的一個想法,我把進來的數據就完整的放進去。

          這種方式非常容易實現,屬于眼前最簡單,以后最麻煩的方式。因為會造成很多空洞,明明還有很多空間位置,但是由于整個太大,形狀不合適(數據大小),哪里都放不下。因為你要放一個完整的空間。


          怎么改進?有人會想,既然整個放不進去,那就剁碎了唄。這里塞一點,那里塞一點,就塞進去了。


          對,思路完全正確。改進的方式就是切分,把空間按照一定粒度切分。每個小粒度的物理塊命名為 Block,每個 Block 一般是 4K 大小,用戶數據存到文件系統里來自然也是要切分,存儲到磁盤上各個角落。

          圖示標號表示這個完整對象的 Block 的序號,用來復原對象用的。


          隨之而來又有一個問題:你光會切成塊還不行,取文件數據的時候,還得把它們給組合起來才行。


          所以,要有一個表記錄文件對應所有 Block 的位置,這個表被文件系統稱為inode。


          寫文件的流程是這樣的:
          • 先寫數據:數據先按照 Block 粒度存儲到磁盤的各個位置。

          • 再寫元數據:然后把 Block 所在的各個位置保存起來,即 inode(我用一本書來表示)。
          讀文件流程則是:
          • 先讀 inode,找到各個 Block 的位置。

          • 然后讀數據,構造一個完整的文件,給到用戶。

          inode/block 概念

          好,我們現在來看看 inode,直觀地感受一下:

          這個 inode 有文件元數據和 Block 數組(長度是 15),數組中前兩項指向 Block 3 和 Block 11,表示數據在這兩個塊中存著。?


          你肯定會意識到:Block 數組只有 15 個元素,每個 Block 是 4K, 難道一個文件最大只能是 15*4K=60K ? ?


          這是絕對不行的!?最簡單的辦法就是:把這個 Block 數組長度給擴大!


          比如我們想讓文件系統最大支持 100G 的文件,Block 數組需要這么長:(100*1024*1024)/4=26214400。

          Block 數組中每一項是 4 個字節(jié),那就需要(26214400*4)/1024/1024=100M。


          為了支持 100G 的文件,我們的 Block 數組本身就得 100M !?并且對每個文件都是如此 !即使這個文件只有 1K!?這將是巨大浪費!


          肯定不能這么干,解決方案就是間接索引,按照約定,把這 15 個槽位分作 4 個不同類別來用:
          • 前 12 個槽位(也就是 0 - 11 )我們成為直接索引

          • 第 13 個位置,我們稱為?1 級索引

          • 第 14 個位置,我們稱為?2 級索引

          • 第 15 個位置,我們稱為?3 級索引


          直接索引:能存 12 個 block 編號,每個 block 4K,就是 48K,也就是說,48K 以內的文件,前 12 個槽位存儲編號就能完全 hold 住。


          一級索引:也就是說這里存儲的編號指向的 block 里面存儲的也是 block 編號,里面的編號指向用戶數據。


          一個 block ?4K,每個元素 4 字節(jié),也就是有 1024 個編號位置可以存儲。所以,一級索引能尋址 4M(1024 * 4K)空間 。

          二級索引:二級索引是在一級索引的基礎上多了一級而已,換算下來,有了 4M 的空間用來存儲用戶數據的編號。所以二級索引能尋址 4G (4M/4 * 4K)?的空間。

          三級索引:三級索引是在二級索引的基礎上又多了一級,也就是說,有了 4G 的空間來存儲用戶數據的 block 編號。所以二級索引能尋址 4T (4G/4 * 4K) 的空間。

          所以,在這種文件系統(如ext2)上,通過這種間接塊索引的方式,最大能支撐的文件大小 = 48K+4M+4G+4T ,約等于 4T。


          這種多級索引尋址性能表現怎么樣?在不超過 12 個數據塊的小文件的尋址是最快的,訪問文件中的任意數據理論只需要兩次讀盤,一次讀 inode,一次讀數據塊。


          訪問大文件中的數據則需要最多五次讀盤操作:inode、一級間接尋址塊、二級間接尋址塊、三級間接尋址塊、數據塊。


          為什么 cp 那么快?接下來我們要寫入一個奇怪的文件,這個文件很大,但是真正的數據只有 8K:

          • 在 [0,4K] 這位置有 4K 的數據

          • 在 [1T , 1T+4K] 處也有 4K 數據


          中間沒有數據,這樣的文件該如何寫入硬盤?
          • 創(chuàng)建一個文件,這個時候分配一個 inode。

          • 在 [ 0,4K ] 的位置寫入 4K 數據,這個時候只需要 一個 block,把這個編號寫到 block[0]?這個位置保存起來。

          • 在 [ 1T,1T+4K ] 的位置寫入 4K 數據,這個時候需要分配一個 block,因為這個位置已經落到三級索引才能表現的空間了,所以需要還需要分配出 3 個索引塊。。

          • 寫入完成,close 文件。


          實際存儲如圖:

          這個時候,我們的文件看起來是超大文件,size 等于 1T+4K ,但里面實際的數據只有 8K,位置分別是 ?[ 0,4K ],[ 1T,1T+4K ]。?


          由于沒寫數據的地方不用分配物理 block 塊,所以實際占用的物理空間只有 8K。


          重點:文件 size 只是 inode 里面的一個屬性,實際物理空間占用則是要看用戶數據放了多少個 block ,沒寫數據的地方不用分配物理 block 塊。


          這樣的文件其實就是稀疏文件, 它的邏輯大小和實際物理空間是不相等的。?所以當我們用 cp 命令去復制一個這樣的文件時,那肯定迅速就完成了。

          好,我們再深入思考下,文件系統為什么能做到這一點?
          • 首先,最關鍵的是把磁盤空間切成離散的、定長的 block 來管理。

          • 然后,通過 inode 能查找到所有離散的數據(保存了所有的索引)。

          • 最后,實現索引塊和數據塊空間的后分配。


          這三點是層層遞進的。


          后記


          我把這點小知識給小伙伴講了一小時,看到他感動欲哭的表情,我覺得他學 fei 了,非常滿意。是我想太多了嗎?中午吃飯都沒叫我。



          后臺回復?學習資料?領取學習視頻



          瀏覽 48
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日本一级色情片 | 国产午夜精品久久 | 影音先锋亚洲成人 | 在线国产理论午夜福利片 | 亚洲AV无码成人精品区久 |