大資料時代之hadoop(四):hadoop 分散式檔案系統(HDFS)

chaofanwei發表於2014-10-20

 

 

大資料時代之hadoop(一):hadoop安裝

大資料時代之hadoop(二):hadoop指令碼解析

大資料時代之hadoop(三):hadoop資料流(生命週期)

 

        分散式檔案系統即是網路中多臺計算機組合在一起提供一個統一儲存及管理的系統。Hadoop提供了一個檔案系統介面和多個分散式檔案系統實現,其中比較重要的就是HDFS(Hadoop Distributed Filesystem)了。Hadoop是一個綜合性的檔案系統抽象,因此它也可以整合其他檔案系統的實現,如本地檔案系統和Amazon S3系統及淘寶 TFS等。

 

 


1、概念模型

         HDFS以流式資料訪問模式來儲存超大檔案,執行於商業硬體叢集上。

 

         HDFS實現下來,分為兩類節點,一個是namenode及secondarynode,主要目的是用於儲存系統映象及備份。

 

         其中namenode將檔案系統的後設資料儲存在記憶體中(因此該檔案系統所能儲存的檔案總數受制於namenode的記憶體容量)。它維護著檔案系統樹及樹內的所有檔案和目錄,這些資訊同時以兩個檔案(名稱空間映象檔案和編輯日誌檔案)的形式永久儲存在本地磁碟上。namenode也記錄著每個檔案的各個塊所在的資料節點資訊(會在系統啟動時有資料節點重建)。

 

         secondarynode的作用是定期通過編輯日誌檔案合併名稱空間映象,以防止編輯日誌過大和namenode發生故障時啟用並作為新的namenode,但secondarynamenode狀態總是滯後於主節點的。

 

         另一類是datanode,其會有多個,目標就是實現具體的儲存,及把檔案的每個塊給儲存到本地磁碟上,和namenode關聯起來,共同組成儲存。
  

       HDFS在儲存資料時用的塊的概念,預設每個塊大小為64M(目的是為了最小化磁碟定址時間)。HDFS上的檔案被劃分為塊大小的多個分塊(chunk),作為獨立的儲存單元,但HDFS中小於一個塊大小的檔案不會佔據整個塊的空間。因為是分散式檔案系統,HDFS也提供了備份的功能,即把檔案的每個塊都會複製到多個機器上(預設為3個)。

 

2、hadoop檔案系統

        Hadoop有一個抽象的檔案系統概念,HDFS只是其中的一個實現。抽象類org.apache.hadoop.fs.FileSystem定義了一個檔案系統介面,並且該抽象類有幾個具體實現。

 

檔案系統

URI方案

Java實現

(org.apache.hadoop)

定義

Local

file

fs.LocalFileSystem

支援有客戶端校驗和本地檔案系統。帶有校驗和的本地系統檔案在fs.RawLocalFileSystem中實現。

HDFS

hdfs

hdfs.DistributionFileSystem

Hadoop的分散式檔案系統。

HFTP

hftp

hdfs.HftpFileSystem

支援通過HTTP方式以只讀的方式訪問HDFS,distcp經常用在不同的HDFS叢集間複製資料。

HSFTP

hsftp

hdfs.HsftpFileSystem

支援通過HTTPS方式以只讀的方式訪問HDFS。

HAR

har

fs.HarFileSystem

構建在Hadoop檔案系統之上,對檔案進行歸檔。Hadoop歸檔檔案主要用來減少NameNode的記憶體使用

KFS

kfs

fs.kfs.KosmosFileSystem

Cloudstore(其前身是Kosmos檔案系統)檔案系統是類似於HDFS和Google的GFS檔案系統,使用C++編寫。

FTP

ftp

fs.ftp.FtpFileSystem

由FTP伺服器支援的檔案系統。

S3(本地)

s3n

fs.s3native.NativeS3FileSystem

基於Amazon S3的檔案系統。

S3(基於塊)

s3 

fs.s3.NativeS3FileSystem

基於Amazon S3的檔案系統,以塊格式儲存解決了S3的5GB檔案大小的限制。

Hadoop對檔案系統提供了許多介面,它一般使用URI方案來選取合適的檔案系統例項進行互動。

 

3、HDFS實現

        要想實現一個檔案系統,除了簡單的增刪改查檔案以及資料夾等簡單的操作之外,還需要考慮的有很多,如資料的完整性、資料是否需要壓縮儲存,以及如何壓縮、儲存物件時使用的序列化及反序列化框架等很多複雜的問題。

 

3.1、資料的完整性

          資料的完整性即指在從檔案系統中讀取資料時需要和當初存入到檔案系統的資料保障一致,是否損壞,而不是殘缺的資料。常見的錯誤檢測門是CRC-32(迴圈冗餘檢驗),任何大小的資料輸入都會計算出一個32位的資料校驗和。


       HDFS會對寫入的所有資料計算校驗和,並在讀取時驗證校驗和。它針對每個由io.bytes.per.checksum指定的資料計算校驗和。預設情況下為512個位元組,由於CRC-32校驗和是4個位元組,所以儲存校驗和的額外開銷低於1%。

 

       hadoop提供了一個ChecksumFileSystem,這個類繼承自FileSystem類,它的主要作用就是通過使用裝飾模式為其他檔案系統加入校驗和模組。

 

3.2、壓縮

       檔案壓縮有兩大好處:減少儲存檔案所需要的磁碟空間;加速資料在網路和磁碟上的傳輸時間。常見的壓縮演算法如下:

 

壓縮格式

 工具

 演算法

 副檔名

 多檔案

 可分割性

 DEFLATE

 無

 DEFLATE

 .deflate

 不

 不

 gzip

 gzip

 DEFLATE

 .gz

 不

 不

 ZIP

 zip

 DEFLATE

 .zip

 是

 是,在檔案範圍內

 bzip2

 bzip2

 bzip2

 .bz2

 不

 是

 LZO

 lzop

 LZO

 .lzo

 不

 是

 

 

 

 

 

 

 

 

    

DEFLATE是一個標準壓縮演算法,該演算法的標準實現是zlib。由於沒有可用於生成DEFLATE檔案的常用命令列工具,因此常用gzip格式。gzip檔案格式只是在DEFLATE格式上增加了檔案頭和檔案尾。

 

既然常用的壓縮演算法挺多,但既然是壓縮演算法,肯定需要關注每個壓縮演算法的磁碟空間壓縮比,壓縮時間和解壓縮時間,下面摘自網上的一個測試。

壓縮演算法

原始檔案大小

壓縮後的檔案大小

壓縮速度

解壓縮速度

gzip

8.3GB

1.8GB

17.5MB/s

58MB/s

bzip2

8.3GB

1.1GB

2.4MB/s

9.5MB/s

LZO-bset

8.3GB

2GB

4MB/s

60.6MB/s

LZO

8.3GB

2.9GB

49.3MB/S

74.6MB/s

 

 

 

 

 

 

 

 

 

在hadoop中,codec代表一種壓縮-解壓縮演算法,一個對CompressionCodec介面的實現代表一個codec。下表列舉了hadoop的實現的codec。

壓縮格式

Hadoop compression codec

DEFLATE

org.apache.hadoop.io.compress.DefaultCodec

gzip

org.apache.hadoop.io.compress.GzipCodec

bzip2

org.apache.hadoop.io.compress.Bzip2Codec

LZO

com.hadoop.compression.lzo.LzoCodec

CompressionCodec包含兩個函式,可以輕鬆用於壓縮和解壓縮資料,分別為createOutputStream(OutputStream out)方法和createInputStream(InputStream in)方法。

3.3、壓縮與輸入分片

 

      上表中“是否可切分”這一列,表示該壓縮演算法是否支援切分(splitable),也就是說是否可以搜尋資料流的任意位置並進一步往下讀取資料。可切分壓縮格式尤其適合mapreduce(不支援也可以,不過效率慢,整體作為一個map任務的資料)。

 

      在考慮如何壓縮將有mapreduce處理的資料時,理解這些壓縮格式是否支援切分是非常重要的。


      在一個儲存在HDFS檔案系統上的且壓縮前大小為1G的檔案為例。如果HDFS塊的大小為預設64M,那麼該檔案將被儲存在16個塊中,把這個檔案作為輸入資料的mapreduce作業,如果檔案支援切分的話,那麼將建立16個資料塊,其中每個資料塊作為一個map任務的輸入;如果檔案不支援切發的話,那麼一個map任務處理16個HDFS(整體作為輸入)。

通常在hadoop中,對於巨大的、沒有儲存邊界的檔案,如日誌檔案,可以考慮如下選項:

  • 儲存未經壓縮的檔案
  • 使用支援切分的壓縮格式,如bzip2
  • 使用順序檔案(sequence File),它支援壓縮和切分
  • 使用一個Avro資料檔案,該檔案支援壓縮和切分,就想順序檔案一樣,但增加了許多程式語言都可讀寫的優勢

 

3.4、hadoop序列化

序列化:是指將結構化物件轉化為位元組流,以便在網路上傳輸或寫到磁碟上進行永久儲存。

反序列化:是指將位元組流轉向結構化物件的逆過程。

 

序列化在分散式資料處理量大領域經常出現:程式通訊和永久儲存

 

Hadoop中,各個節點的通訊是通過遠端呼叫(RPC)實現的,RPC將資料序列化成二進位制後傳送給遠端節點,遠端節點收到資料後將二進位制位元組流反序列化為原始資料。序列化在RPC應用中有著自己的特點,RPC序列化的特點是:


Hadoop使用自己的序列化格式Writable,它格式緊湊,速度快,但是很難用java以外的語言進行擴充套件和使用。因為Writable是hadoop的核心(大多數mapreduce程式都會為鍵和值使用它)。

 

hadoop提供了大多數java基本型別的writable封裝器,使其可以在底層處理序列化資料。

 

3.4.1序列化框架

       在hadoop中,提供了一個可以替換的序列化框架的API。一個序列化框架用一個Serialization(在org.apache.hadoop.io.serializer包中)實現來表示。例如WritableSerialization類是對Writable型別的Serialization實現。


Serialization物件定義了從型別到Serializer(物件到位元組流)和Deserializer(位元組流到物件)例項的對映方式。

 

將io.serizalizations屬性設定為一個由句點分割的類名列表,即可註冊Serialization實現。它的預設值是org.apache.hadoop.io.serializer.WritableSerializationg,這意味著只有Writable物件才可以在外部序列化和反序列化


雖然在hadoop中預設的序列化框架為WritableSerialization,但hadoop還是提供了java本身自帶的JavaSerialization類的框架,該類使用java Object Serialization。

 

3.4.2、arvo

apache avro是一個獨立於程式語言資料序列化系統,該專案是由hadoop之父建立的,旨在解決hadoop中Writable型別的不足:缺乏語言的可移植性。


avro可以被多種語言(c,c++,java)處理的資料格式,具有豐富的資料型別和模式,主要包括avro模式(定義資料結構)和avro物件容器檔案(儲存資料)。

3.4.3、SequenceFile

        hadoop提供了一種順序檔案型別即SequnceFile,裡面存放的其實是鍵值對資料型別,但這裡的鍵值對都可用二進位制資料來表示,因此SequenceFile對於處理二進位制資料非常合適。


 SequenceFile同樣也可以作為小檔案的容器,即key儲存檔名,value儲存檔案內容,這樣可以把許多小檔案合併到一個大檔案中,尤其適合hadoop處理大檔案。


 同樣提供了MapFile,其實就是已經排序的SequenceFile,並且加入用於搜尋鍵的索引。可以將MapFile視為java.util.Map的持久化形式。MapFile在儲存到磁碟上後,會有兩個檔案,一個資料原資料檔案,另一個是index索引檔案。

 

 



 

相關文章