HDFS概述(2)————Block塊大小設置


以下內容轉自:http://blog.csdn.net/samhacker/article/details/23089157?utm_source=tuicool&utm_medium=referral

 http://snglw.blog.51cto.com/5832405/1643587

 

小文件BLOCK占用

【小於塊大小的小文件不會占用整個HDFS塊空間。也就是說,較多的小文件會占用更多的NAMENODE的內存(記錄了文件的位置等信息);再者,在文件處理時,可能會有較大的網絡開銷。】

一個常被問到的一個問題是: 如果一個HDFS上的文件大小(file size) 小於塊大小(block size) ,那么HDFS會實際占用Linux file system的多大空間?

答案是實際的文件大小,而非一個塊的大小。

1、往hdfs里面添加新文件前,hadoop在linux上面所占的空間為 464 MB:

2、往hdfs里面添加大小為2673375 byte(大概2.5 MB)的文件:

2673375 derby.jar 

3、此時,hadoop在linux上面所占的空間為 467 MB—— 增加了一個實際文件大小(2.5 MB)的空間,而非一個block size(128 MB) :

4、使用hadoop dfs -stat查看文件信息: 

這里就很清楚地反映出: 文件的實際大小(file size)是2673375 byte, 但它的block size是128 MB。

5、通過NameNode的web console來查看文件信息: 

結果是一樣的: 文件的實際大小(file size)是2673375 byte, 但它的block size是128 MB。

6、不過使用‘hadoop fsck’查看文件信息,看出了一些不一樣的內容——  ‘1(avg.block size 2673375 B)’: 

值得注意的是,結果中有一個 ‘1(avg.block size 2673375 B)’的字樣。這里的 'block size' 並不是指平常說的文件塊大小(Block Size)—— 后者是一個元數據的概念,相反它反映的是文件的實際大小(file size)。以下是Hadoop Community的專家給我的回復: 

“The fsck is showing you an "average blocksize", not the block size metadata attribute of the file like stat shows. In this specific case, the average is just the length of your file, which is lesser than one whole block.”

最后一個問題是: 如果hdfs占用Linux file system的磁盤空間按實際文件大小算,那么這個”塊大小“有必要存在嗎?

其實塊大小還是必要的,一個顯而易見的作用就是當文件通過append操作不斷增長的過程中,可以通過來block size決定何時split文件。以下是Hadoop Community的專家給我的回復: 

“The block size is a meta attribute. If you append tothe file later, it still needs to know when to split further - so it keeps that value as a mere metadata it can use to advise itself on write boundaries.” 

 

 

HDFS設置BLOCK的目的

在HDFS里面,data node上的塊大小默認是64MB(或者是128MB或256MB)

問題: 為什么64MB(或128MB或256MB)是最優選擇?

為什么不能遠少於64MB(或128MB或256MB) (普通文件系統的數據塊大小一般為4KB)減少硬盤尋道時間(disk seek time)

 
1.減少硬盤尋道時間

HDFS設計前提是支持大容量的流式數據操作,所以即使是一般的數據讀寫操作,涉及到的數據量都是比較大的。假如數據塊設置過少,那需要讀取的數據塊就比較多,

由於數據塊在硬盤上非連續存儲,普通硬盤因為需要移動磁頭,所以隨機尋址較慢,讀越多的數據塊就增大了總的硬盤尋道時間。當硬盤尋道時間比io時間還要長的多時,那么硬盤尋道時間就成了系統的一個瓶頸。合適的塊大小有助於減少硬盤尋道時間,提高系統吞吐量。

2.減少Namenode內存消耗

對於HDFS,他只有一個Namenode節點,他的內存相對於Datanode來說,是極其有限的。然而,namenode需要在其內存FSImage文件中中記錄在Datanode中的數據塊信息,假如數據塊大小設置過少,而需要維護的數據塊信息就會過多,那Namenode的內存可能就會傷不起了。

 

 

為什么不能遠大於64MB(或128MB或256MB)?

 

這里主要從上層的MapReduce框架來討論

Map崩潰問題:系統需要重新啟動,啟動過程需要重新加載數據,數據塊越大,數據加載時間越長,系統恢復過程越長

監管時間問題:主節點監管其他節點的情況,每個節點會周期性的把完成的工作和狀態的更新報告回來。如果一個節點保持沉默超過一個預設的時間間隔,主節點記錄下這個節點狀態為死亡,並把分配給這個節點的數據發到別的節點。對於這個“預設的時間間隔”,這是從數據塊的角度大概估算的。假如是對於64MB的數據塊,我可以假設你10分鍾之內無論如何也能解決了吧,超過10分鍾也沒反應,那就是死了。可對於640MB或是1G以上的數據,我應該要估算個多長的時間內?估算的時間短了,那就誤判死亡了,分分鍾更壞的情況是所有節點都會被判死亡。估算的時間長了,那等待的時間就過長了。所以對於過大的數據塊,這個“預設的時間間隔”不好估算。

問題分解問題:數據量大小是問題解決的復雜度是成線性關系的。對於同個算法,處理的數據量越大,它的時間復雜度也就越大。

約束Map輸出:在Map Reduce框架里,Map之后的數據是要經過排序才執行Reduce操作的。想想歸並排序算法的思想,對小文件進行排序,然后將小文件歸並成大文件的思想,然后就會懂這點了

 

 

 

 

hadoop在文件的split中使用到了一個 變量 是   blocksize,這個值  默認配置 是 64M  ,1.0的代碼 給的默認值是32M ,這個值我們先不要糾纏 他 到底是多少,因為這個值是可配置的,而且已經給了默認配置64M ,只有我們不配置的時候才會使用32M ,且在官方文檔上2.0已經是64M。

那么為什么這個大小是64M ,記得在jvm的一片論文中提到這個大小是64M ,

 

我們在使用linux的時候,linux系統也有塊的大小,我們一般是喲功能的4096   也就是4K ,

 

Java代碼   收藏代碼
  1. [root@cluster-19 workspace]# du -sk  
  2. 272032  .  
  3. [root@cluster-19 workspace]# vi 1  
  4. [root@cluster-19 workspace]# du -sk  
  5. 272036  .  
  6. [root@cluster-19 workspace]# ls -la 1  
  7. -rw-r--r--. 1 root root 8月  27 14:56 1  

 以上代碼可以看到,我們 使用du命令  時    看到 1 這個文件占用了一個 塊  的空間,由於一個塊的空間是 4096 (4K) 所有我們創建1這個文件之后  我們看到磁盤空間 增加了 4K  , 但是我們在使用ls 查看 1 這個文件的時候,我么看到 這里 文件的大小是 2 個字節。

其實我們使用ls 看到的只是文件的meta信息。

那么在hdfs中呢,前邊已經說過塊的大小是64M ,

我們做個假設  如果  1T 的盤 ,我們上傳 小文件到 hdfs   ,那么我們是不是只能上傳1632個小文件,這個和我們預期遠遠不相符,hadoop確實是處理大文件有優勢,但是也有處理小文件的能力,那就是在shuffle階段會有合並的,且map的個數和塊的數量有關系,如果塊很小,那其不是有很多塊 也就是很多map了

所以 hdfs中的塊,會被充分利用,如果一個文件的大小小於這個塊的話那么這個文件 不會占據整個塊空間:

 

hdfs 的塊 如此之大 主要還是為 減小尋址開銷的 :

 

一用hadoop權威指南一句話:

Java代碼   收藏代碼
  1. HDFS的塊比磁盤塊大,其目的是為了最小化尋址開銷。如果塊設置得足夠大,從磁盤傳輸數據的時間可以明顯大於定位這個塊開始位置所需的時間。這樣,傳輸一個由多個塊組成的文件的時間取決於磁盤傳輸速率。  
  2.   
  3.   
  4. 我們來做一個速算,如果尋址時間為10ms左右,而傳輸速率為100MB/s,為了使尋址時間僅占傳輸時間的1%,我們需要設置塊大小為100MB左右。而默認的塊大小實際為64MB,但是很多情況下HDFS使用128MB的塊設置。以后隨着新一代磁盤驅動器傳輸速率的提升,塊的大小將被設置得更大。  
  5.   
  6.   
  7. 但是該參數也不會設置得過大。MapReduce中的map任務通常一次處理一個塊中的數據,因此如果任務數太少(少於集群中的節點數量),作業的運行速度就會比較慢。  

 

我們都知道 ,hdfs 的文件是不允許修改的,目前的hadoop2.0 持支 對一個文件做append操作,那么就遇到另一個問題,

假如現在有一個兩個文件  放在同一個block中的話:

 

如上圖,如果原始文件是這樣字存在的話 ,那么我如果對File1 做 append操作的花,那么hdfs會怎么處理呢?

我們知道在文件的namenode信息中記錄了文件的信息,我們對hadoop做了appdend之后,一個文件只會記錄一個文件信息,不可能一個文件記錄在多個文件塊中,那么 hdfs是會將File1 原來的文件取出來,和我們將要appdend的內容放在一起重新存儲文件呢?還是在文件的meta信息中維護了這個文件的兩個地址呢?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM