轉載自http://www.cnblogs.com/edisonchou/p/3538524.htmlhtml
隨着社會的進步,須要處理數據量愈來愈多,在一個操做系統管轄的範圍存不下了,那麼就分配到更多的操做系統管理的磁盤中,可是卻不方便管理和維護—>所以,迫切須要一種系統來管理多臺機器上的文件,因而就產生了分佈式文件管理系統,英文名成爲DFS(Distributed File System)。編程
那麼,什麼是分佈式文件系統?簡而言之,就是一種容許文件經過網絡在多臺主機上分享的文件系統,可讓多個機器上的多個用戶分享文件和存儲空間。它最大的特色是「通透性」,DFS讓其實是經過網絡來訪問文件的動做,由用戶和程序看來,就像是訪問本地的磁盤通常(In other words,使用DFS訪問數據,你感受不到是訪問遠程不一樣機器上的數據)。安全
圖1.一個典型的DFS示例服務器
做爲Hadoop的核心技術之一,HDFS(Hadoop Distributed File System,Hadoop分佈式文件系統)是分佈式計算中數據存儲管理的基礎。它所具備的高容錯、高可靠、高可擴展性、高吞吐率等特性爲海量數據提供了 不怕故障的存儲,也爲超大規模數據集(Large Data Set)的應用處理帶來了不少便利。網絡
圖2.Hadoop HDFS的LOGO架構
提到HDFS,不得不說Google的GFS。正是Google發表了關於GFS的論文,纔有了HDFS這個關於GFS的開源實現。分佈式
(1)硬件錯誤是常態而不是異常;(最核心的設計目標—>HDFS被設計爲運行在衆多的普通硬件上,因此硬件故障是很正常的。所以,錯誤檢測並快速恢復是HDFS最核心的設計目標)oop
(2)流式數據訪問;(HDFS更關注數據訪問的高吞吐量)post
(3)大規模數據集;(HDFS的典型文件大小大多都在GB甚至TB級別)性能
(4)簡單一致性模型;(一次寫入,屢次讀取的訪問模式)
(5)移動計算比移動數據更爲划算;(對於大文件來講,移動計算比移動數據的代價要低)
HDFS是一個主/從(Master/Slave)式的結構,以下圖所示。
圖3.HDFS的基本架構
從最終用戶的角度來看,它就像傳統的文件系統同樣,能夠經過目錄路徑對文件執行 CRUD(增刪查改)操做。但因爲分佈式存儲的性質,HDFS擁有一個NameNode和一些DataNodes。NameNode管理文件系統的元數 據,DataNode存儲實際的數據。客戶端經過同NameNode和DataNode的交互訪問文件系統→客戶端聯繫NameNode以獲取文件的元數 據,而真正的I/O操做是直接和DataNode進行交互的。
下面咱們再來看看HDFS的讀操做和寫操做的流程:
①讀操做
圖4.HDFS的讀操做
客戶端要訪問一個文件,首先,客戶端從NameNode中得到組成該文件數據塊位置列表,即知道數據塊被存儲在哪幾個DataNode上;而後,客戶端直接從DataNode上讀取文件數據。在此過程當中,NameNode不參與文件的傳輸。
②寫操做
圖5.HDFS的寫操做
客戶端首先須要向NameNode發起寫請求,NameNode會根據文件大小和文件塊 配置狀況,返回給Client它所管理部分DataNode的信息。最後,Client(開發庫)將文件劃分爲多個文件塊,根據DataNode的地址信 息,按順序寫入到每個DataNode塊中。
下面咱們看看NameNode和DataNode扮演什麼角色,有什麼具體的做用:
(1)NameNode
NameNode的做用是管理文件目錄結構,是管理數據節點的。NameNode維護兩套數據:一套是文件目錄與數據塊之間的關係,另外一套是數據塊與節點間的關係。前一套是靜態的,是存放在磁盤上的,經過fsimage和edits文件來維護;後一套數據時動態的,不持久化到磁盤,每當集羣啓動的時候,會自動創建這些信息。
(2)DataNode
毫無疑問,DataNode是HDFS中真正存儲數據的。這裏要提到一點,就是 Block(數據塊)。假設文件大小是100GB,從字節位置0開始,每64MB字節劃分爲一個Block,以此類推,能夠劃分出不少的Block。每一個 Block就是64MB(也能夠自定義設置Block大小)。
(3)典型部署
HDFS的一個典型部署是在一個專門的機器上運行NameNode,集羣中的其餘機器各 運行一個DataNode。(固然,也能夠在運行NameNode的機器上同時運行DataNode,或者一個機器上運行多個DataNode)一個集羣 中只有一個NameNode(可是單NameNode存在單點問題,在Hadoop 2.x版本以後解決了這個問題)的設計大大簡化了系統架構。
HDFS具有了較爲完善的冗餘備份和故障恢復機制,能夠實如今集羣中可靠地存儲海量文件。
(1)冗餘備份:HDFS將每一個文件存儲成一系列的數據塊(Block), 默認塊大小爲64MB(能夠自定義配置)。爲了容錯,文件的全部數據塊均可以有副本(默認爲3個,能夠自定義配置)。當DataNode啓動的時候,它會 遍歷本地文件系統,產生一份HDFS數據塊和本地文件對應關係的列表,並把這個報告發送給NameNode,這就是報告塊(BlockReport),報 告塊上包含了DataNode上全部塊的列表。
(2)副本存放:HDFS集羣通常運行在多個機架上,不一樣機架上機器的通訊須要經過交換機。一般狀況下,副本的存放策略很關鍵,機架內節點之間的帶寬比跨機架節點之間的帶寬要大,它能影響HDFS的可靠性和性能。HDFS採用一種稱爲機架感知(Rack- aware)的策略來改進數據的可靠性、可用性和網絡帶寬的利用率。在大多數狀況下,HDFS副本系數是默認爲3,HDFS的存放策略是將一個副本存放在 本地機架節點上,一個副本存放在同一個機架的另外一個節點上,最後一個副本放在不一樣機架的節點上。這種策略減小了機架間的數據傳輸,提升了寫操做的效率。機架的錯誤遠遠比節點的錯誤少,因此這種策略不會影響到數據的可靠性和可用性。
圖6.副本存放的策略
(3)心跳檢測:NameNode 週期性地從集羣中的每一個DataNode接受心跳包和塊報告,NameNode能夠根據這個報告驗證映射和其餘文件系統元數據。收到心跳包,說明該 DataNode工做正常。若是DataNode不能發送心跳信息,NameNode會標記最近沒有心跳的DataNode爲宕機,而且不會給他們發送任 何I/O請求。
(4)安全模式
(5)數據完整性檢測
(6)空間回收
(7)元數據磁盤失效
(8)快照(HDFS目前還不支持)
(1)列出文件目錄:hadoop fs -ls 目錄路徑
查看HDFS根目錄下的目錄:hadoop fs -ls /
遞歸查看HDFS根目錄下的目錄:hadoop fs -lsr /
(2)在HDFS中建立文件夾:hadoop fs -mkdir 文件夾名稱
在根目錄下建立一個名稱爲di的文件夾:
(3)上傳文件到HDFS中:hadoop fs -put 本地源路徑 目標存放路徑
將本地系統中的一個log文件上傳到di文件夾中:hadoop fs -put test.log /di
*PS:咱們經過Hadoop Shell上傳的文件是存放在DataNode的Block(數據塊)中的,經過Linux Shell是看不到文件的,只能看到Block。所以,能夠用一句話來描述HDFS:把客戶端的大文件存放在不少節點的數據塊中。
(4)從HDFS中下載文件:hadoop fs -get HDFS文件路徑 本地存放路徑
將剛剛上傳的test.log下載到本地的Desktop文件夾中:hadoop fs -get /di/test.log /home/hadoop/Desktop
(5)直接在HDFS中查看某個文件:hadoop fs -text(-cat) 文件存放路徑
在HDFS查看剛剛上傳的test.log文件:hadoop fs -text /di/test.log
(6)刪除在HDFS中的某個文件(夾):hadoop fs -rm(r) 文件存放路徑
刪除剛剛上傳的test.log文件:hadoop fs -rm /di/test.log
刪除HDFS中的di文件夾:hadoop fs -rmr /di
(7)善用help命令求幫助:hadoop fs -help 命令
查看ls命令的幫助:hadoop fs -help ls
咱們在工做中寫完的各類代碼是在服務器中運行的,HDFS的操做代碼也不例外。在開發階段,咱們使用Windows下的Eclipse做爲開發環境,訪問運行在虛擬機中的HDFS,也就是經過在本地的Eclipse中的Java代碼訪問遠程Linux中的HDFS。
在本地的開發調試過程當中,要使用宿主機中的Java代碼訪問客戶機中的HDFS,須要確保如下幾點:
宿主機和虛擬機的網絡可否互通?確保宿主機和虛擬機中的防火牆都關閉!確保宿主機與虛擬機中的jdk版本一致!
(1)導入依賴jar包,以下圖所示
(2)關聯hadoop源碼項目,以下圖所示
(1)定義HDFS_PATH:public static final String HDFS_PATH = "hdfs://hadoop-master:9000/testdir/testfile.log";
(2)讓URL類型識別hdfs://(URL類型默認只識別http://):URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());
(3)具體詳細代碼以下:
(4)運行結果(後面再也不貼運行結果圖):
(1)得到萬能的大神對象:final FileSystem fileSystem = FileSystem.get(new URI(HDFS_PATH),new Configuration());
(2)調用HDFS API進行CRUD操做,詳情見下代碼
(1)傳智播客Hadoop從入門到工做視頻教程第二季:http://bbs.itcast.cn/thread-21310-1-1.html
(2)劉鵬教授,《實戰Hadoop:開啓通向雲計算的捷徑》:http://item.jd.com/10830089.html
(3)吳超,《Hadoop的底層架構——RPC機制》:http://www.superwu.cn/2013/08/05/360
(4)zy19982004,《Hadoop學習十一:Hadoop-HDFS RPC總結》:http://zy19982004.iteye.com/blog/1875969