大數據技術主要要解決的問題的是大規模數據的計算處理問題,那麼首先要解決的就是大規模數據的存儲問題。大規模數據存儲要解決的核心問題有三個方面:算法
數據存儲容量的問題,既然大數據要解決的是數以PB計的數據計算問題,而通常的服務器磁盤容量一般1-2TB,那麼如何存儲這麼大規模的數據。數據庫
數據讀寫速度的問題,通常磁盤的連續讀寫速度爲幾十MB,以這樣的速度,幾十PB的數據恐怕要讀寫到天荒地老。編程
數據可靠性的問題,磁盤大約是計算機設備中最易損壞的硬件了,在網站一塊磁盤使用壽命大概是一年,若是磁盤損壞了,數據怎麼辦?服務器
在大數據技術出現以前,人們就須要面對這些關於存儲的問題,對應的解決方案就是RAID技術。架構
RAID(獨立磁盤冗餘陣列)技術主要是爲了改善磁盤的存儲容量,讀寫速度,加強磁盤的可用性和容錯能力。目前服務器級別的計算機都支持插入多塊磁盤(8塊或者更多),經過使用RAID技術,實現數據在多塊磁盤上的併發讀寫和數據備份。併發
經常使用RAID技術有如下幾種,如圖所示。框架
假設服務器有N塊磁盤。運維
RAID0編程語言
數據在從內存緩衝區寫入磁盤時,根據磁盤數量將數據分紅N份,這些數據同時併發寫入N分佈式
塊磁盤,使得數據總體寫入速度是一塊磁盤的N倍。讀取的時候也同樣,所以RAID0具備極快的數據讀寫速度,可是RAID0不作數據備份,N塊磁盤中只要有一塊損壞,數據完整性就被破壞,全部磁盤的數據都會損壞。
RAID1
數據在寫入磁盤時,將一份數據同時寫入兩塊磁盤,這樣任何一塊磁盤損壞都不會致使數據丟失,插入一塊新磁盤就能夠經過複製數據的方式自動修復,具備極高的可靠性。
RAID10
結合RAID0和RAID1兩種方案,將全部磁盤平均分紅兩份,數據同時在兩份磁盤寫入,至關於RAID1,可是在每一份磁盤裏面的N/2塊磁盤上,利用RAID0技術併發讀寫,既提升可靠性又改善性能,不過RAID10的磁盤利用率較低,有一半的磁盤用來寫備份數據。
RAID3
通常狀況下,一臺服務器上不會出現同時損壞兩塊磁盤的狀況,在只損壞一塊磁盤的狀況下,若是能利用其餘磁盤的數據恢復損壞磁盤的數據,這樣在保證可靠性和性能的同時,磁盤利用率也獲得大幅提高。
在數據寫入磁盤的時候,將數據分紅N-1份,併發寫入N-1塊磁盤,並在第N塊磁盤記錄校驗數據,任何一塊磁盤損壞(包括校驗數據磁盤),均可以利用其餘N-1塊磁盤的數據修復。可是在數據修改較多的場景中,任何磁盤修改數據都會致使第N塊磁盤重寫校驗數據,頻繁寫入的後是第N塊磁盤比其餘磁盤容易損壞,須要頻繁更換,因此RAID3不多在實踐中使用。
RAID5
相比RAID3,更多被使用的方案是RAID5。
RAID5和RAID3很類似,可是校驗數據不是寫入第
塊磁盤,而是螺旋式地寫入全部磁盤中。這樣校驗數據的修改也被平均到全部磁盤上,避免RAID3頻繁寫壞一塊磁盤的狀況。
RAID6
若是數據須要很高的可靠性,在出現同時損壞兩塊磁盤的狀況下(或者運維管理水平比較落後,壞了一塊磁盤可是遲遲沒有更換,致使又壞了一塊磁盤),仍然須要修復數據,這時候可使用RAID6。
RAID6和RAID5相似,可是數據只寫入N-2塊磁盤,並螺旋式地在兩塊磁盤中寫入校驗信息(使用不一樣算法生成)。
在相同磁盤數目(N)的狀況下,各類RAID技術的比較以下表所示。
RAID技術有硬件實現,好比專用的RAID卡或者主板直接支持,也能夠經過軟件實現,在操做系統層面將多塊磁盤組成RAID,在邏輯視做一個訪問目錄。RAID技術在傳統關係數據庫及文件系統中應用比較普遍,是改善計算機存儲特性的重要手段。
RAID技術只是在單臺服務器的多塊磁盤上組成陣列,大數據須要更大規模的存儲空間和訪問速度。將RAID技術原理應用到分佈式服務器集羣上,就造成了Hadoop分佈式文件系統HDFS的架構思想。
和RAID在多個磁盤上進行文件存儲及並行讀寫同樣思路,HDFS在一個大規模分佈式服務器集羣上,對數據進行並行讀寫及冗餘存儲。由於HDFS能夠部署在一個比較大的服務器集羣上,集羣中全部服務器的磁盤均可以供HDFS使用,因此整個HDFS的存儲空間能夠達到PB級容量。HDFS架構如圖。
HDFS中關鍵組件有兩個,一個是NameNode,一個是DataNode。
DataNode負責文件數據的存儲和讀寫操做,HDFS將文件數據分割成若干塊(block),每一個DataNode存儲一部分block,這樣文件就分佈存儲在整個HDFS服務器集羣中。應用程序客戶端(Client)能夠並行對這些數據塊進行訪問,從而使得HDFS能夠在服務器集羣規模上實現數據並行訪問,極大地提升訪問速度。實踐中HDFS集羣的DataNode服務器會有不少臺,通常在幾百臺到幾千臺這樣的規模,每臺服務器配有數塊磁盤,整個集羣的存儲容量大概在幾PB到數百PB。
NameNode負責整個分佈式文件系統的元數據(MetaData)管理,也就是文件路徑名,數據block的ID以及存儲位置等信息,承擔着操做系統中文件分配表(FAT)的角色。HDFS爲了保證數據的高可用,會將一個block複製爲多份(缺省狀況爲3份),並將三份相同的block存儲在不一樣的服務器上。這樣當有磁盤損壞或者某個DataNode服務器宕機致使其存儲的block不能訪問的時候,Client會查找其備份的block進行訪問。
block多份複製存儲以下圖所示,對於文件/users/sameerp/data/part-0,其複製備份數設置爲2,存儲的block id爲1,3。block1的兩個備份存儲在DataNode0和DataNode2兩個服務器上,block3的兩個備份存儲DataNode4和DataNode6兩個服務器上,上述任何一臺服務器宕機後,每一個block都至少還有一個備份存在,不會影響對文件/users/sameerp/data/part-0的訪問。
事實上,DataNode會經過心跳和NameNode保持通訊,若是DataNode超時未發送心跳,NameNode就會認爲這個DataNode已經失效,當即查找這個DataNode上存儲的block有哪些,以及這些block還存儲在哪些服務器上,隨後通知這些服務器再複製一份block到其餘服務器上,保證HDFS存儲的block備份數符合用戶設置的數目,即便再有服務器宕機,也不會丟失數據。
Hadoop分佈式文件系統能夠象通常的文件系統那樣進行訪問:使用命令行或者編程語言API進行文件讀寫操做。咱們以HDFS寫文件爲例看HDFS處理過程,以下圖。
應用程序Client調用HDFS API,請求建立文件,HDFS API包含在Client進程中。
HDFS API將請求參數發送給NameNode服務器,NameNode在meta信息中建立文件路徑,並查找DataNode中空閒的block。而後將空閒block的id、對應的DataNode服務器信息返回給Client。由於數據塊須要多個備份,因此即便Client只須要一個block的數據量,NameNode也會返回多個NameNode信息。
Client調用HDFS API,請求將數據流寫出。
HDFS API鏈接第一個DataNode服務器,將Client數據流發送給DataNode,該DataNode一邊將數據寫入本地磁盤,一邊發送給第二個DataNode。同理第二個DataNode記錄數據併發送給第三個DataNode。
Client通知NameNode文件寫入完成,NameNode將文件標記爲正常,能夠進行讀操做了。
HDFS雖然提供了API,可是在實踐中,咱們不多本身編程直接去讀取HDFS中的數據,緣由正如開篇提到,在大數據場景下,移動計算比移動數據更划算。於其寫程序去讀取分佈在這麼多DataNode上的數據,不如將程序分發到DataNode上去訪問其上的block數據。可是如何對程序進行分發?分發出去的程序又如何訪問HDFS上的數據?計算的結果如何處理,若是結果須要合併,該如何合併?
Hadoop提供了對存儲在HDFS上的大規模數據進行並行計算的框架,就是咱們以前講的MapReduce。