① hadoop中在HDFS中創建一個input目錄,然後hadoop fs -ls命令
你創建input目錄的時候是不是也用了sudo命令?這樣的話就是使用了root用戶來創建了input,所以生成專的是user/root/input,而不是用了hadoop這個用戶屬創的目錄,所以沒有生成/user/hadoop/input。hadoop的指令都不需要用sudo來使用root許可權啊,
② 用 java遍歷hadoop分布式文件系統中某個目錄下的全部文件,我的hadoop是單節點的
原因:
你訪問的是本地文件系統而非hdfs , 因為Configuration默認的是在core-default.xml中的屬性fs.default.name默認值是file:///,表示本地文件系統。在我們new Configuration();時會默認載入core-default.xml文件,所以根據這個文件的fs.default.name值使用了本地文件系統。
解決方法:
一般安裝hadoop時都是修改core-site.xml文件,這個文件設置的屬性值一般使用來覆蓋core-default.xml這個文件的,在core-site.xml文件中會設置fs.default.name值為hadoop的namenode的地址以及埠號,如hdfs://localhost:9000,即表示namenode是本機,也就是為分布式。所以我們在連接hdfs時需要指定連接的地址,也就是hadoop集群中core-site.xml中fs.default.name屬性值。所以解決方法有三種:
1)在代碼Configuration conf=new Configuration();之後手動為Configuration對象設置fs.default.name屬性值,如:conf.set("fs.default.name","hdfs:localhost:9000");
2)在代碼的classpath下創建一個文件,在文件中設置fs.default.name屬性值,再使用conf.addResource("文件路徑")將該文件添加到Configuration中;
3)直接將集群的core-site.xml添加到classpath下即可,無需手動添加到Configuration,在new Configuration時會自動載入該文件
③ HDFS和本地文件系統文件互導
初步了解一下情況,後續根據給出案例
一、從本地文件系統到HDFS
使用hdfs自帶的命令
命令:hdfs dfs -FromLocal inputPath outputPath
inputPath:本地文件目錄的路徑
outputPath:hdfs文件目錄路徑,即存儲路徑
二、從HDFS到本地文件系統
命令:hdfs dfs -ToLocal inputPath outputPath
inputPath:hdfs文件目錄
outputPath:本地文件文件目錄,即本地存儲路徑
因為Hbas和Hive都在存儲在HDFS中,所以可以通過該條命令可以把Hbase和Hive存儲在HDFS中的文件復制出來。但是經過實踐,通高簡過這種方式復制出來的Hbase文件是亂碼。Hive里的文件有時候也會亂碼,這取決於Hive數據的插入方式。
三、文件在HDFS內的移動
1、從Hbase表導出數據到HDFS
命令:hbase org.apache.hadoop.hbase.maprece.Export tableName outputPaht
例子:hbase org.apache.hadoop.hbase.maprece.Export test /user/data
test為需要從Hbase中導出的表,/user/data為hdfs上的路徑,即存儲路徑,如果最後一個參數有前綴file:// 則為本地上的文件存儲系統
2、從HDFS導入到Hbase表中,需要事先建立好表結構
命令:hbase org.apache.hadoop.hbase.maprece.Export tableName inputPaht
例子:hbase org.apache.hadoop.hbase.maprece.Import test1 /態拍temp/part-m-00000
案列:
兩個不同環境數據,數據導入
過程描述:
導出正式環境數據到hdfs中,然後從hdfs中導出到本地,本地傳到測試環境主機,然後從本地導入到hdfs中,再從hdfs中導入到hbase中。
處理過程:
1、注意事項:1、許可權問題使用hdfs:sudo -u hdfs ;
2、存放上傳路徑最好不要在root下
帆念羨 3、上傳完成後,查看是否在使用,數據已經插入。
1、sudo -u hdfs hbase org.apache.hadoop.hbase.maprece.Export ** /hbase/**_bak (導出到hdfs中的**_bak)
2、hdfs dfs -ToLocal /hbase/sw_bak /test (導出hdfs中文件到本地test,註:提前建好目錄)
3、scp -r test_bak [email protected].**:/root/test (傳送目錄到測試環境主機目錄下,註:傳到測試環境後,把文件不要放到root的目錄下,換家目錄下)
4、sudo -u hdfs hdfs dfs -FromLocal /chenzeng/text_bak /data (把sw傳到hdfs 中,注意上傳時,文件路徑要對,放在data路徑下比較好)
5、sudo -u hdfs hbase org.apache.hadoop.hbase.maprece.Import test /data/test_bak/part-m-0000 (注意上次文件)
6、在hbase shell 中查看test :count 'test' 確認是否上傳成功
優化:
truncate 『』
正式環境導入至hdfs中時,
可以直接在另一個環境的執行sudo -u hdfs hbase org.apache.hadoop.hbase.maprece.Import test hdfs://server243:8020/hbase**** 可以直接加主機和對應路徑進行put。
④ HDFS文件
Hadoop支持的文件系統由很多(見下圖),HDFS只是其中一種實現。Java抽象類 org.apache.hadoop.fs.FileSystem 定義了Hadoop中一個文件系統的客戶端介面,並且該抽象類有幾個具體實現。Hadoop一般使用URI(下圖)方案來選取合適的文件系統實例進行交互。
特別的,HDFS文件系統的操作可以使用 FsSystem shell 、客戶端(http rest api、Java api、C api等)。
FsSystem shell 的用法基本同本地shell類似,命令可參考 FsSystem shell
Hadoop是用Java寫的,通過Java Api( FileSystem 類)可以調用大部分Hadoop文件系統的交互操作。更詳細的介紹可參考 hadoop Filesystem 。
非Java開發的應用可以使用由WebHDFS協議提供的HTTP REST API,但是HTTP比原生的Java客戶端要慢,所以不到萬不得已盡量不要使用HTTP傳輸特大數據。通過HTTP來訪問HDFS有兩種方法:
兩種如圖
在第一種情況中,namenode和datanode內嵌的web服務作為WebHDFS的端節點運行(是否啟用WebHDFS可通過dfs.webhdfs.enabled設置,默認為true)。文件元數據在namenode上,文件讀寫操作首先被發往namenode,有namenode發送一個HTTP重定向至某個客戶端,指示以流的方式傳輸文件數據的目的或源datanode。
第二種方法依靠一個或多個獨立代理伺服器通過HTTP訪問HDFS。所有集群的網路通信都需要通過代理,因此客戶端從來不直接訪問namenode或datanode。使用代理後可以使用更嚴格的防火牆策略和帶寬策略。
HttpFs代理提供和WebHDFS相同的HTTP介面,這樣客戶端能夠通過webhdfs URI訪問介面。HttpFS代理啟動獨立於namenode和datanode的守護進程,使用httpfs.sh 腳本,默認在一個不同的埠上監聽(14000)。
下圖描述了
讀文件時客戶端與 HDFS 中的 namenode, datanode 之間的數據流動。
對上圖的解釋如下:
在讀取過程中, 如果 FSDataInputStream 在和一個 datanode 進行交流時出現了一個錯誤,他就去試一試下一個最接近的塊,他當然也會記住剛才發生錯誤的 datanode 以至於之後不會再在這個 datanode 上進行沒必要的嘗試。 DFSInputStream 也會在 datanode 上傳輸出的數據上核查檢查數(checknums).如果損壞的塊被發現了, DFSInputStream 就試圖從另一個擁有備份的 datanode 中去讀取備份塊中的數據。
在這個設計中一個重要的方面就是客戶端直接從 datanode 上檢索數據,並通過 namenode 指導來得到每一個塊的最佳 datanode。這種設計允許 HDFS 擴展大量的並發客戶端,因為數據傳輸只是集群上的所有 datanode 展開的。期間,namenode 僅僅只需要服務於獲取塊位置的請求(塊位置信息是存放在內存中,所以效率很高)。如果不這樣設計,隨著客戶端數據量的增長,數據服務就會很快成為一個瓶頸。
我們知道,相對於客戶端(之後就是 maprece task 了),塊的位置有以下可能性:
我們認為他們對於客戶端的帶寬遞減,距離遞增(括弧中表示距離)。示意圖如下:
如果集群中的機器都在同一個機架上,我們無需其他配置,若集群比較復雜,由於hadoop無法自動發現網路拓撲,所以需要額外配置網路拓撲。
基本讀取程序,將文件內容輸出到console
FileSystemCat
隨機讀取
展開原碼
下圖描述了寫文件時客戶端與 HDFS 中的 namenode, datanode 之間的數據流動。
對上圖的解釋如下:
如果在任何一個 datanode 在寫入數據的時候失敗了,接下來所做的一切對客戶端都是透明的:首先, pipeline 被關閉,在確認隊列中的剩下的包會被添加進數據隊列的起始位置上,以至於在失敗的節點下游的任 何節點都不會丟失任何的包。然後與 namenode 聯系後,當前在一個好的 datanode 會聯系 namenode, 給失敗節點上還未寫完的塊生成一個新的標識ID, 以至於如果這個失敗的 datanode 不久後恢復了,這個不完整的塊將會被刪除。失敗節點會從 pipeline 中移除,然後剩下兩個好的 datanode 會組成一個的新的 pipeline ,剩下的 這些塊的包(也就是剛才放在數據隊列隊首的包)會繼續寫進 pipeline 中好的 datanode 中。最後,namenode 注意到塊備份數小於規定的備份數,他就安排在另一個節點上創建完成備份,直接從已有的塊中復制就可以。然後一直到滿足了備份數( dfs.replication )。如果有多個節點的寫入失敗了,如果滿足了最小備份數的設置( dfs.namenode.repliction.min ),寫入也將會成功,然後剩下的備份會被集群非同步的執行備份,直到滿足了備份數( dfs.replication )。
創建目錄
文件壓縮有兩大好處:
Hadoop 對於壓縮格式的是自動識別。如果我們壓縮的文件有相應壓縮格式的擴展名(比如 lzo,gz,bzip2 等)。Hadoop 會根據壓縮格式的擴展名自動選擇相對應的解碼器來解壓數據,此過程完全是 Hadoop 自動處理,我們只需要確保輸入的壓縮文件有擴展名。
Hadoop中有多種壓縮格式、演算法和工具,下圖列出了常用的壓縮方法。
表中的「是否可切分」表示對應的壓縮演算法是否支持切分,也就是說是否可以搜索數據流的任意位置並進一步往下讀取數據,可切分的壓縮格式尤其適合MapRece。
所有的壓縮演算法都需要權衡空間/時間:壓縮和解壓縮速度更快,其代價通常是只能節省少量的空間。不同的壓縮工具有不同的特性:
更詳細的比較如下
1.壓縮性能比較
2.優缺點
另外使用hadoop原生(native)類庫比其他java實現有更快的壓縮和解壓縮速度。特徵比較如下:
使用容器文件格式結合壓縮演算法也能更好的提高效率。順序文件、Arvo文件、ORCFiles、Parqurt文件同時支持壓縮和切分。
壓縮舉例(Java)
壓縮
解壓縮
六、文件序列化
序列化是指將結構化數據轉換為位元組流以便在網路上傳輸或寫到磁碟進行永久存儲。反序列化獅子將位元組流轉換回結構化對象的逆過程。
序列化用於分布式數據處理的兩大領域:進程間通信和永久存儲。
對序列化的要求時是格式緊湊(高效使用存儲空間)、快速(讀寫效率高)、可擴展(可以透明地讀取老格式數據)且可以互操作(可以使用不同的語言讀寫數據)。
Hadoop使用的是自己的序列化格式 Writable ,它絕對緊湊、速度快,但不太容易用java以外的語言進行擴展或使用。
當然,用戶也可以使用其他序列化框架或者自定義序列化方式,如 Avro 框架。
Hadoop內部還使用了 Apache Thrift 和 Protocal Buffers 來實現RPC和數據交換。
⑤ Hadoop系列之HDFS架構
本篇文章翻譯了Hadoop系列下的 HDFS Architecture ,原文最初經過筆者翻譯後大概有6000字,之後筆者對內容進行了精簡化壓縮,從而使筆者自己和其他讀者們閱讀本文時能夠更加高效快速的完成對Hadoop的學習或復習。本文主要介紹了Hadoop的整體架構,包括但不限於節點概念、命名空間、數據容錯機制、數據管理方式、簡單的腳本命令和垃圾回收概念。
PS:筆者新手一枚,如果看出哪裡存在問題,歡迎下方留言!
Hadoop Distributed File System(HDFS)是高容錯、高吞吐量、用於處理海量數據的分布式文件系統。
HDFS一般由成百上千的機器組成,每個機器存儲整個數據集的一部分數據,機器故障的快速發現與恢復是HDFS的核心目標。
HDFS對介面的核心目標是高吞吐量而非低延遲。
HDFS支持海量數據集合,一個集群一般能夠支持千萬以上數量級的文件。
HDFS應用需要對文件寫一次讀多次的介面模型,文件變更只支持尾部添加和截斷。
HDFS的海量數據與一致性介面特點,使得遷移計算以適應文件內容要比遷移數據從而支持計算更加高效。
HDFS支持跨平台使用。
HDFS使用主從架構。一個HDFS集群由一個NameNode、一個主伺服器(用於管理系統命名空間和控制客戶端文件介面)、大量的DataNode(一般一個節點一個,用於管理該節點數據存儲)。HDFS對外暴露了文件系統命名空間並允許在文件中存儲用戶數據。一個文件被分成一個或多個塊,這些塊存儲在一組DataNode中。NameNode執行文件系統命名空間的打開關閉重命名等命令並記錄著塊和DataNode之間的映射。DataNode用於處理客戶端的讀寫請求和塊的相關操作。NameNode和DataNode一般運行在GNU/Linux操作系統上,HDFS使用Java語言開發的,因此NameNode和DataNode可以運行在任何支持Java的機器上,再加上Java語言的高度可移植性,使得HDFS可以發布在各種各樣的機器上。一個HDFS集群中運行一個NameNode,其他機器每個運行一個(也可以多個,非常少見)DataNode。NameNode簡化了系統的架構,只用於存儲所有HDFS元數據,用戶數據不會進入該節點。下圖為HDFS架構圖:
HDFS支持傳統的分層文件管理,用戶或者應用能夠在目錄下創建目錄或者文件。文件系統命名空間和其他文件系統是相似的,支持創建、刪除、移動和重命名文件。HDFS支持用戶數量限制和訪問許可權控制,不支持軟硬鏈接,用戶可以自己實現軟硬鏈接。NameNode控制該命名空間,命名空間任何變動幾乎都要記錄到NameNode中。應用可以在HDFS中對文件聲明復制次數,這個次數叫做復制系數,會被記錄到NameNode中。
HDFS將每個文件存儲為一個或多個塊,並為文件設置了塊的大小和復制系數從而支持文件容錯。一個文件所有的塊(除了最後一個塊)大小相同,後來支持了可變長度的塊。復制系數在創建文件時賦值,後續可以更改。文件在任何時候只能有一個writer。NameNode負責塊復制,它周期性收到每個數據節點的心跳和塊報告,心跳錶示數據節點的正常運作,塊報告包含了這個DataNode的所有塊。
副本存儲方案對於HDFS的穩定性和性能至關重要。為了提升數據可靠性、靈活性和充分利用網路帶寬,HDFS引入了機架感知的副本存儲策略,該策略只是副本存儲策略的第一步,為後續優化打下基礎。大型HDFS集群一般運行於橫跨許多支架的計算機集群中,一般情況下同一支架中兩個節點數據傳輸快於不同支架。一種簡單的方法是將副本存放在單獨的機架上,從而防止丟失數據並提高帶寬,但是增加了數據寫入的負擔。一般情況下,復制系數是3,HDFS存儲策略是將第一份副本存儲到本地機器或者同一機架下一個隨機DataNode,另外兩份副本存儲到同一個遠程機架的不同DataNode。NameNode不允許同一DataNode存儲相同副本多次。在機架感知的策略基礎上,後續支持了 存儲類型和機架感知相結合的策略 ,簡單來說就是在機架感知基礎上判斷DataNode是否支持該類型的文件,不支持則尋找下一個。
HDFS讀取數據使用就近原則,首先尋找相同機架上是否存在副本,其次本地數據中心,最後遠程數據中心。
啟動時,NameNode進入安全模式,該模式下不會發生數據塊復制,NameNode接收來自DataNode的心跳和塊報告,每個塊都有一個最小副本數量n,數據塊在NameNode接受到該塊n次後,認為這個數據塊完成安全復制。當完成安全復制的數據塊比例達到一個可配的百分比值並再過30s後,NameNode退出安全模式,最後判斷是否仍然存在未達到最小復制次數的數據塊,並對這些塊進行復制操作。
NameNode使用名為EditLog的事務日誌持續記錄文件系統元數據的每一次改動(如創建文件、改變復制系數),使用名為FsImage的文件存儲全部的文件系統命名空間(包括塊到文件的映射關系和文件系統的相關屬性),EditLog和FsImage都存儲在NameNode本地文件系統中。NameNode在內存中保存著元數據和塊映射的快照,當NameNode啟動後或者某個配置項達到閾值時,會從磁碟中讀取EditLog和FsImage,通過EditLog新的記錄更新內存中的FsImage,再講新版本的FsImage刷新到磁碟中,然後截斷EditLog中已經處理的記錄,這個過程就是一個檢查點。檢查點的目的是確保文件系統通過在內存中使用元數據的快照從而持續的觀察元數據的變更並將快照信息存儲到磁碟FsImage中。檢查點通過下面兩個配置參數出發,時間周期(dfs.namenode.checkpoint.period)和文件系統事務數量(dfs.namenode.checkpoint.txns),二者同時配置時,滿足任意一個條件就會觸發檢查點。
所有的HDFS網路協議都是基於TCP/IP的,客戶端建立一個到NameNode機器的可配置的TCP埠,用於二者之間的交互。DataNode使用DataNode協議和NameNode交互,RPC包裝了客戶端協議和DataNode協議,通過設計,NameNode不會發起RPC,只負責響應來自客戶端或者DataNode的RPC請求。
HDFS的核心目標是即使在失敗或者錯誤情況下依然能夠保證數據可靠性,三種常見失敗情況包括NameNode故障、DataNode故障和network partitions。
網路分區可能會導致部分DataNode市區和NameNode的連接,NameNode通過心跳包判斷並將失去連接的DataNode標記為掛掉狀態,於是所有注冊到掛掉DataNode的數據都不可用了,可能會導致部分數據塊的復制數量低於了原本配置的復制系數。NameNode不斷地追蹤哪些需要復制的塊並在必要時候進行復制,觸發條件包含多種情況:DataNode不可用、復制亂碼、硬體磁碟故障或者認為增大負值系數。為了避免DataNode的狀態不穩定導致的復制風暴,標記DataNode掛掉的超時時間設置比較長(默認10min),用戶可以設置更短的時間間隔來標記DataNode為陳舊狀態從而避免在對讀寫性能要求高的請求上使用這些陳舊節點。
HDFS架構兼容數據各種重新平衡方案,一種方案可以在某個DataNode的空閑空間小於某個閾值時將數據移動到另一個DataNode上;在某個特殊文件突然有高的讀取需求時,一種方式是積極創建額外副本並且平衡集群中的其他數據。這些類型的平衡方案暫時還未實現(不太清楚現有方案是什麼...)。
存儲設備、網路或者軟體的問題都可能導致從DataNode獲取的數據發生亂碼,HDFS客戶端實現了對文件內容的校驗,客戶端在創建文件時,會計算文件中每個塊的校驗值並存儲到命名空間,當客戶端取回數據後會使用校驗值對每個塊進行校驗,如果存在問題,客戶端就會去另一個DataNode獲取這個塊的副本。
FsImage和EditLog是HDFS的核心數據結構,他們的錯誤會導致整個HDFS掛掉,因此,NameNode應該支持時刻維持FsImage和EditLog的多分復制文件,它們的任何改變所有文件應該同步更新。另一個選擇是使用 shared storage on NFS 或者 distributed edit log 支持多個NameNode,官方推薦 distributed edit log 。
快照能夠存儲某一特殊時刻的數據副本,從而支持HDFS在發生錯誤時會滾到上一個穩定版本。
HDFS的應用場景是大的數據集下,且數據只需要寫一次但是要讀取一到多次並且支持流速讀取數據。一般情況下一個塊大小為128MB,因此一個文件被切割成128MB的大塊,且每個快可能分布在不同的DataNode。
當客戶端在復制系數是3的條件下寫數據時,NameNode通過目標選擇演算法收到副本要寫入的DataNode的集合,第1個DataNode開始一部分一部分的獲取數據,把每個部分存儲到本地並轉發給第2個DataNode,第2個DataNode同樣的把每個部分存儲到本地並轉發給第3個DataNode,第3個DataNode將數據存儲到本地,這就是管道復制。
HDFS提供了多種訪問方式,比如 FileSystem Java API 、 C language wrapper for this Java API 和 REST API ,而且還支持瀏覽器直接瀏覽。通過使用 NFS gateway ,客戶端可以在本地文件系統上安裝HDFS。
HDFS使用目錄和文件的方式管理數據,並提供了叫做 FS shell 的命令行介面,下面有一些簡單的命令:
DFSAdmin命令集合用於管理HDFS集群,這些命令只有集群管理員可以使用,下面有一些簡單的命令:
正常的HDFS安裝都會配置一個web服務,通過可配的TCP埠對外暴露命名空間,從而使得用戶可以通過web瀏覽器查看文件內容。
如果垃圾回收配置打開,通過FS shell移除的文件不會立刻刪除,而是會移動到一個垃圾文件專用的目錄(/user/<username>/.Trash),類似回收站,只要文件還存在於那個目錄下,則隨時可以被回復。絕大多數最近刪除的文件都被移動到了垃圾目錄(/user/<username>/.Trash/Current),並且HDFS每個一段時間在這個目錄下創建一個檢查點用於刪除已經過期的舊的檢查點,詳情見 expunge command of FS shell 。在垃圾目錄中的文件過期後,NameNode會刪除這個文件,文件刪除會引起這個文件的所有塊的空間空閑,需要注意的是在文件被刪除之後和HDFS的可用空間變多之間會有一些時間延遲(個人認為是垃圾回收機制佔用的時間)。下面是一些簡單的理解刪除文件的例子:
當文件復制系數減小時,NameNode會選擇多餘的需要刪除的副本,在收到心跳包時將刪除信息發送給DataNode。和上面一樣,這個刪除操作也是需要一些時間後,才能在集群上展現空閑空間的增加。
HDFS Architecture
⑥ 第三章 大數據存儲
一,HDFS的基本特徵與構架
1.基本特徵
(1)大規模數據分布存儲能力:以分布式存儲能力和良好的可擴展性。(基於大量分布節點上的本地文件系統,構建一個邏輯上具有巨大容量的分布式文件系統,並且整個文件系統的容量可隨集群中節點的增加而線性擴展)
(2)高並發訪問能力:提供很高的數據訪問寬頻(高數據吞吐率),並且可以把帶寬的大小等比例擴展到集群中的全部節點上
(3)強大的容錯能力:(設計理念中硬體故障被視作常態)保證在經常有節點發生硬體故障的情況下正確檢測硬體故障,並且能自動從故障中快速恢復,確保數據不丟失(採用多副本數據塊形式存儲)
(4)順序式文件訪問:(大數據批處理都是大量簡單數據記錄的順序處理)對順序讀進行了優化,支持大量數據的快速順序讀出,代價是對於隨機的訪問負載較高
(5)簡單的一致性模型(一次寫多次讀):支持大量數據的一次寫入,多次讀取;不支持已寫入數據的更新操作,但允許在文件尾部添加新的數據
(6)數據塊存儲模式:默認的塊大小是64MB。好處:減少元數據的數量,允許這些數據塊通過隨機方式選擇節點,分布存儲在不同地方
2.基本框架與工作過程
(1)基本組成結構與文件訪問過程
[1]HDFS;一個建立在一組分布式伺服器節點的本地文件系統之上的分布式文件系統(採用經典主-從結構)
[2]主控節點NameNode:
1)是一個主伺服器,用來管理整個文件系統的命名空間和元數據,以及處理來自外界的文件訪問請求
2)保存了文件系統的三中元數據
命名空間:整個分布式文件系統的目錄結構
數據塊與文件名的映射表
每個數據塊副本的位置信息,每一個數據塊默認有3個副本
[3]從節點DataNode:
1)用來實際存儲和管理文件的數據塊
2)為了防止數據丟失,每個數據塊默認有3個副本,且3個副本會分別復制在不同節點上,以避免一個節點失效造成一個數據塊的徹底丟失
[4]程序訪問文件時,實際文件數據流並不會通過NameNode傳送,而是從NameNode獲得所需訪問數據塊的存儲位置信息後,直接去訪問對應的DataNode獲取數據
[5]設計好處:
1)可以允許一個文件的數據能同時在不同DataNode上並發訪問,提高數據訪問的速度
2)減少NameNode的負擔,避免使NameNode成為數據訪問瓶頸
[6]基本訪問過程:
1)首先,用戶的應用程序通過HDFS的客戶端程序將文件名發送至NameNode
2)NameNode接收到文件名之後,在HDFS目錄中檢索文件名對應的數據塊,再根據數據塊信息找到保存數據塊的DataNode地址,講這些地址回送到客戶端
3)客戶端接收到這些DataNode地址之後,與這些DataNode並行的進行數據傳輸操作,同時將操作結果的相關日誌提交到NameNode
2.數據塊
(1)為了提高硬碟的效率,文件系統中最小的數據讀寫單元是數據塊
(2)HDFS數據塊的默認大小是64MB,實際部署中,可能會更多
(3)將數據塊設置大的原因是減少定址開銷的時間
(4)當應用發起數據傳輸請求:
[1]NameNode首先檢索文件對應的數據塊信息,找到數據塊對應的DataNode
[2]DataNode根據數據塊信息在自身的存儲中尋找相應的文件,進而與應用程序之間交換數據
[3]因為檢索過程是但進行,所以要增加數據塊大小,這樣就可以減少定址的頻度和時間開銷
3.命名空間
(1)文件命名遵循「目錄/子目錄/文件」格式
(2)通過命令行或者是API可以創建目錄,並且將文件保存在目錄中。可以對文件進行創建,刪除,重命名操作
(3)命令空間由NameNode管理。所有對命名空間的改動都會被記錄
(4)允許用戶配置文件在HDFS上保存的副本數量,保存的副本數稱作「副本因子」
4.通信協議
(1)採用TCP協議作為底層的支撐協議
(2)應用協議
[1]應用可以向NameNode主動發起TCP連接
[2]應用和NameNode交互協議稱為Client協議
[3]NameNode和DataNode交互的協議稱為DataNode協議
(3)用戶和DataNode的交互是通過發起遠程調用(RPC),並由NameNode響應來完成的。另外,NameNode不會主動發起遠程過程調用請求
5.客戶端:是用戶和HDFS通信最常見的渠道,部署的HDFS都會提供客戶端
二,HDFS可靠性設計
1.HDFS數據塊多副本存儲設計
(1)採用了在系統中保存多個副本的方式保存數據,且同一個數據塊的多個副本會存放在不同節點上
(2)優點:
[1]採用多副本,可以讓客戶從不同數據塊中讀取數據,加快傳輸速度
[2]HDFS的DataNode之間通過網路傳輸數據,如果採用多個副本可以判斷數據傳輸是否出錯
[3]多副本可以保證某個DataNode失效的情況下,不會丟失數據
2.可靠性的設計實現
(1)安全模式:
[1]HDFS啟動時,NameNode進入安全模式
[2]處於安全模式的NameNode不能做任何文本操作,甚至內部的副本創建不允許
[3]NameNode需要和各個DataNode通信,獲得其中保存的數據塊信息,並對數據塊信息進行檢查
[4]只有通過了NameNode檢查,一個數據塊被認為安全。當被認為安全的數據塊所佔比例達到某個閾值,NameNode退出
(2)SecondaryNmaeNode
[1]使用它來備份NameNode元數據,以便在其失效時能從中恢復出其上的元數據
[2]它充當NameNode的一個副本,本身並不處理任何請求。
[3]作用:周期性保存NameNode的元數據
(3)心跳包和副本重新創建
[1]心跳包:位於HDFS核心的NameNode,通過周期性的活動檢查DataNode的活動
[2]檢測到DataNode失效,保存在其上的數據不可用。則其上保存的副本需要重新創建這個副本,放到另外可用的地方
(4)數據一致性
[1]採用了數據校驗和機制
[2]創建文件時,HDFS會為這個文件生成一個校驗和,校驗和文件和文件本身保存在同一空間上,
[3]傳輸數據時會將數據與校驗和一起傳輸,應用收到數據後可以進行校驗
(5)租約
[1]防止同一個文件被多個人寫入數據
[2]NameNode保證同一個文件只會發放一個允許的租約,可以有效防止出現多人寫入的情況
(6)回滾
三,HDFS文件存儲組織與讀寫
1.文件數據的存儲組織
(1)NameNode目錄結構
[1]藉助本地文件系統來保存數據,保存文件夾位置由配置選項({dfs.name.dir}/{/tmp/dfs/name})決定
[2]在NameNode的${dfs.name.dir}之下有3個文件夾和1個文件:
1)current目錄:
文件VERSION:保存了當前運行的HDFS版本信息
FsImages:是整個系統的空間鏡像文件
Edit:EditLog編輯文件
Fstime:上一次檢查點時間
2)previous.checkpoint目錄:和上一個一致,但是保存的是上一次檢查點的內容
3)image目錄:舊版本的FsImage存儲位置
4)in_use.look:NameNode鎖,只在NameNode有效(啟動並且能和DataNode正常交互)時存在。
(2)DataNode目錄結構
[1]藉助本地文件系統來保存數據。保存文件夾位置由配置選項{dfs.data.dir}決定
[2]在其之下有4個子目錄和2個文件
1)current目錄:已經成功寫入的數據塊,以及一些系統需要的文件
a)文件VERSION:保存了當前運行的HDFS版本信息
b)subdirXX:當同一目錄下文件超過一定限制,新建一個目錄,保存多出來的數據塊和元數據
2)tmp目錄和blockBeingWritten目錄:正在寫入的數據塊,是HDFS系統內部副本創建時引發的寫入操作對應的數據塊
3)detach目錄:用於DataNode升級
4)Storage目錄:防止版本不同帶來風險
5)in_user.lock文件:DataNode鎖。只有在DataNode有效時存在。
(3)CheckPointNode目錄結構:和上一個基本一致
2.數據的讀寫過程
(1)數據讀取過程
[1]首先,客戶端調用FileSystem實例的open方法,獲得這個文件對應的輸入流,在HDFS中就是DFSInputStream
[2]構造第一步的輸入流時,通過RPC遠程調用NameNode可以獲得NameNode中此文件對應的數據塊保存位置,包括這個文件副本的保存位置(註:在輸入流中會按照網路拓撲結構,根據與客戶端距離對DataNode進行簡單排序)
[3]-[4]獲得此輸入流後,客戶端調用READ方法讀取數據。輸入流選擇最近的DFSInputStream會根據前面的排序結果,選擇最近的DataNode建立連接並讀取數據。
[5]如果已達到數據塊末端,關閉這個DataNode的連接,然後重新查找下一個數據塊
[6]客戶端調用close,關閉輸入流DFSInputStream
(2)數據輸入過程
[1]-[2]:客戶端調用FileSystem實例的create方法,創建文件。檢查後,在NameNode添加文件信息,創建結束之後,HDFS會返回一個輸出流DFSDataOutputStream給客戶端
[3]調用輸出流的write方法向HDFS中對應的文件寫入數據。
數據首先會被分包,這些分包會寫入一個輸出流的內部隊列Data隊列中,接收完整數據分包,輸出流回想NameNode申請保存文件和副本數據塊的若干個DataNode
[4]DFSDataOutputStream會(根據網路拓撲結構排序)將數據傳輸給距離上最短的DataNode,這個節點接收到數據包後傳給下一個。數據在各節點之間通過管道流通,減少傳輸開銷
[5]數據節點位於不同機器上,數據需要通過網路發送。(為保證數據節點數據正確,接收到數據的節點要向發送者發送確認包)
[6]執行3-5知道數據全部寫完,DFSDataInputStream繼續等待知道所有數據寫入完畢並確認,調用complete方法通知NameNode文件寫入完成
[7]NameNode接收到complete消息之後,等待相應數量的副本寫入完畢後,告知客戶端
傳輸過程,當某個DataNode失效,HDFS執行:
1)關閉數據傳輸的管道
2)將等待ACK隊列的數據放到Data隊列頭部
3)更新正常DataNode中所有數據塊版本。當失效的DataNode重啟,之前的數據塊會因為版本不對被清除
4)在傳輸管道中刪除失效的DataNode,重新建立管道並發送數據包
4.HDFS文件系統操作命令
(1)HDFS啟動與關閉
[1]啟動過程:
1)進入到NameNode對應節點的Hadoop安裝目錄
2)執行啟動腳本:bin/start-dfs.sh
[2]關閉過程:bin/stop-dfs.sh
(2)文件操作命令格式與注意事項
[1]基本命令格式:
1)bin/hadoop dfs-cmd <args> args-> scheme://authority/path
2)args參數基本格式前面是scheme,authority是機器地址和對應埠
a)本地文件,scheme是file
b)HDFS上文件,scheme是hdfs
(3)文件操作基本格式
[1]hadoop dfs-cat URL [URL ...]
[2]作用:將參數所指示文件內容輸出到stdout
⑦ hdfs的啟動流程
整理HDFS整個啟動的詳細過程
Namenode保存文件系統元數據鏡像,namenode在內存及磁碟(fsimage和editslog)上分別存在一份元數據鏡像文件,內存中元數據鏡像保證了hdfs文件系統文件訪問效率,磁碟上的元數據鏡像保證了hdfs文件系統的安全性。
namenode在磁碟上的兩類文件組成:
fsimage文件:保存文件系統至上次checkpoint為止目錄和文件元數據。
edits文件:保存文件系統從上次checkpoint起對hdfs的所有操作記錄日誌信息。
fsimage和editlog文件可以在本地文件系統看到
首次安裝格式化(format)主要作用是在本地文件系統生成fsimage文件。
1、首此啟動hdfs過程:
啟動namenode:
讀取fsimage生成內存中元數據鏡像。
啟動datanode:
向namenode注冊;
向namenode發送blockreport。
啟動成功後,client可以對HDFS進行目錄創建、文件上傳、下載、查看、重命名等操作,更改namespace的操作將被記錄在edits文件中。
2、之後啟動HDFS文件系統過程:
啟動namenode:
讀取fsimage元數據鏡像文件,載入到內存中。
讀取editlog日誌文件,載入到內存中,使當前內存中元數據信息與上次關閉系統時保持一致。然後在磁碟上生成一份同內存中元數據鏡像相同的fsimage文件,同時生成一個新的null的editlog文件用於記錄以後的hdfs文件系統的更改。
啟動datanode:
向namenode注冊;
向namenode發送blockreport。
啟動成功後,client可以對HDFS進行目錄創建、文件上傳、下載、查看、重命名等操作,更改namespace的操作將被記錄在editlog文件中。
3、SecondaryNameNode
輔助namenode,不能代替namenode。
SecondaryNameNode的主要作用是用於合並fsimage和editlog文件。在沒有SecondaryNameNode守護進程的情況下,從namenode啟動開始至namenode關閉期間所有的HDFS更改操作都將記錄到editlog文件,這樣會造成巨大的editlog文件,所帶來的直接危害就是下次啟動namenode過程會非常漫長。
在啟動SecondaryNameNode守護進程後,每當滿足一定的觸發條件(每3600s、文件數量增加100w等),SecondaryNameNode都會拷貝namenode的fsimage和editlog文件到自己的目錄下,首先將fsimage載入到內存中,然後載入editlog文件到內存中合並fsimage和editlog文件為一個新的fsimage文件,然後將新的fsimage文件拷貝回namenode目錄下。並且聲稱新的editlog文件用於記錄DFS的更改。
4、安全模式
在啟動namenode至所有datanode啟動完成前的階段成為安全模式。在安全模式下,client只能讀取部分HDFS文件信息,不允許client對HDFS的任何更改操作,比如創建目錄、上傳文件、刪除文件、重命名文件等。
namenode推出安全模式條件需要滿足以下條件:
datanodes blocks/total blocks >= 99.999% + 30s(緩沖時間) 此時安全模式才會推出
Secondary namenode工作流程:
1)secondary通知namenode切換edits文件
2)secondary通過http請求從namenode獲得fsimage和edits文件
3)secondary將fsimage載入內存,然後開始合並edits
4)secondary將新的fsimage發回給namenode
5)namenode用新的fsimage替換舊的fsimage