Hadoop集羣由一個Master主節點和若干個Slave節點組成。其中,Master節點上運行NameNode和JobTracker守護進程;Slave節點上運行DataNode和TaskTracker守護進程。
Hadoop分別從三個角度將集羣中的主機劃分爲兩種角色:java
換句話說,namenode的安全機制很重要,若是丟失或者損壞了namenode,文件系統上全部的文件就將丟失。由於咱們不知道如何根據datanode塊重建文件。Hadoop提供了兩種保護機制:node
而實際上,這兩種方法在後來咱們會繼續討論,更重要的是,namenode HA的機制衆多大牛已經將其設計的很是科學了,咱們能夠參考一下這篇文章:namenode的HA原理詳解。mysql
實際上,Hadoop的文件系統遠不止HDFS一種,它整合了衆多的文件系統,首先提供了一個高層的文件系統抽象org.apache.hadoop.fs.FileSystem,該抽象類展現了一個分佈式文件系統,並有幾個具體的實現,見下表:sql
Hadoop文件系統數據庫
文件系統 | URI方案 | java實現org.apache.hadoop | 定義 |
Local | file | fs.LocalFileSystem | 支持有客戶端校檢和的本地文件系統。 |
HDFS | hdfs | hdfs.DistributedFileSystem | Hadoop的分佈式文件系統。 |
HFTP | hftp | hdfs.HftpFileSystem | 支持經過HTTP方式以只讀的方式訪問HDFS,distcp常常用在不一樣的HDFS集羣間複製數據。 |
HSFTP | hsftp | fs.HsftpFileSystem | 支持經過HTTPS方式以只讀的方式訪問HDFS。 |
HAR | har | fs.HarFileSystem | 構建在其餘文件系統上進行歸檔文件的文件系統。Hadoop歸檔文件主要來減小NameNode的內存使用。 |
KFS | kfs | fs.kfs.Kosmos.FileSystem | 相似於GFS和HDFS,用C++編寫 |
FTP | ftp | fs.ftp.FtpFileSystem | 由FTP服務器支持的文件系統 |
S3(本地) | s3n | fs.s2native.NativeS3FileSystem | 基於Amazon S3的文件系統 |
S3(基於塊) | s3 | fs.s3.NativeS3FileSystem | 基於Amazon S3的文件系統,以塊格式儲存解決了S3的5GB文件大小的限制。 |
3. 從MapReduce角度 apache
從MapReduce角度將主機劃分爲JobTracker和TaskTracker。JobTracker是做業的調度與管理者,屬於master;TaskTracker是任務的實際執行者,屬於slave。緩存
因此HDFS只是其中的一個文件系統之一安全
HDFS是Hadoop使用的標準存儲系統,是基於網絡環境下的分佈式文件系統。它是基於流數據模式訪問和處理超大文件的需求開發的,實際上,這並非什麼新穎的事情,80年代左右就已經有人這麼去實現了。存儲在HDFS上的數據文件首先進行分塊,每一個分塊建立多個副本,並存儲在集羣的不一樣節點上,Hadoop MapReduce程序能夠在全部節點上處理這些數據。HDFS上數據存儲和處理過程以下所示。服務器
Hadoop上的數據存儲和處理模型網絡
HDFS的設計聽從主從體系結構,每一個HDFS集羣都有一個名字節點(NameNode)和若干數據節點(DataNode)。HDFS存儲文件的機制是將數據文件分塊,這裏的文件塊指的是系統讀寫操做的最小文件大小,文件系統每次只能處理磁盤塊大小的整數倍數據。而後將這些數據塊按照必定的策略存放在數據節點上。NameNode節點管理文件系統的命名空間、文件、目錄操做,同時也負責肯定數據節點和文件塊的映射關係。DataNode節點負責來自客戶端的文件讀/寫請求,同時還要執行塊的建立、刪除以及來自名字節點的文件和塊的操做命令。
NameNode和DataNode在功能上的區別:
HDFS的架構如圖所示:
HDFS中客戶端讀取文件的流程以下所示:
HDFS讀取文件流程
讀取操做的具體流程以下:
1. 客戶端(client)用FileSystem的open()函數打開文件。
2. DistributedFileSystem用RPC和NameNode通訊,獲得文件的全部數據塊信息以及這些數據塊所在節點的地址信息。
3. DistributedFileSystem將獲取的數據塊信息保存在FSDataInputStream中,而後返回給客戶端,用來讀取數據。
4. 客戶端根據NameNode返回的信息,鏈接到存有數據塊的數據節點,而後調用stream的read()函數開始讀取數據。
5. DFSInputStream鏈接保存此文件第一個數據塊的最近的數據節點。
6. Data從數據節點讀到客戶端(client)。
7. 當此數據塊讀取完畢時,DFSInputStream關閉和此數據節點的鏈接,而後鏈接此文件下一個數據塊的最近的數據節點。
8. 當客戶端讀取完畢數據的時候,調用FSDataInputStream的close函數。
9. 在讀取數據的過程當中,若是客戶端在與數據節點通訊出現錯誤,則嘗試鏈接包含此數據塊的下一個數據節點。
10. 失敗的數據節點將被記錄,之後再也不鏈接。
HDFS寫入文件流程以下所示。
HDFS寫入文件流程
寫入操做的具體流程以下:
1. 客戶端調用create()來建立文件
2. DistributedFileSystem用RPC調用元數據節點,在文件系統的命名空間中建立一個新的文件。
3. 元數據節點首先肯定文件原來不存在,而且客戶端有建立文件的權限,而後建立新文件。
4. DistributedFileSystem返回DFSOutputStream,客戶端用於寫數據。
5. 客戶端開始寫入數據,DFSOutputStream將數據分紅塊,寫入data queue。
6. Data queue由Data Streamer讀取,並通知元數據節點分配數據節點,用來存儲數據塊(每塊默認複製3塊)。分配的數據節點放在一個pipeline裏。
7. Data Streamer將數據塊寫入pipeline中的第一個數據節點。第一個數據節點將數據塊發送給第二個數據節點。第二個數據節點將數據發送給第三個數據節點。
8. DFSOutputStream爲發出去的數據塊保存了ack queue,等待pipeline中的數據節點告知數據已經寫入成功。
若是數據節點在寫入的過程當中失敗:
關閉pipeline,將ack queue中的數據塊放入data queue的開始。
當前的數據塊在已經寫入的數據節點中被元數據節點賦予新的標示,則錯誤節點重啓後可以察覺其數據塊是過期的,會被刪除。
失敗的數據節點從pipeline中移除,另外的數據塊則寫入pipeline中的另外兩個數據節點。
元數據節點則被通知此數據塊是複製塊數不足,未來會再建立第三份備份。
9. 當客戶端結束寫入數據,則調用stream的close函數。此操做將全部的數據塊寫入pipeline中的數據節點,並等待ack queue返回成功。最後通知元數據節點寫入完畢。
一些補充的地方:
1. NameNode啓動後會進入一個成爲安全模式的特殊狀態。此時NameNode不會進行數據塊複製。NameNode從全部的DataNode接收心跳信號和塊狀態報告。塊狀態報告包括了某個DataNode全部的數據塊列表。每一個數據塊都有一個指定的最小副本數,當NameNode檢測確認某個數據塊的副本數達到要求的時候,該數據塊就會被認爲是副本安全的。等安全DataNode達到了必定比率,NameNode就會推出安全模式,接下來還會繼續肯定還有哪些數據的副本沒有達到指定數目。
2. Hadoop的優缺點
優勢:
缺點:
整個MapReduce做業的工做工程,以下所示:
MapReduce工做流程
1. 做業的提交
客戶端調用JobClient的runjob()方法建立一個 JobClient實例,而後調用submitJob()方法提交做業到集羣,其中主要包括如下步驟:
1)經過JobTracker的getNewJobId()請求一個新的做業ID;
2)檢查做業的輸出(好比沒有指定輸出目錄或輸出目錄已經存在,就拋出異常),以避免覆蓋原有文件內容;
3)計算做業的輸入分片,爲了高效,分片大小最好和HDFS塊的大小相同(當分片沒法計算時,好比輸入路徑不存在等緣由,就拋出異常);
4)將運行做業所需的資源(好比做業Jar文件,配置文件,計算所得的輸入分片等)複製到一個以做業ID命名的目錄中。(集羣中有多個副本可供TaskTracker訪問);
5)經過調用JobTracker的submitJob()方法告知做業準備執行;
6)JobTracker調度任務到工做節點上執行。runjob每隔1秒輪訓一次節點,看看執行進度,指導任務執行完畢。
2. 做業的初始化
1)JobTracker接收到對其submitJob()方法的調用後,就會把這個調用放入一個內部隊列中,交由做業調度器(好比先進先出調度器,容量調度器,公平調度器等)進行調度;
2)初始化主要是建立一個表示正在運行做業的對象——封裝任務和記錄信息,以便跟蹤任務的狀態和進程;
3)爲了建立任務運行列表,做業調度器首先從HDFS中獲取JobClient已計算好的輸入分片信息;
4)而後爲每一個分片建立一個MapTask,而且建立ReduceTask。(Task在此時被指定ID,請區分清楚Job的ID和Task的ID)。
3. 任務的分配
1)TaskTracker按期經過「心跳」與JobTracker進行通訊,主要是告知JobTracker自身是否還存活,以及是否已經準備好運行新的任務等;
2)JobTracker在爲TaskTracker分配一個Task前,JobTracker須要按照優先級選擇一個做業,在最高優先級的job中選擇一個task。Hadoop默認的做業調度Map Task優先級比Reduce Task高;
3)TaskTracker根據必定的策略運行必定數量的map task和reduce task。可運行的數量有TaskTracker的數量和內存大小決定
4. 任務的執行
1)TaskTracker分配到一個任務後,經過從HDFS把做業的Jar文件複製到TaskTracker所在的文件系統(Jar本地化用來啓動JVM),同時TaskTracker將應用程序所須要的所有文件從分佈式緩存複製到本地磁盤;
2)TaskTracker爲任務新建一個本地工做目錄,並把Jar文件中的內容解壓到這個文件夾中;
3)TaskTracker啓動一個新的JVM來運行每一個Task(包括MapTask和ReduceTask),這樣Client的MapReduce就不會影響TaskTracker守護進程(好比,致使崩潰或掛起等)。
子進程經過umbilical接口與父進程進行通訊,Task的子進程每隔幾秒便告知父進程它的進度,直到任務完成。
5. 進程和狀態的更新
一個做業和它的每一個任務都有一個狀態信息,包括做業或任務的運行狀態,Map和Reduce的進度,計數器值,狀態消息或描述(能夠由用戶代碼來設置)。這些狀態信息在做業期間不斷改變,它們是如何與Client通訊的呢?
任務在運行時,對其進度(即任務完成的百分比)保持追蹤。對於MapTask,任務進度是已處理輸入所佔的比例。對於ReduceTask,狀況稍微有點複雜,但系統仍然會估計已處理Reduce輸入的比例;
這些消息經過必定的時間間隔由Child JVM—>TaskTracker—>JobTracker匯聚。JobTracker將產生一個代表全部運行做業及其任務狀態的全局視圖。能夠經過Web UI查看。同時JobClient經過每秒查詢JobTracker來得到最新狀態,而且輸出到控制檯上。
Shuffle階段是指從Map的輸出開始,包括系統執行排序以及傳送Map輸出到Reduce做爲輸入的過程。Sort階段是指對Map端輸出的Key進行排序的過程。不一樣的Map可能輸出相同的Key,相同的Key必須發送到同一個Reduce端處理。Shuffle階段能夠分爲Map端的Shuffle和Reduce端的Shuffle。Shuffle階段和Sort階段的工做過程,以下所示:
一、Map端的Shuffle
Map函數開始產生輸出時,並非簡單地把數據寫到磁盤,由於頻繁的磁盤操做會致使性能嚴重降低。它的處理過程更復雜,數據首先寫到內存中的一個緩衝區,並作一些預排序,以提高效率;
每一個MapTask都有一個用來寫入輸出數據的循環內存緩衝區(默認大小爲100MB),當緩衝區中的數據量達到一個特定閾值時(默認是80%)系統將會啓動一個後臺線程把緩衝區中的內容寫到磁盤(即spill階段)。在寫磁盤過程當中,Map輸出繼續被寫到緩衝區,但若是在此期間緩衝區被填滿,那麼Map就會阻塞直到寫磁盤過程完成;
在寫磁盤前,線程首先根據數據最終要傳遞到的Reducer把數據劃分紅相應的分區(partition)。在每一個分區中,後臺線程按Key進行排序(快速排序),若是有一個Combiner(即Mini Reducer)便會在排序後的輸出上運行;
一旦內存緩衝區達到溢出寫的閾值,就會建立一個溢出寫文件,所以在MapTask完成其最後一個輸出記錄後,便會有多個溢出寫文件。在在MapTask完成前,溢出寫文件被合併成一個索引文件和數據文件(多路歸併排序)(Sort階段);
溢出寫文件歸併完畢後,Map將刪除全部的臨時溢出寫文件,並告知TaskTracker任務已完成,只要其中一個MapTask完成,ReduceTask就開始複製它的輸出(Copy階段);
Map的輸出文件放置在運行MapTask的TaskTracker的本地磁盤上,它是運行ReduceTask,TaskTracker所須要的輸入數據,可是Reduce輸出不是這樣的,它通常寫到HDFS中(Reduce階段)。
二、Reduce端的Shuffle
Copy階段:Reduce進程啓動一些數據copy線程,經過HTTP方式請求MapTask所在的TaskTracker以獲取輸出文件。
Merge階段:將Map端複製過來的數據先放入內存緩衝區中,Merge有3種形式,分別是內存到內存,內存到磁盤,磁盤到磁盤。默認狀況下第一種形式不啓用,第二種Merge方式一直在運行(spill階段)直到結束,而後啓用第三種磁盤到磁盤的Merge方式生成最終的文件。
Reduce階段:最終文件可能存在於磁盤,也可能存在於內存中,可是默認狀況下是位於磁盤中的。當Reduce的輸入文件已定,整個Shuffle就結束了,而後就是Reduce執行,把結果放到HDFS中。
一、大:一個表能夠有數十億行,上百萬列;
二、無模式:每行都有一個可排序的主鍵和任意多的列,列能夠根據須要動態的增長,同一張表中不一樣的行能夠有大相徑庭的列;
三、面向列:面向列(族)的存儲和權限控制,列(族)獨立檢索;
稀疏:空(null)列並不佔用存儲空間,表能夠設計的很是稀疏;
四、數據多版本:每一個單元中的數據能夠有多個版本,默認狀況下版本號自動分配,是單元格插入時的時間戳;
五、數據類型單一:Hbase中的數據都是字符串,沒有類型。
HBase集羣在物理組成上由一個Zookeeper集羣、一個Master主服務器、多個RegionServer從服務器組成,同時,HBse在底層依賴於HDFS集羣。總體系統架構以下所示:
HBase的物理集羣架構
HBase集羣運行依賴於Zookeeper,默認狀況下,它管理一個Zookeeper實例,做爲集羣「權威」。若是區域分配過程當中有服務器崩潰,就須要Zookeeper來協調分配。客戶端讀寫HBase中的數據時也須要先訪問Zookeeper,瞭解集羣屬性。
在底層,HBase的全部信息都保存在HDFS中,HBase是構建在HDFS上的分佈式數據庫。
HBase的存儲架構以下所示:
HBase的存儲架構
HBASE集羣種重要的角色就是其守護進程。包括運行在集羣Master節點上的HMaster進程和運行在每一個從節點RegionServer節點上的HRegionServer進程,初次以外,還包括若干Zookeeper進程。具體組件實體以下:
一、Client
HBse Client使用HBase的RPC機制與HMaster(進行管理操做)和HRegionServer(進行讀寫操做)進行通訊。
二、HMaster
HMaster是集羣Master節點的主進程,HMaster沒有單點問題,HBase中能夠啓動多個HMaster,經過Zookeper的Master Election機制保證總有一個Master運行,HMaster在功能上主要負責Table和Region的管理工做。包括:Table的增刪該查、Region分佈等。
三、HRegionServer
HRegionServer進程運行在集羣從節點上,主要負責響應用戶的IO請求,向HDFS系統中讀寫數據。其內部功能結構圖以下:
HRegionServer內部功能結構圖
從圖上能夠看出,HRegionServer管理一系列HRegion對象,每個HRegion又由多個HStore組成。HRegion對應Table中的一個Region;HStore對應Table中的一個列簇。每一個列簇就是一個存儲單元。
HStore由兩部分組成:MemStore和StoreFile。用戶寫入的數據首先會放入MemSore,MemStore滿了以後,flush成一個StoreFile.
四、Zookeeper
Zookeeper中除了存儲-ROOT表的地址和Master的地址,還會有HRegionServer的信息,使得Hmaster能夠隨時知道HRegionServer的情況。
五、Hlog
每個HRegionServer都有一個Hlog對象,用戶寫入數據時,會備份一份到HLOG中,以便出現意外好恢復。
一、Hbase中的區域
當HBase中數據記錄數不斷增多時,達到閾值後,就會從行的方向分裂成多份,每份是一個region,一個region由【startkey,endkey】表示。不一樣的region會被集羣的Master分配給相應的RegionServer進行管理。
二、HBse中兩種特殊表
運行中的HBase內部保留了2中特殊的目錄表:-ROOT- 和 .META. 。-ROOT-表包含了.META.表的全部區域列表的信息,而.META.表保存了全部用戶空間的區域列表信息,以及RegionServer的服務器地址。
HBse中兩種特殊表
Hive是創建在Hadoop之上的數據倉庫軟件工具,它提供了一系列的工具,幫助用戶對大規模的數據進行提取、轉換和加載,即ETL操做。Hive定義了簡單的類SQL查詢語言,稱爲HiveSql。從本質上講,Hive其實就是一個SQL解釋器,它可以將用戶輸入的HiveSql語句轉換成MapReduce做業在Hadoop集羣上執行。
Hive的體系結構