HDFS存儲理念(kiding): 以最少的錢買最爛的機器並實現最安全、難度高的分佈式文件系統(高容錯性低成本),從上能夠看出,HDFS認爲機器故障是種常態,因此在設計時充分考慮到單個機器故障,單個磁盤故障,單個文件丟失等狀況。
node
處理超大文件:存儲的一個超大文件能夠達到數GB級、數TB級、數PB級。安全
集羣規模動態擴展:節點動態加入到集羣,能夠數百數千個服務器
流式數據讀寫:HDFS的設計思想「一次寫入,屢次讀取」,一個數據集一旦由數據源生成,就會被複制分發到不一樣的存儲節點中,而後響應各類各樣的數據分析任務請求。網絡
運行於廉價的商用機器集羣上:HDFS設計時充分考慮了可靠性、安全性及高可用性,所以Hadoop對硬件要求比較低,能夠運行於廉價的商用機器集羣,無需昂貴的高可用性機器分佈式
不適合低延遲數據訪問: HDFS是爲了處理大型數據集,主要是爲了達到高的數據吞吐量而設計,這就可能以高延遲做爲代價。10毫秒如下的訪問能夠無視hdfs,不過hbase能夠彌補這個缺oop
沒法高效存儲大量小文件: namenode節點在內存中存儲住整個文件系統的元數據,所以文件的數量就會受到限制,每一個文件的元數據大約150字節fetch
不支持多用戶寫入及任意修改文件 :不支持多用戶對同一文件進行操做,並且寫操做只能在文件末尾完成,即追加操做。spa
Hadoop分佈式文件系統(HDFS)被設計成適合運行在通用硬件(commodity hardware)上的分佈式文件系統。HDFS體系結構中有兩類節點,一類是NameNode,又叫"元數據節點";另外一類是DataNode,又叫"數據節點"。總的設計思想:分而治之——將大文件、大批量文件,分佈式存放在大量獨立的服務器上,以便於採起分而治之的方式對海量數據進行運算分析。.net
HDFS是一個主/從(Mater/Slave)體系結構,從最終用戶的角度來看,它就像傳統的文件系統同樣,能夠經過目錄路徑對文件執行CRUD操做。但因爲分佈式存儲的性質,HDFS集羣擁有一個NameNode和一些DataNode。NameNode管理文件系統的元數據,DataNode存儲實際的數據。客戶端經過同NameNode和DataNodes的交互訪問文件系統。客戶端聯繫NameNode以獲取文件的元數據,而真正的文件I/O操做是直接和DataNode進行交互的。
HDFS通常是用來「一次寫入,屢次讀取」,不適合作實時交互性很強的事情,不適合存儲大量小文件(固然,若是你偏要存大量小文件的話本文末尾會有解決方案).設計
(1)分佈式文件系統,它所管理的文件是被切塊存儲在若干臺datanode服務器上.
(2)hdfs提供了一個統一的目錄樹來定位hdfs中的文件,客戶端訪問文件時只要指定目錄樹的路徑便可,不用關心文件的具體物理位置.
(3)每個文件的每個切塊,在hdfs集羣中均可以保存多個備份(默認3份),在hdfs-site.xml中,dfs.replication的value的數量就是備份的數量.
(4)hdfs中有一個關鍵進程服務進程:namenode,它維護了一個hdfs的目錄樹及hdfs目錄結構與文件真實存儲位置的映射關係(元數據).而datanode服務進程專門負責接收和管理"文件塊"-block.默認大小爲128M(可配置),(dfs.blocksize).(老版本的hadoop的默認block是64M的)
數據塊的第一個副本優先放在寫入數據塊的客戶端所在的節點上,可是若是這個客戶端上的數據節點空間不足或者是當前負載太重,則應該從該數據節點所在的機架中選擇一個合適的數據節點做爲本地節點。
若是客戶端上沒有一個數據節點的話,則從整個集羣中隨機選擇一個合適的數據節點做爲此時這個數據塊的本地節點。
HDFS的存放策略是將一個副本存放在本地機架節點上,另外兩個副本放在不一樣機架的不一樣節點上。
這樣集羣可在徹底失去某一機架的狀況下還能存活。同時,這種策略減小了機架間的數據傳輸,提升了寫操做的效率,由於數據塊只存放在兩個不一樣的機架上,減小了讀取數據時須要的網絡傳輸總帶寬。這樣在必定程度上兼顧了數據安全和網絡傳輸的開銷。
(1)若是傳輸過程當中,有某個datanode出現了故障,那麼當前的pipeline會被關閉,出現故障的datanode會從當前的pipeline中移除,剩餘的block會繼續剩下的datanode中繼續以pipeline的形式傳輸,同時Namenode會分配一個新的datanode,保持replicas設定的數量。
(2)關閉pipeline,將ack queue中的數據塊放入data queue的開始。
(3)當前的數據塊在已經寫入的數據節點中被元數據節點賦予新的標示,則錯誤節點重啓後可以察覺其數據塊是過期的,會被刪除。
(4)失敗的數據節點從pipeline中移除,另外的數據塊則寫入pipeline中的另外兩個數據節點。
(5)元數據節點則被通知此數據塊是複製塊數不足,未來會再建立第三份備份。
(6)客戶端調用create()來建立文件
(7)DistributedFileSystem用RPC調用元數據節點,在文件系統的命名空間中建立一個新的文件。
(8)元數據節點首先肯定文件原來不存在,而且客戶端有建立文件的權限,而後建立新文件。
(9)DistributedFileSystem返回DFSOutputStream,客戶端用於寫數據。
(10)客戶端開始寫入數據,DFSOutputStream將數據分紅塊,寫入data queue。
(11)Data queue由Data Streamer讀取,並通知元數據節點分配數據節點,用來存儲數據塊(每塊默認複製3塊)。分配的數據節點放在一個pipeline裏。
(12)Data Streamer將數據塊寫入pipeline中的第一個數據節點。第一個數據節點將數據塊發送給第二個數據節點。第二個數據節點將數據發送給第三個數據節點。
(13)DFSOutputStream爲發出去的數據塊保存了ack queue,等待pipeline中的數據節點告知數據已經寫入成功。
namenode:首先來講對於每一個文件操做,Hadoop並不會都寫到fsimage,這樣是很慢的,可是每次操做在提交後運行前先寫入edits編輯日誌,當edits編輯日誌文件大小超過64M(參數能夠設定),或者時間超過1小時(參數能夠設定),secondarynamenode就會作checkpoint的工做,這時namenode產生臨時空文件edits.new,secondarynamenode就會讀取namenode中的edits和fsimage,而後進行合併,合併成fsimage.ckpt檢查點,而後經過HTTP方式將fsimage.ckpt發送到NameNode,而後NameNode把fsimage.ckpt重命名爲fsimage(覆蓋原有fsimage文件),同時edits.new重命名爲edits(覆蓋原有edits文件)。注意這裏edits.new是個臨時文件,只有NameNode或者SecondaryNameNode正在作checkpoint的時候存在。
namenode啓動讀取fsimage原理: 當從新啓動namenode的時候,NameNode啓動時根據checkpoint時間加載最新的fsimage和edits文件到內存裏,而後建立文件edits.new臨時空文件,而後合併生成fsimage.ckpt檢查點,edits.new重命名爲edits(覆蓋原有edits文件),fsimage.ckpt重命名爲fsimage(覆蓋原有fsimage文件),而後更新fstime時間 和VERSION版本
答案:不能夠,
網盤只存儲,不用作分析,hdfs在增長節點,同時也加大了分析能力,主要是大容量存儲之上的數據分析
一、容量成本過高,二、文件大小不肯定,若是存大量小文件會形成很大的浪費 三、相對於網盤來講,文件讀寫的效率低 四、只適合一次寫入,屢次讀取的操做
五、hdfs不支持文件內容修改,可支持往文件尾部追加內容。
一、對於待上傳的文件,先將小文件合併爲一個大文件再上傳,利用SequenceFile、MapFile、Har等方式歸檔小文件,這個方法的原理就是把小文件歸檔起來管理,HBase就是基於此的。對於這種方法,若是想找回原來的小文件內容,那就必須得知道與歸檔文件的映射關係。
二、若是對於已經上傳了的文件,須要進行合併的話,咱們可使用Map-redure來進行歸檔。
三、BlueSky解決方案,以一種two-level prefetching機制以提升小文件讀取效率,即索引文件預取和數據文件預取。索引文件預取是指當用戶訪問某個文件時,該文件所在的block對應的索引文件被加載到內存中,這樣,用戶訪問這些文件時沒必要再與namenode交互了。數據文件預取是指用戶訪問某個文件時,將該文件所在課件中的全部文件加載到內存中,這樣,若是用戶繼續訪問其餘文件,速度會明顯提升。
參考:
漫畫解讀HDFS存儲原理: http://www.36dsj.com/archives/41391
hadoop原理和機制: http://blog.csdn.net/qa962839575/article/details/42748541