HDFS 體系架構
1,HDFS 是一個主/從(Master/Slave)體系架構,由於分布式存儲的性質,集群擁有兩類節點 NameNode 和 DataNode。兩者是通過rpc通信的
2,NameNode(名字節點):系統中通常只有一個,中心服務器的角色,管理存儲和檢索多個 DataNode 的實際數據所需的所有元數據。
3,DataNode(數據節點):系統中通常有多個,是文件系統中真正存儲數據的地方,在
4,NameNode 統一調度下進行數據塊的創建、刪除和復制。
HDFS 讀寫過程
1,讀過程
首先 Client 通過 File System 的 Open 函數打開文件,Distributed File System 用 RPC調用 NameNode 節點,得到文件的數據塊信息。對於每一個數據塊,NameNode 節點返回保存數據塊的數據節點的地址。Distributed File System 返回 FSDataInputStream 給客戶端,用來讀取數據。客戶端調用 stream 的 read()函數開始讀取數據。DFSInputStream連接保存此文件第一個數據塊的最近的數據節點。DataNode 從數據節點讀到客戶端(client),當此數據塊讀取完畢時,DFSInputStream 關閉和此數據節點的連接,然后連接此文件下一個數據塊的最近的數據節點。當客戶端讀取完畢數據的時候,調用FSDataInputStream 的 close 函數。在讀取數據的過程中,如果客戶端在與數據節點通信出現錯誤,則嘗試連接包含此數據塊的下一個數據節點。失敗的數據節點將被記錄,以后不再連接。
2,寫過程
客戶端調用 create()來創建文件,Distributed File System 用 RPC 調用 NameNode節點,在文件系統的命名空間中創建一個新的文件。NameNode 節點首先確定文件原來不存在,並且客戶端有創建文件的權限,然后創建新文件。Distributed File System 返回 DFSOutputStream,客戶端用於寫數據。客戶端開始寫入數據,DFSOutputStream 將數據分成塊,寫入 Data Queue。Data Queue 由 DataStreamer 讀取,並通知 NameNode 節點分配數據節點,用來存儲數據塊(每塊默認復制 3塊)。分配的數據節點放在一個 Pipeline 里。Data Streamer 將數據塊寫入 Pipeline 中的第一個數據節點。第一個數據節點將數據塊發送給第二個數據節點。第二個數據節點將數據發送給第三個數據節點。DFSOutputStream 為發出去的數據塊保存了 Ack Queue,等待 Pipeline 中的數據節點告知數據已經寫入成功。HDFS shell(一個client 連接端) 的基本操作命令
1,打印文件列表
hdfs dfs -ls hdfs:/ # 標准寫法 hdfs: 明確說明是 HDFS 系統路徑 '''以下簡寫''' hdfs dfs -ls / # 打印HDFS 系統下的根目錄 hdfs dfs -ls -r /package/test/ #打印指定文件目錄 -r(遞歸)
2,上傳文件、目錄. -f 才會覆蓋,有可能會 File exists
hdfs dfs -put /root/test.txt hdfs:/ #上傳本地 test.txt 文件到 HDFS 根目錄 hdfs dfs -put test.txt /test2.txt #上傳並重命名文件。 hdfs dfs -put test1.txt test2.txt hdfs:/ #一次上傳多個文件到 HDFS 路徑。 #上傳文件夾: hdfs dfs -put mypkg /newpkg #上傳並重命名了文件夾。 # -f 覆蓋上傳 hdfs dfs -put -f /root/test.txt / #如果 HDFS 目錄中有同名文件會被覆蓋 #上傳文件並重命名:-copyFromLocal(重命名) -f(覆蓋) hdfs dfs -copyFromLocal /test.txt hdfs:/test2.txt #覆蓋上傳: hdfs dfs -copyFromLocal -f test.txt /test.txt
3,下載文件、目錄
'''拷貝到本地''' #拷貝文件到本地目錄: hdfs dfs -get hdfs:/test.txt /root #拷貝文件並重命名,可以簡寫: hdfs dfs -get /test.txt /root/test.txt #從本地到 HDFS,同 put hdfs dfs -cp /test.txt hdfs:/test2.txt # 從 HDFS 到 HDFS hdfs dfs -cp hdfs:/test.txt hdfs:/test2.txt hdfs dfs -cp /test.txt /test2.txt
4,移動與刪除文件
hdfs dfs -mv hdfs:/test.txt hdfs:/dir/test.txt hdfs dfs -mv /test/slaves /testdir # 把/test/slaves 復制到 /testdir #刪除指定文件 hdfs dfs -rm /a.txt #刪除全部 txt 文件 hdfs dfs -rm /*.txt #遞歸刪除全部文件和目錄 hdfs dfs -rm -R /dir/
5,讀取與創建文件
hdfs dfs -cat /test.txt #以字節碼的形式讀取 hdfs dfs -tail /test.t # hdfs dfs - touchz /newfile.txt #創建文件 hdfs dfs -mkdir /newdir /newdir2 #可以同時創建多個 hdfs dfs -mkdir -p /newpkg/newpkg2/newpkg3 #同時創建父級目錄
# ./hdfs dfs -mkdir -p hdfs://sr128:9000/shared/spark-logs
6,獲取邏輯空間文件、目錄大小
hdfs dfs - du / #顯示 HDFS 根目錄中各文件和文件夾大小 hdfs dfs -du -h / #以最大單位顯示 HDFS 根目錄中各文件和文件夾 hdfs dfs -du -s / #僅顯示 HDFS 根目錄大小。即各文件和文件夾大小之和
hadoop 集群之間的文件拷貝
1,hadoop 自帶一種並行復制的程序,可以並行的從hadoop文件系統之中復制大量數據
2,diskcp 是作為一個 MapReduce 來進行實現的,只有 map 沒有reduce,默認20個map使用
#Distcp 兩個集群之間互相拷貝,並行執行的 map reduce 任務 # 如果 bar 文件存在,就會復制到bar文件之內,可以使用 -overwrite 進行覆蓋 ./hadoop distcp hdfs://master1:9000/H/K/ hdfs://master2:9000/H/K #不同版本之間的拷貝 前者目標主機(namenode ui端口) 后者目的主機(hdfs rpc端口) hadoop distcp hftp:/master1:50070/foo/bar hdfs:/master2:8020/foo/bar
job 工具可以檢查當前 job的狀態
./hadoop job -list ./hadoop job -kill <job_id> ./hadoop job -kill-task <attempt_id>
查看 hdfs 集群 運行狀態
./hdfs dsfadmin -report
計算向數據移動實例
首先創建
./hdfs dfs -D dfs.blocksize=1048576 -put logs.txt /user/logs.txt
我們可以使用 getFileBlockLocations(來自java 代碼) 獲取文件塊信息, 得到塊在哪個節點,然后實現計算向數據移動
Path i = new Path("/user/logs.txt") fileStatus ifile = fs.getFileBlockLocations(ifile,0,ifle.getLen()) // 使用增強for循環 for (BlockLocation b: blak){ System.out.println(b) /* 0,1048576,node1,node2 1048576,543234,node2,node3 * */ }