1.什麼是分佈式文件系統?
管理網絡中跨多臺計算機存儲的文件系統稱爲分佈式文件系統。
2.爲什麼需要分佈式文件系統了?
原因很簡單,當數據集的大小超過一臺獨立物理計算機的存儲能力時候,就有必要對它進行分區(partition)並存儲到若干臺單獨計算機上。
3.分佈式系統比傳統的文件的系統更加複雜
因爲分佈式文件系統架構在網絡之上,因此分佈式系統引入了網絡編程的複雜性,所以分佈式文件系統比普通文件系統更加複雜。
4.Hadoop的文件系統
很多童鞋會把hdfs等價於hadoop的文件系統,其實hadoop是一個綜合文件系統抽象,而hdfs是hadoop旗艦級文件系統,hadoop除了hdfs還能集成其他文件系統。Hadoop的這個特點充分體現了hadoop的優良的可擴展性。
在hadoop裏,hadoop定義了一個抽象的文件系統的概念,具體就是hadoop裏面定義了一個java的抽象類:org.apache.hadoop.fs.FileSystm,這個抽象類用來定義hadoop中的一個文件系統接口,只要某個文件系統實現了這個接口,那麼它就可以作爲hadoop支持的文件系統。下面是目前實現了hadoop抽象文件類的文件系統,如下表所示:
文件系統 | 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裏有一個文件系統概念,例如上面的FileSystem抽象類,它是位於hadoop的Common項目裏,主要是定義一組分佈式文件系統和通用的I/O組件和接口,hadoop的文件系統準確的應該稱作hadoop I/O。而HDFS是實現該文件接口的hadoop自帶的分佈式文件項目,hdfs是對hadoop I/O接口的實現。
下面我給大家展示一張表,這樣大家對hadoop的FileSystem裏的相關API操作就比較清晰了,表如下所示:
Hadoop的FileSystem | Java操作 | Linux操作 | 描述 |
URL.openSteam FileSystem.open FileSystem.create FileSystem.append | URL.openStream | open | 打開一個文件 |
FSDataInputStream.read | InputSteam.read | read | 讀取文件中的數據 |
FSDataOutputStream.write | OutputSteam.write | write | 向文件寫入數據 |
FSDataInputStream.close FSDataOutputStream.close | InputSteam.close OutputSteam.close | close | 關閉一個文件 |
FSDataInputStream.seek | RandomAccessFile.seek | lseek | 改變文件讀寫位置 |
FileSystem.getFileStatus FileSystem.get* | File.get* | stat | 獲取文件/目錄的屬性 |
FileSystem.set* | File.set* | Chmod等 | 改變文件的屬性 |
FileSystem.createNewFile | File.createNewFile | create | 創建一個文件 |
FileSystem.delete | File.delete | remove | 從文件系統中刪除一個文件 |
FileSystem.rename | File.renameTo | rename | 更改文件/目錄名 |
FileSystem.mkdirs | File.mkdir | mkdir | 在給定目錄下創建一個子目錄 |
FileSystem.delete | File.delete | rmdir | 從一個目錄中刪除一個空的子目錄 |
FileSystem.listStatus | File.list | readdir | 讀取一個目錄下的項目 |
FileSystem.getWorkingDirectory | getcwd/getwd | 返回當前工作目錄 | |
FileSystem.setWorkingDirectory | chdir | 更改當前工作目錄 |
有了這張表,大家對FileSystem的理解應該會清晰多了吧。
大家從對照表裏會發現,hadoop的FileSystem裏有兩個類:FSDataInputStream和FSDataOutputStream類,它們相當於java I/O裏的InputStream和Outputsteam,而事實上這兩個類是繼承java.io.DataInputStream和java.io.DataOutputStream。
至於關於hadoop I/O本文今天不做介紹,以後也許會專門寫篇文章講講我自己的理解,不過爲了給大家一個清晰的印象,我在博客園裏找到了兩篇文章,有興趣的童鞋可以好好看看看,連接如下:
http://www.cnblogs.com/xuqiang/archive/2011/06/03/2042526.html
http://www.cnblogs.com/xia520pi/archive/2012/05/28/2520813.html
5.數據的完整性
數據完整性也就是檢測數據是否損壞的技術。Hadoop用戶肯定都希望系統在存儲和處理數據時候,數據不會有任何的丟失或損壞,儘管磁盤或網絡上的每個I/O操作都不太可能將錯誤引入到自己正在讀寫的數據裏,但是如果系統需要處理的數據量大到hadoop能夠處理的極限,數據被損壞的概率就很高了。Hadoop引入了數據完整性校驗的功能,下面我將其原理描述如下:
檢測數據是否損壞的措施是,在數據第一次引入系統時候計算校驗和(checksum),並在數據通過一個不可靠的通道時候進行傳輸時再次計算校驗和,這樣就能發現數據是否損壞了,如果兩次計算的校驗和不匹配,你就認爲數據已經損壞了,但是該技術不能修復數據,它只能檢測出錯誤。常用的錯誤檢測碼是CRC-32(循環冗餘校驗),任何大小的數據輸入均計算得到一個32位的整數校驗和。
6.壓縮與輸入分片
文件壓縮有兩大好處:一是可以減少存儲文件所需要的磁盤空間,二是可以加速數據在網絡和磁盤上的傳輸。對於處理海量數據的hadoop而言,這兩個好處就變得相當重要了,所以理解hadoop的壓縮是很有必要的,下表列出了hadoop支持的壓縮格式,如下表:
壓縮格式 | 工具 | 算法 | 文件擴展名 | 多文件 | 可分割性 |
DEFLATE | 無 | DEFLATE | .deflate | 不 | 不 |
gzip | gzip | DEFLATE | .gz | 不 | 不 |
ZIP | zip | DEFLATE | .zip | 是 | 是,在文件範圍內 |
bzip2 | bzip2 | bzip2 | .bz2 | 不 | 是 |
LZO | lzop | LZO | .lzo | 不 | 是 |
在hadoop對於壓縮有兩個指標很重要一個是壓縮率還有就是壓縮速度,下表列出一些壓縮格式在此方面表現的性能,如下所示:
壓縮算法 | 原始文件大小 | 壓縮後的文件大小 | 壓縮速度 | 解壓縮速度 |
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支持壓縮裏,是否支持切分(splitting)文件的特性也是相當重要的,下面我將講述切分的問題,也就是我標題寫的輸入分片的問題:
壓縮格式是否可以切分的特性是針對mapreduce處理數據而言的,比如我們有一個壓縮爲1GB的文件,如果hdfs塊大小設置爲(hdfs塊我的文章裏沒有講解,不理解的童鞋可以先查查百度,以後我在寫hdfs時候會重點講這個的)64mb,那麼這個文件將存儲在16個塊裏,如果把這個文件作爲mapreduce作業的輸入數據,mapreduce會根據這16個數據塊,產生16個map操作,每個塊都是其中一個map操作的輸入,那麼mapreduce執行效率會非常的高,但是這個前提就是該壓縮格式要支持切分。假如壓縮格式不支持切分的話,那麼mapreduce也是可以做出正確處理,這時候它會將16個數據塊放到一個map任務裏面,這時候map任務數少了,作業粒度也變大了,那麼執行效率就會大大下降。
由於本人知識還是有限,關於壓縮和切入分片的問題我就講述到這裏,下面提供一篇相關的文章,有興趣的童鞋可以看看,鏈接如下:
http://www.cnblogs.com/ggjucheng/archive/2012/04/22/2465580.html
7.hadoop序列化
我們先看兩個定義:
序列化:是指將結構化對象轉化爲字節流,以便在網絡上傳輸或寫到磁盤上進行永久存儲。
反序列化:是指將字節流轉向結構化對象的逆過程。
序列化在分佈式數據處理量大領域經常出現:進程通信和永久存儲。
Hadoop中,各個節點的通信是通過遠程調用(RPC)實現的,RPC將數據序列化成二進制後發送給遠程節點,遠程節點收到數據後將二進制字節流反序列化爲原始數據。序列化在RPC應用中有着自己的特點,RPC序列化的特點是:
緊湊:緊湊的格式能讓我們能充分利用網絡帶寬,而帶寬是數據中心最稀缺的資源;
快速:進程通信形成了分佈式系統的骨架,所以需要儘量減少序列化和反序列化的性能開銷,這是基本的
可擴展:協議爲了滿足新的需求變化,所以控制客戶端和服務器過程中,需要直接引進相應的協議,這些事新協議,原序列化方式能支持心得協議報文
互操作:能支持不同語言寫的客戶端和服務端進行交互
在hadoop裏面有自己定義的序列化格式:writable,它是hadoop的核心之一。
Writable是一個接口,要實現hadoop的序列化就得實現該接口。因爲時間原因,序列化我也不展開了,我下面也推薦一篇文章,裏面講述了hadoop的序列化,雖然講的簡單點,而且不全面,但是看完後對hadoop序列化的具體實現會有個初步的瞭解,鏈接如下:
http://blog.csdn.net/a15039096218/article/details/7591072