<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秒居然復(fù)制了100G文件?

          共 5087字,需瀏覽 11分鐘

           ·

          2021-10-13 01:36

          轉(zhuǎn)自:OSC開(kāi)源社區(qū)

          cp 引發(fā)的思考

          今天同事用 cp 命令,把他給驚到了!
          背景是這樣的:他用 cp  拷貝了一個(gè) 100 G的文件,竟然一秒不到就拷貝完成了!
          用 ls  看一把文件,顯示文件確實(shí)是 100 G。

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

          但是copy起來(lái)為什么會(huì)這么快呢?

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

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

          一個(gè) SATA 機(jī)械盤(pán)的寫(xiě)能力能到 150 M/s (大部分的機(jī)械盤(pán)都是到不了這個(gè)值的)就算非常不錯(cuò)了,正常情況下,copy 一個(gè) 100G 的文件至少要 682 秒 ( 100 G/ 150 M/s ),也就是 11 分鐘。
          實(shí)際情況卻是 cp 一秒沒(méi)到就完成了工作,驚呆了,為啥呢?
          更詭異的是:他的文件系統(tǒng)只有 40 G,為啥里面會(huì)有一個(gè) 100 G的文件呢?
          同事把我找來(lái),看看這個(gè)詭異的問(wèn)題。

          分析文件

          我讓他先用 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 命令輸出解釋:
          1. Size 為 107374182400(知識(shí)點(diǎn):?jiǎn)挝皇亲止?jié)),也就是 100G ;
          2. Blocks 這個(gè)指標(biāo)顯示為 4096(知識(shí)點(diǎn):一個(gè) Block 的單位固定是 512 字節(jié),也就是一個(gè)扇區(qū)的大小),這里表示為 2M;
          劃重點(diǎn)
          • Size 表示的是文件大小,這個(gè)也是大多數(shù)人看到的大小;
          • Blocks 表示的是物理實(shí)際占用空間
          同事問(wèn)道:文件大小和實(shí)際物理占用,這兩個(gè)竟然不是相同的概念 !為什么是這樣?   
          “看來(lái),我們必須得深入文件系統(tǒng)才能理解了,來(lái),我給你好好講講。”
          文件系統(tǒng)
          文件系統(tǒng)聽(tīng)起來(lái)很高大上,通俗話就用來(lái)存數(shù)據(jù)的一個(gè)容器而已,本質(zhì)和你的行李箱、倉(cāng)庫(kù)沒(méi)有啥區(qū)別,只不過(guò)文件系統(tǒng)存儲(chǔ)的是數(shù)字產(chǎn)品而已。
          我有一個(gè)視頻文件,我把這個(gè)視頻放到這個(gè)文件系統(tǒng)里,下次來(lái)拿,要能拿到我完整的視頻文件數(shù)據(jù),這就是文件系統(tǒng),對(duì)外提供的就是存取服務(wù)

          現(xiàn)實(shí)的存取場(chǎng)景

          例如你到火車站使用寄存服務(wù):
          存行李的時(shí)候,是不是要登記一些個(gè)人信息?對(duì)吧,至少自己名字要寫(xiě)上。可能還會(huì)給你一個(gè)牌子,讓你掛手上,這個(gè)東西就是為了標(biāo)示每一個(gè)唯一的行李。

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

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

          文件系統(tǒng)

          回到我們的文件系統(tǒng),對(duì)比上面的行李存取行為,可以做個(gè)簡(jiǎn)單的類比;
          1. 登記名字就是在文件系統(tǒng)記錄文件名;
          2. 生成的牌子就是元數(shù)據(jù)索引;
          3. 你的行李就是文件;
          4. 寄存室就是磁盤(pán)(容納東西的物理空間);
          5. 管理員整套運(yùn)行機(jī)制就是文件系統(tǒng);
          上面的對(duì)應(yīng)并不是非常嚴(yán)謹(jǐn),僅僅是幫助大家理解文件系統(tǒng)而已,讓大家知道其實(shí)文件系統(tǒng)是非常樸實(shí)的一個(gè)東西,思想都來(lái)源于生活。

          空間管理

          現(xiàn)在思考文件系統(tǒng)是怎么管理空間的?
          如果,一個(gè)連續(xù)的大磁盤(pán)空間給你使用,你會(huì)怎么使用這段空間呢?
          直觀的一個(gè)想法,我把進(jìn)來(lái)的數(shù)據(jù)就完整的放進(jìn)去。

          這種方式非常容易實(shí)現(xiàn),屬于眼前最簡(jiǎn)單,以后最麻煩的方式。因?yàn)闀?huì)造成很多空洞,明明還有很多空間位置,但是由于整個(gè)太大,形狀不合適(數(shù)據(jù)大小),哪里都放不下。因?yàn)槟阋乓粋€(gè)完整的空間。
          怎么改進(jìn)?有人會(huì)想,既然整個(gè)放不進(jìn)去,那就剁碎了唄。這里塞一點(diǎn),那里塞一點(diǎn),就塞進(jìn)去了。
          對(duì),思路完全正確。改進(jìn)的方式就是切分,把空間按照一定粒度切分。每個(gè)小粒度的物理塊命名為 Block,每個(gè) Block 一般是 4K 大小,用戶數(shù)據(jù)存到文件系統(tǒng)里來(lái)自然也是要切分,存儲(chǔ)到磁盤(pán)上各個(gè)角落。

          圖示標(biāo)號(hào)表示這個(gè)完整對(duì)象的 Block 的序號(hào),用來(lái)復(fù)原對(duì)象用的。
          隨之而來(lái)又有一個(gè)問(wèn)題:你光會(huì)切成塊還不行,取文件數(shù)據(jù)的時(shí)候,還得把它們給組合起來(lái)才行。
          所以,要有一個(gè)表記錄文件對(duì)應(yīng)所有 Block 的位置,這個(gè)表被文件系統(tǒng)稱為inode
          寫(xiě)文件的流程是這樣的:

          1. 先寫(xiě)數(shù)據(jù):數(shù)據(jù)先按照 Block 粒度存儲(chǔ)到磁盤(pán)的各個(gè)位置;
          2. 再寫(xiě)元數(shù)據(jù):然后把 Block 所在的各個(gè)位置保存起來(lái),即inode(我用一本書(shū)來(lái)表示);

          讀文件流程則是:
          1. 先讀inode,找到各個(gè) Block 的位置;
          2. 然后讀數(shù)據(jù),構(gòu)造一個(gè)完整的文件,給到用戶;

          inode/block 概念

          好,我們現(xiàn)在來(lái)看看inode,直觀地感受一下:
          這個(gè)inode有文件元數(shù)據(jù)Block數(shù)組(長(zhǎng)度是15),數(shù)組中前兩項(xiàng)指向Block 3和Block 11,表示數(shù)據(jù)在這兩個(gè)塊中存著。 
          你肯定會(huì)意識(shí)到:Block數(shù)組只有15個(gè)元素,每個(gè)Block是4K, 難道一個(gè)文件最大只能是 15 * 4K =  60 K ?  
          這是絕對(duì)不行的! 
          最簡(jiǎn)單的辦法就是:把這個(gè)Block數(shù)組長(zhǎng)度給擴(kuò)大!
          比如我們想讓文件系統(tǒng)最大支持100G的文件,Block數(shù)組需要這么長(zhǎng):
          (100*1024*1024)/4 = 26214400
          Block數(shù)組中每一項(xiàng)是4個(gè)字節(jié),那就需要(26214400*4)/1024/1024 = 100M 
          為了支持100G的文件,我們的Block數(shù)組本身就得100M ! 
          并且對(duì)每個(gè)文件都是如此 !即使這個(gè)文件只有1K! 這將是巨大浪費(fèi)!
          肯定不能這么干,解決方案就是間接索引,按照約定,把這 15 個(gè)槽位分作 4 個(gè)不同類別來(lái)用:
          1. 前 12 個(gè)槽位(也就是 0 - 11 )我們成為直接索引
          2. 第 13 個(gè)位置,我們稱為 1 級(jí)索引
          3. 第 14 個(gè)位置,我們稱為 2 級(jí)索引
          4. 第 15 個(gè)位置,我們稱為 3 級(jí)索引

          直接索引:能存 12 個(gè) block 編號(hào),每個(gè) block 4K,就是 48K,也就是說(shuō),48K 以內(nèi)的文件,前 12 個(gè)槽位存儲(chǔ)編號(hào)就能完全 hold 住。
          一級(jí)索引
          也就是說(shuō)這里存儲(chǔ)的編號(hào)指向的 block 里面存儲(chǔ)的也是 block 編號(hào),里面的編號(hào)指向用戶數(shù)據(jù)。一個(gè) block  4K,每個(gè)元素 4 字節(jié),也就是有 1024 個(gè)編號(hào)位置可以存儲(chǔ)。
          所以,一級(jí)索引能尋址 4M(1024 * 4K)空間 。
          二級(jí)索引
          二級(jí)索引是在一級(jí)索引的基礎(chǔ)上多了一級(jí)而已,換算下來(lái),有了 4M 的空間用來(lái)存儲(chǔ)用戶數(shù)據(jù)的編號(hào)。所以二級(jí)索引能尋址 4G (4M/4 * 4K) 的空間。
          三級(jí)索引
          三級(jí)索引是在二級(jí)索引的基礎(chǔ)上又多了一級(jí),也就是說(shuō),有了 4G 的空間來(lái)存儲(chǔ)用戶數(shù)據(jù)的 block 編號(hào)。所以二級(jí)索引能尋址 4T (4G/4 * 4K) 的空間。
          所以,在這種文件系統(tǒng)(如ext2)上,通過(guò)這種間接塊索引的方式,最大能支撐的文件大小 = 48K + 4M + 4G + 4T ,約等于 4 T。
          這種多級(jí)索引尋址性能表現(xiàn)怎么樣?
          在不超過(guò) 12 個(gè)數(shù)據(jù)塊的小文件的尋址是最快的,訪問(wèn)文件中的任意數(shù)據(jù)理論只需要兩次讀盤(pán),一次讀 inode,一次讀數(shù)據(jù)塊。
          訪問(wèn)大文件中的數(shù)據(jù)則需要最多五次讀盤(pán)操作:inode、一級(jí)間接尋址塊、二級(jí)間接尋址塊、三級(jí)間接尋址塊、數(shù)據(jù)塊。

          為什么cp那么快?

          接下來(lái)我們要寫(xiě)入一個(gè)奇怪的文件,這個(gè)文件很大,但是真正的數(shù)據(jù)只有8K:
          在[0,4K]這位置有4K的數(shù)據(jù)
          在[1T , 1T+4K] 處也有4K數(shù)據(jù)
          中間沒(méi)有數(shù)據(jù),這樣的文件該如何寫(xiě)入硬盤(pán)?
          1. 創(chuàng)建一個(gè)文件,這個(gè)時(shí)候分配一個(gè) inode;
          2. 在 [ 0,4K ] 的位置寫(xiě)入 4K 數(shù)據(jù),這個(gè)時(shí)候只需要 一個(gè) block,把這個(gè)編號(hào)寫(xiě)到 block[0] 這個(gè)位置保存起來(lái);
          3. 在 [ 1T,1T+4K ] 的位置寫(xiě)入 4K 數(shù)據(jù),這個(gè)時(shí)候需要分配一個(gè) block,因?yàn)檫@個(gè)位置已經(jīng)落到三級(jí)索引才能表現(xiàn)的空間了,所以需要還需要分配出 3 個(gè)索引塊;
          4. 寫(xiě)入完成,close 文件;
          實(shí)際存儲(chǔ)如圖

          這個(gè)時(shí)候,我們的文件看起來(lái)是超大文件,size 等于 1T+4K ,但里面實(shí)際的數(shù)據(jù)只有 8 K,位置分別是  [ 0,4K ] ,[ 1T,1T+4K ]。 
          由于沒(méi)寫(xiě)數(shù)據(jù)的地方不用分配物理block塊,所以實(shí)際占用的物理空間只有8K。
          重點(diǎn):文件 size 只是 inode 里面的一個(gè)屬性,實(shí)際物理空間占用則是要看用戶數(shù)據(jù)放了多少個(gè) block ,沒(méi)寫(xiě)數(shù)據(jù)的地方不用分配物理block塊。
          這樣的文件其實(shí)就是稀疏文件, 它的邏輯大小和實(shí)際物理空間是不相等的。 
          所以當(dāng)我們用cp命令去復(fù)制一個(gè)這樣的文件時(shí),那肯定迅速就完成了。

          總結(jié)

          好,我們?cè)偕钊胨伎枷拢募到y(tǒng)為什么能做到這一點(diǎn)?

          1. 首先,最關(guān)鍵的是把磁盤(pán)空間切成離散的、定長(zhǎng)的 block 來(lái)管理;
          2. 然后,通過(guò) inode 能查找到所有離散的數(shù)據(jù)(保存了所有的索引);
          3. 最后,實(shí)現(xiàn)索引塊和數(shù)據(jù)塊空間的后分配;
          這三點(diǎn)是層層遞進(jìn)的。

          往期推薦

          Spring Boot中使用PostgreSQL數(shù)據(jù)庫(kù)

          細(xì)說(shuō)Redis分布式鎖

          Git各指令的本質(zhì),真是通俗易懂啊

          聊聊前后端分離的接口規(guī)范

          用這個(gè)開(kāi)源項(xiàng)目,給你心愛(ài)的女孩子搶個(gè)九價(jià)疫苗吧!


          技術(shù)交流群

          最近有很多人問(wèn),有沒(méi)有讀者交流群,想知道怎么加入。加入方式很簡(jiǎn)單,有興趣的同學(xué),只需要點(diǎn)擊下方卡片,回復(fù)“加群,即可免費(fèi)加入我們的高質(zhì)量技術(shù)交流群!


          點(diǎn)擊閱讀原文,直達(dá)教程目錄(Spring Boot教程放這一段)

          點(diǎn)擊閱讀原文,送你免費(fèi)Spring Boot教程!(非Spring Boot教程放這一段)

          閱讀原文鏈接:

          https://blog.didispace.com/spring-boot-learning-2x/


          瀏覽 35
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <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>
                  毛片毛片女人毛片毛片 | 韩国毛片在线播放 | 欧美性爱-熊猫成人网 | 日韩一级电影在线 | 国产精品久久久久久久久久梁医生 |