大數據時代之hadoop(四):hadoop 分佈式文件系統(HDFS)

 

 

大數據時代之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索引文件。

 

 



 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章