本篇的主旨在於「協助入門Hadoop」並能快速地掌握一些概念,所以筆者先以基本的檔案系統(file system)來敘述,故本篇不會包含「HDFS」,當然文中若有任何謬誤的地方,麻煩不吝地給予指教,筆者必當感激!
感謝 Yi-Kai 協助Review本文。
何謂檔案系統?它和檔案格式(file format)有什麼不同?
筆者先行介紹一下檔案格式,這裡我們先來想像一個劇情,通常我們電腦開機後,進入到作業系統之中,然後就開始進行我們想要執行的程式,例如:上網我們可以開啟Firefox,聽音樂我們可以開啟一個MP3,看影像我們可以開啟任一張JPEG等相關格式的影像,OK, 劇本就到此為止,現在我們來回顧上述的情況,為何我們點選一張影像左鍵兩下,就可以開啟這張影像並顯示出來?必然是我們系統有個看圖軟體(e.g. ACDSee)或是美工軟體,而這些軟體都會向作業系統註冊一些指定用來開啟的檔案格式,也就是說,只要你點選特定的影像檔案格式(e.g. jpeg,png),它就指定用這些相關軟體來開啟,所以作業系統會先載入這個特定軟體到記憶體,然後由這個軟體來開啟這張影像檔。
重點就在於開啟這張影像檔時,看圖軟體就會開始剖析你剛剛所點選的這張影像檔,如: jpeg,然後並顯示出來在螢幕上,從這裡我們可以知道,我們所利用手機或數位相機所拍攝的影像資訊都會儲存在這個檔案格式中,當然一個影像檔案格式它所包含的資訊也許不只有影像資料,我們可以在一個用數位相機拍攝的影像檔上,按右鍵點選「內容」並在「摘要」項目可以看到我們當時拍攝的一些相關資訊,如:拍照時間、快門、曝光、光圈等資訊。筆者再舉另一個實際的例子,在windows xp的作業系統上,倘若我們開啟一個放滿影像的目錄夾,並在瀏覽模式選擇「縮圖模式」,你會發現在目錄夾中自動地多出一個名為「Thumbs.db」的檔案,這個檔案沒有任何惡意,它純粹用來存放縮圖影像的快取資訊而已,有興趣的話可以用相關的HexDump工具將這個檔案Dump出來看,你會發現有許多以「0xFF、0xD8」和「0xFF、0xD9」的bytes資訊,這兩對的位元組就代表jpeg影像格式的開頭、結尾。
OK, 同樣的道理,開啟一個MP3音樂檔也是類似的作法,且甚至有些軟體還提供編輯相關歌詞直接附加在MP3的檔案格式之中,並一邊播放音樂還可以一邊對應到歌詞。
那何謂檔案系統?
基本上每個作業系統都有屬於自己的檔案系統,那它是要做什麼用的?我想大家多半應該都有電腦重灌的經驗,就算沒有也應該有聽過「重灌」兩字吧! 那在安裝作業系統時一定會詢問你要用什麼檔案系統來格式化你的磁碟,在Windows平台下常用的從以前的FAT、FAT32到NTFS。
那為何要格式化?由於磁碟上的基本儲存單位是磁區(sector),而一個磁區的單位是512 bytes,重點就在這邊,由於一張影像檔或是一個音樂檔,都動輒幾mb,換句話說,如果我們用基本的儲存單位512 bytes來儲存這些檔案當然也是可行的,但,這樣卻犧牲了效能,為何?這牽扯到磁碟上seek time的問題,假設先不考慮相關的細節問題,你只要了解磁碟上的磁頭要移到你所想要讀/寫的磁區位置,而這個過程所需要的時間就稱它為seek time,依目前市面上的磁碟(7200rpm)而言,大部份平均都約8ms ~ 10ms上下不等。
從這個數據再來看Google的搜尋速度,通常第一次對Google查詢的時間會比較慢一些,不過我們是感覺不出來的,因為那個時間通常只有100ms~300ms之間,而對同樣的關鍵字再進行一次查詢,你就會發覺第二次的查詢會比第一次的查詢來得快許多,而且通常都小於 100ms,由於筆者不曉得Google確切的作法,但「應該」是典型的利用空間換取時間的方式,也就是拿記憶體來快取(也許第一次就有相關的處理機制,純粹筆者猜測)。再回到我們的主題中,剛剛提到了為何要格式化?簡單來說,格式化的目的在於讓作業系統能有效地快速讀寫檔案,因為檔案系統會有預設的block size,也就是一個個連續的磁區所組成的blocks,在Linux的ext3檔案系統下,block size可以是1k、2k或4k,而在Windows下的NTFS檔案系統則是4k,所以作業系統可以針對這一個個的block來處理檔案,試問一次讀/ 寫4k、512bytes,那一種方式會來的有效率呢?重點也就在於此,倘若我們採用Windows的平台並格式化成NTFS的檔案系統,那代表著一件事,在這個檔案系統下的任何檔案所耗費的磁碟空間基本上也就是4k,就算你只是用「Notepad」儲存700個英文字母(其實才700 bytes),它仍然會佔用你磁碟4k的空間,這也就是內部分裂(Internal Fragmentation)的問題,那照這樣說Google File System(GFS)預設的block size是「64MB」,不就很浪費空間?的確沒錯,如果沒有相關的機制來處理的話,這樣的作法的確很浪費空間(注意:GFS是Distributed File System的一種,不同於本文所敘述的File System),所以Google採用「Lazy Space Allocation」的作法來處理這樣的問題,那什麼又是「Lazy Space Allocation」?請先關注第一個單字「Lazy」,中文可以翻譯成「懶惰」(想快速閱讀外文嗎?可參考TransNote),這裡的「懶惰」又代表什麼含意?「懶惰」在生活上我們可以為它解釋成「不會主動」的意思,也就是一切都是「懶懶散散」的,或是要人家叫才會「被動」的去做事,筆者舉一個物件導向中Design Patterns的相關例子,如果您對Design Pattern不陌生的話,那一定知道「Singleton Pattern」,筆者在此不詳述何謂「Singleton Pattern」,你只要想像在一個Class之中,我要限制它僅能產生單一個實體(instance)即可,而最簡單的寫法就是直接在Class中寫下
public class Singleton { private static Singleton instance = new Singleton(); private Singleton() {} public static Singleton getInstance() { return instance; } }
之類的作法,但這樣的方式會造成只要這個Class被載入到JVM之後就會馬上產生這個實體,但... 也許,這裡說的是也許,我們都不會用到這個Class,所以我們可以採取「Lazy Initialization」的方式來處理,就可以避免浪費一塊在Heap中的記憶體,唯有等到想使用它時再呼叫「getInstance()」的方法即可,當然這還有同步的問題,不過這就超過這篇文章的範圍了,所以對於「Lazy」這個單字的含意,這裡我們可以給它解釋成「有需要的話我才去做」。
再回到剛剛的主題,Google採用「Lazy Space Allocation」的方式來避免「Internal Fragmentation」的問題發生,也就是說雖然預設「64MB」的block size,但是如果我們將一份10MB、20MB的檔案個別寫入這樣的檔案系統之中,那倒底會耗費多少的磁碟大小?128MB嗎?(勤奮的作法)當然不是~ 而是兩份文件的加總「30MB」如此而已(懶惰的作法)。
喔,怪不得我在每次搬動檔案、增加檔案時總會看到硬碟標示多了4096kb使用率。
那[windows 發現檔案系統有問題。]的意思是?
有重新格式化以外的解決方法嗎?
2009-10-21 08:09:35
用chkdsk試試看,不行再format
2009-10-21 08:39:49
發表前已經試過chkdsk、chkdsk /f /r...全都不行了, 看來真的要format了
先謝了
2009-10-30 15:29:56
1. windows會劃分一部份硬碟空間模擬成ram, 那模擬出來的ram, 仍會受4kb叢集大少影響嗎? 還是跟ram一樣, 可以在任何部份讀/寫?
2. 假設一個檔案剛好是4kb大少, 放在8kb的叢集區,會不會比放在4kb叢集區讀/寫更慢?
3. windows可以安裝在大於4kb的叢集區嗎? 我試過好像不行
4. 其實叢集區有什麼用, 沒有叢集區存在, 一個700位元組的記事本不就可以以原始檔案大少來寫入嗎?
2010-01-30 05:12:08
1. 會,只要存放在檔案系統都一樣。
2. 理論上不會,因為仍只要一次的seek time。
3. 我也沒試過,不過應該可行。
4. 是啊,對磁碟使用率來說比較好,但是這樣存取時就很沒有效率。
2010-02-05 21:36:05
喔! 我看了幾天都不見你回覆, 一直到今天再來...
之前再試過了一下把windows安裝在8kb和64kb都不行,被鎖在4kb了...實在太令人失望了
關於2.因為看了幾天都不見你回覆, 再問了別人, 卻有不同的回覆: http://hk.knowledge.yahoo.com/question/question?qid=7010013102475
(還是以 8K 計算。copy 4k 的當然比 8k 快。這只是對一個檔案而言。)
還是沒有人真正知道呢?...
還想問一下為何4kb跟64kb在讀寫上有何分別, 我想會不會是64kb會供磁頭更多電,以更大磁力作讀寫? 在7200rpm的硬碟測試了一下64kb寫入速度竟然比4kb快上4.xx倍, 不明白
2010-06-07 03:32:13
>還想問一下為何4kb跟64kb在讀寫上有何分別, 我想會不會是64kb會供磁頭更多電,以更大磁力作讀寫? 在7200rpm的硬碟測試了一下64kb寫入速度竟然比4kb快上4.xx倍, 不明白
假設你要寫一個約64kb的資料,試問直接寫在「1塊64kb」的block size和寫在「16塊4kb」的block size哪種比較快?但需要考量Internal Fragmentation的問題。
>關於2.因為看了幾天都不見你回覆, 再問了別人, 卻有不同的回覆: http://hk.knowledge.yahoo.com/question/question?qid=7010013102475
>(還是以 8K 計算。copy 4k 的當然比 8k 快。這只是對一個檔案而言。)
我猜沒錯的話,他指的應該是純粹從copy的角度來看讀一個4k和一個8k的block,所以讀4k的會比較快~ 因為資料較少的關係~ 但是如果有External fragmentation的問題呢?假設要讀8k的資料,而原本讀一個8k的block只要花一次seek time的時間,而4kb則要花二次。可參考:http://en.wikipedia.org/wiki/Slack_space
2010-06-07 08:57:42
謝謝!看過兩個人的回答加上自己的研究,現在明白很多了。
但現在想問一下,一部hard disk共596gb裡面有2隻碟片,我怎樣做可以將2隻碟片準確平圴分割為298gb
即是596*1024*1024*8那種…
2010-11-30 02:28:41
呃... 我沒試過咧~ 你可能要請教有這方面經驗的同好。
2010-11-30 15:39:09
我又來麻煩你了,今次是想問怎様找hard disk的sata驅動程式。
我的主機版是ZOTAC INTEL X58-SLI BOARD,剛去google試找過,找不到…
我主要是想問找的方法…
2011-04-06 12:27:57
官網沒提供的話,寫信過去要可能比較快...
2011-04-07 08:36:53