hdfs的存儲機制
㈠ 1g的文件在hadoop是怎麼存儲的
hdfs是按塊進行存儲的。1GB文件會劃分成若干塊(默認64MB一個塊,也可以自己配置),然後分配到不同的存儲節點上存儲。
nameserver會記錄哪些塊存儲在哪個節點上,等讀的時候需要訪問nameserver,獲取到不同的數據節點,然後再訪問數據即可。
㈡ 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詳解
認識HDFS
HDFS的特點:
HDFS不適用的場景
HDFS的組成
HDFS的數據復制
HDFS復制的選擇
HDFS的安全模式
HDFS的元數據持久化
HDFS架構
數據塊
為什麼HDFS默認的Block為128MB(64MB)?
分布式文件系統中的塊進行抽象帶來的好處:
NameNode
NameNode主要功能如下:
DataNode
SecondaryNameNode
SecondaryNameNode合並Fsimage和EditsLog文件過程如下:
CheckPoint過程如下:
SecondaryNameNode會周期性地消純將EditsLog文件進行合並,合並前提條件如下:
機架感知
HDFS的RPC機制
RPC的實現流程
RPC的實體模型
HDFS的文件讀取
文件讀取的流程如下:
HDFS的文件寫入
寫入文件的過拿態咐程比讀取復雜,步驟如下:
HDFS的HA(High Availability,高可用性)機制
HA架構解釋如下:
HDFS的federation機制
HDFS Federation使用了多個獨立的NameNode/NameSpace使得HDFS的命名服務能閉讓夠水平擴展
HDFS Federation中的NameNode之間是聯盟關系,它們之間相互獨立且不需要相互協調。HDFS Federation中的NameNode提供了名字空間和塊關聯功能.HDFS Federation中的DataNode被所有的NameNode用作公共存儲塊的地方.每一個DataNode都會向所在集群中所有的NameNode注冊,並周期性的發送心跳和塊信息報告,同時處理來自NameNode的指令
在HDFS中,所有的更新、回滾都是以NameNode和BlockPool為單元發生的.即同HDFS Federation中不同的NameNode/BlockPool之間沒有什麼關系
多個名字空間的管理問題
HDFS Federation中名字空間管理的基本原理:
維護HDFS
追加數據
並行復制
升級與回滾
兩種升級升級都簡單分為以下幾步:
添加節點
刪除節點
HDFS許可權管理
㈣ HDFS架構
HDFS中的文件是以數據塊(Block)的形式存儲的,默認最基本的存儲單位是128 MB(Hadoop 1.x為64 MB)的數據塊。也就是說,存儲在HDFS中的文件都會被分割成128 MB一塊的數據塊進行存儲,如果文件本身小於一個數據塊的大小,則按實際大豎歲答小存儲,並不佔用整個數據塊空間。HDFS的數據塊之所以會設置這么大,其目的是減少定址開銷。數據塊數量越多,定址數據塊所耗的時間就越多。當然也不會設置過大,MapRece中的Map任務通常一次只處理一個塊中的數據,如果任務數太少,作業的運行速度就會比較慢。HDFS的每一個數據塊默認都有三個副本,分別存儲在不同的DataNode上,以實現容錯功能。因此,若數據塊的某個副本丟失並不會影響對數據塊的訪問。數據塊大小和副本數量可在配置文件中更改
NameNode是HDFS中存儲元數據(文件名稱、大小和位置等信息)的地方,它將所有文件和文件夾的元數據保存在一個文件系統目錄樹中,任何元數據信息的改變,NameNode都會記錄。HDFS中的每個文件都被拆分為多個數據塊存放,這種文件與數據塊的對應關系也存儲在文件系統目錄樹中,由NameNode維護。NameNode還存儲數據塊到DataNode的映射信息,這種映射信息包括:數據塊存放在哪些DataNode上、每個DataNode上保存了哪些數據塊。NameNode也會周期性地接收來自集群中DataNode的「心跳」和「塊報告」。通過「心跳」與DataNode保持通信,監控DataNode的狀態(活著還是宕機),若長時間接收不到「心跳」信息,NameNode會認為DataNode已經宕機,從而做出相應的調整策略。「塊報告」包含了DataNode上所有數據塊的列表信息。
DataNode是HDFS中真正存儲數據的地方。客戶端可以向DataNode請求寫入或讀取數據塊,DataNode還在來自NameNode的指令下執行塊的創建、刪除和復制,並且周期性地向NameNode匯報數據塊信息。
NodeSecondaryNameNode用於幫助NameNode管理元數據,從而使NameNode能夠快速、高效地工作。它並不是第二個NameNode,僅是NameNode的一個輔助工具。HDFS的元數據信息主要存儲於兩個文件中:fsimage和edits。fsimage是文件系統映射文件,主余慧要存儲文件元數據信息,其中包含文件系統所有目錄、文件信息以及數據塊的索引;edits是HDFS操作日誌文件,HDFS對文件系統的修改日誌會存儲到該文件中。當NameNode啟動時,會從文件fsimage中讀取HDFS的狀態,雀辯也會對文件fsimage和edits進行合並,得到完整的元數據信息,隨後會將新HDFS狀態寫入fsimage。但是在繁忙的集群中,edits文件會隨著時間的推移變得非常大,這就導致NameNode下一次啟動的時間會非常長。為了解決這個問題,則產生了SecondaryNameNode,SecondaryNameNode會定期協助NameNode合並fsimage和edits文件,並使edits文件的大小保持在一定的限制內。SecondaryNameNode通常與NameNode在不同的計算機上運行,因為它的內存需求與NameNode相同,這樣可以減輕NameNode所在計算機的壓力。
㈤ hadoop中存儲文件系統hdfs的冗餘機制是怎麼進行的有什麼特點
可以只用一行代碼來運行MapRece作業:JobClient.runJon(conf),Job作業運行時參與的四個實體:
1.JobClient 寫代碼,配置作業,提交作業。
2.JobTracker:初始化作業,分配作業,協調作業運行。這是一個java程序,主類是JobTracker。
3.TaskTracker:運行作業劃分後的任務,即分配數據分配上執行Map或Rece任務。
4.HDFS:保存作業數據、配置信息等,保存作業結果。
Map/Rece 作業總體執行流程:
代碼編寫 ----> 作業配置 ---->作業提交---->Map任務分配和執行---->處理中間結果----> Rece任務分配與執行----> 輸出結果
而對於每個作業的執行,又包含:
輸入准備---->任務執行---->輸出結果
作業提交JobClient:
JobClient的runJob方法產生一個Jobclient實例並調用其submitJob方法,然後runJob開始循環嗎,並在循環中調用getTaskCompetionEvents方法,獲得TaskCompletionEvent實例,每秒輪詢作業進度(後面有介紹進度和狀態更新),把進度寫到控制台,作業完成後顯示作業計數器,若失敗,則把錯誤記錄到控制台。
submitJob方法作業提交的過程:
1.向JobTracker請求一個新的JobId。
2.檢查作業相關路徑,如果路徑不正確就會返回錯誤。
3.計算作業輸入分片及其劃分信息。
4.將作業運行需要的資源(jar文件、配置文件等)復制到Shared HDFS,並
復制多個副本(參數控制,默認值為10)供tasktracker訪問,也會將計算的分片復制到HDFS。
5.調用JobTracker對象的submitJob()方法來真正提交作業,告訴JobTracker作業准備執行。
作業的初始化JobTracker:
JobTracker收到submitJob方法調用後,會把調用放入到一個內部隊列,由作業調度器(Job scheler)進行調度並對其初始化。Job初始化即創建一個作業對象。
當作業被調度後,JobTracker會創建一個代表這個作業的JobInProgress對象,並將任務和記錄信息封裝在這個對象中,以便跟蹤任務狀態和進程。
初始化過程就是JobInProgress對象的initTasks方法進行初始化的。
初始化步驟:
1.從HDFS中讀取作業對應的job.split信息,為後面的初始化做好准備。
2.創建並初始化map和rece任務。根據數據分片信息中的個數確定map task的個數,然後為每個map task生成一個TaskInProgress對象來處理數據分片,先將其放入nonRunningMapCache,以便JobTracker分配任務的時候使用。接下來根據JobConf中的mapred.rece.tasks屬性利用setNumReceTasks()方法設置rece task的數量,然後同map task創建方式。
3.最後就是創建兩個初始化task,進行map和rece的初始化。
任務的分配JobTracker:
消息傳遞HeartBeat: tasktracker運行一個簡單循環定期發送心跳(heartbeat)給JobTracker。由心跳告知JobTracker自己是否存活,同時作為消息通道傳遞其它信息(請求新task)。作為心跳的一部分,tasktracker會指明自己是否已准備好運行新的任務,如果是,jobtracker會分配它一個任務。
分配任務所屬於的作業:在Jobtracker分配任務前需先確定任務所在的作業。後面會介紹到各種作業調度演算法,默認是一個FIFO的作業調度。
分配Map和Rece任務:tasktracker有固定數量的任務槽,一個tasktracker可以同時運行多個Map和Rece任務,但其准確的數量由tasktracker的核的數量和內存大小決定。默認調度器會先填滿Map任務槽,再填Rece任務槽。jobtracker會選擇距離離分片文件最近的tasktracker,最理想情況下,任務是數據本地化(data-local)的,當然也可以是機架本地化(rack-local),如果不是本地化的,那麼他們就需要從其他機架上檢索數據。Rece任務分配很簡單,jobtracker會簡單的從待運行的rece任務列表中選取下一個來執行,不用考慮數據本地化。
任務的執行TaskTracker:
TaskTracker收到新任務後,就要在本地運行任務了,運行任務的第一步就是通過localizedJob將任務本地化所需要的注入配置、數據、程序等信息進行本地化。
1.本地化數據:從共享文件系統將job.split 、job.jar (在分布式緩存中)復制本地,將job配置信息寫入job.xml。
2.新建本地工作目錄:tasktracker會加壓job.jar文件到本工作目錄。
3.調用launchTaskForJob方法發布任務(其中會新建TaskRunner實例運行任務),如果是Map任務就啟用MapTaskRunner,對於Rece就是ReceTaskRunner。
在這之後,TaskRunner會啟用一個新的JVM來運行每個Map/Rece任務,防止程序原因而導致tasktracker崩潰,但不同任務間重用JVM還是可以的,後續會講到任務JVM重用。
對於單個Map,任務執行的簡單流程是:
1.分配任務執行參數
2.在Child臨時文件中添加map任務信息(Child是運行Map和Rece任務的主進程)
3.配置log文件夾,配置map任務的通信和輸出參數
4.讀取input split,生成RecordReader讀取數據
5.為Map生成MapRunnable,依次從RecordReader中接收數據,並調用Map函數進行處理。
6.最後將map函數的輸出調用collect收集到MapOutputBuffer(參數控制其大小)中。
Streaming和Pipes:
Streaming和Pipes都運行特殊的Map和Rece任務,目的是運行用戶提供的可執行程序並與之通信。
Streaming:使用標准輸入輸出Streaming與進程進行通信。
Pipes:用來監聽套接字,會發送一個埠號給C++程序,兩者便可建立鏈接。
進度和狀態更新:
一個作業和它的任務都有狀態(status),其中包括:運行成功失敗狀態、Map/Rece進度、作業計數器值、狀態消息。
狀態消息與客戶端的通信:
1.對於Map任務Progress的追蹤:progress是已經處理完的輸入所佔的比例。
2.對於Rece:稍復雜,rece任務分三個階段(每個階段佔1/3),復制、排序和Rece處理,若rece已執行一半的輸入的話,那麼任務進度便是1/3+1/3+1/6=5/6。
3.任務計數器:任務有一組計數器,負責對任務運行各個事件進行計數。
4.任務進度報告:如果任務報告了進度,便會設置一個標記以表明狀態將被發送到tasktracker。有一個獨立線程每隔三秒檢查一次此標記,如果已設置,則告知tasktracker當前狀態。
5.tasktracker進度報告:tasktracker會每隔5秒(這個心跳是由集群大小決定,集群越大時間會越長)發送heartbeat到jobtracker,並且tasktracker運行的所有狀態都會在調用中被發送到jobtracker。
6.jobtracker合並各任務報告:產生一個表明所有運行作業機器所含任務狀態的全局視圖。
前面提到的JobClient就是通過每秒查詢JobTracker來接收最新狀態,而且客戶端JobClient的getJob方法可以得到一個RunningJob的實例,其包含了作業的所以狀態信息。
作業的完成:
當jobtracker收到作業最後一個任務已完成的通知後,便把作業狀態設置成成功。JobClient查詢狀態時,便知道任務已成功完成,於是JobClient列印一條消息告知用戶,然後從runJob方法返回。
如果jobtracker有相應設置,也會發送一個Http作業通知給客戶端,希望收到回調指令的客戶端可以通過job.end.notification.url屬性來進行設置。
jobtracker情況作業的工作狀態,指示tasktracker也清空作業的工作狀態,如刪除中間輸出。
失敗
實際情況下,用戶的代碼存在軟體錯誤進程會崩潰,機器也會產生故障,但Hadoop能很好的應對這些故障並完成作業。
1.任務失敗
子任務異常:如Map/Rece任務中的用戶代碼拋出異常,子任務JVM進程會在退出前向父進程tasktracker發送錯誤報告,錯誤被記錄用戶日誌。tasktracker會將此次task attempt標記為tailed,並釋放這個任務槽運行另外一個任務。
子進程JVM突然退出:可能由於JVM bug導致用戶代碼造成的某些特殊原因導致JVM退出,這種情況下,tasktracker會注意到進程已經退出,並將此次嘗試標記為failed。
任務掛起:一旦tasktracker注意一段時間沒有收到進度更新,便會將任務標記為failed,JVM子進程將被自動殺死。任務失敗間隔時間通常為10分鍾,可以以作業或者集群為基礎設置過期時間,參數為mapred.task.timeout。注意:如果參數值設置為0,則掛起的任務永遠不會釋放掉它的任務槽,隨著時間的推移會降低整個集群的效率。
任務失敗嘗試次數:jobtracker得知一個tasktracker失敗後,它會重新調度該任務執行,當然,jobtracker會嘗試避免重新調度失敗過的tasktracker任務。如果一個任務嘗試次數超過4次,它將不再被重試。這個值是可以設置的,對於Map任務,參數是mapred.map.max.attempts,對於rece任務,則由mapred.rece.max.attempts屬性控制。如果次數超過限制,整個作業都會失敗。當然,有時我們不希望少數幾個任務失敗就終止運行的整個作業,因為即使有些任務失敗,作業的一些結果可能還是有用的,這種情況下,可以為作業設置在不觸發作業失敗情況下的允許任務失敗的最大百分比,Map任務和Rece任務可以獨立控制,參數為mapred.max.map.failures.percent 和mapred.max.rece.failures.percent。
任務嘗試中止(kill):任務終止和任務失敗不同,task attempt可以中止是因為他是一個推測副本或因為它所處的tasktracker失敗,導致jobtracker將它上面的所有task attempt標記為killed。被終止的task attempt不會被計入任務運行嘗試次數,因為嘗試中止並不是任務的錯。
2.tasktracker失敗
tasktracker由於崩潰或者運行過慢而失敗,他將停止向jobtracker發送心跳(或很少發送心跳)。jobtracker注意已停止發送心跳的tasktracker(過期時間由參數mapred.tasktracker.expiry.interval設置,單位毫秒),並將它從等待調度的tasktracker池中移除。如果是未完成的作業,jobtracker會安排次tasktracker上已經運行成功的Map任務重新運行,因為此時rece任務已無法訪問(中間輸出存放在失敗的tasktracker的本地文件系統上)。
即使tasktracker沒有失敗,也有可能被jobtracker列入黑名單。如果tasktracker上面的失敗任務數量遠遠高於集群的平均失敗任務次數,他就會被列入黑名單,被列入黑名單的tasktracker可以通過重啟從jobtracker黑名單中移除。
3.jobtracker失敗
老版本的JobTracker失敗屬於單點故障,這種情況下作業註定失敗。
作業調度:
早期作業調度FIFO:按作業提交順序先進先出。可以設置優先順序,通過設置mapred.job.priority屬性或者JobClient的setJobPriority()方法制定優先順序(優先順序別:VERY_HIGH,HIGH,NORMAL,LOW,VERY_LOW)。注意FIFO調度演算法不支持搶占(preemption),所以高優先順序作業仍然會被那些已經開始的長時間運行的低優先順序作業所阻塞。
Fair Scheler:目標是讓每個用戶公平地共享集群能力。當集群存在很多作業時,空閑的任務槽會以」讓每個用戶共享集群「的方式進行分配。默認每個用戶都有自己的作業池。FairScheler支持搶占,所以,如果一個池在特定的一段時間未得到公平地資源共享,它會終止池中得到過多的資源任務,以便把任務槽讓給資源不足的池。FairScheler是一個後續模塊,使用它需要將其jar文件放在Hadoop的類路徑下。可以通過參數map.red.jobtracker.taskScheler屬性配置(值為org.apache.hadoop.mapred.FairScheler)
Capacity Scheler:
集群由很多隊列組成,每個隊列都有一個分配能力,這一點與FairScheler類似,只不過在每個隊列內部,作業根據FIFO方式進行調度。本質上說,Capacity Scheler允許用戶或組織為每個用戶模擬一個獨立使用FIFO的集群。
shuffle和排序:
MapRece確保每個Recer的輸入都是按鍵排序的。系統執行排序的過程-將map輸出作為輸入傳給recer的過程稱為shuffle。shuffle屬於不斷被優化和改進的代碼庫的一部分,從許多方面來看,shuffle是MapRece的心臟。
整個shuffle的流程應該是這樣:
map結果劃分partition 排序sort 分割spill 合並同一劃分 合並同一劃分 合並結果排序 rece處理 輸出
Map端:
寫入緩沖區:Map函數的輸出,是由collector處理的,它並不是簡單的將結果寫到磁碟。它利用緩沖的方式寫到內存,並處於效率的考慮進行預排序。每個map都有一個環形的內存緩沖區,用於任務輸出,默認緩沖區大小為100MB(由參數io.sort.mb調整),一旦緩沖區內容達到閾值(默認0.8),後台進程邊開始把內容寫到磁碟(spill),在寫磁碟過程中,map輸出繼續被寫到緩沖區,但如果緩沖區被填滿,map會阻塞知道寫磁碟過程完成。寫磁碟將按照輪詢方式寫到mapred.local.dir屬性制定的作業特定子目錄中。
寫出緩沖區:collect將緩沖區的內容寫出時,會調用sortAndSpill函數,這個函數作用主要是創建spill文件,按照key值對數據進行排序,按照劃分將數據寫入文件,如果配置了combiner類,會先調用combineAndSpill函數再寫文件。sortAndSpill每被調用一次,就會寫一個spill文件。
合並所有Map的spill文件:TaskTracker會在每個map任務結束後對所有map產生的spill文件進行merge,merge規則是根據分區將各個spill文件中數據同一分區中的數據合並在一起,並寫入到一個已分區且排序的map輸出文件中。待唯一的已分區且已排序的map輸出文件寫入最後一條記錄後,map端的shuffle階段就結束了。
在寫磁碟前,線程首先根據數據最終要傳遞到的recer把數據劃分成響應的分區(partition),在每個分區中,後台線程按鍵進行內排序,如果有一個combiner,它會在排序後的輸出上運行。
內存達到溢出寫的閾值時,就會新建一個溢出寫文件,因為map任務完成其最後一個輸出記錄之後,會有幾個溢出寫文件。在任務完成前,溢出寫文件會被合並成一個已分區且已排序的輸出文件。配置屬性io.sort.facor控制一次最多能合並多少流,默認值是10。
如果已經指定combiner,並且寫次數至少為3(通過min.mum.spills.for.combine設置)時,則combiner就會在輸出文件寫到磁碟之前運行。運行combiner的意義在於使map輸出更緊湊,捨得寫到本地磁碟和傳給recer的數據更少。
寫磁碟時壓縮:寫磁碟時壓縮會讓寫的速度更快,節約磁碟空間,並且減少傳給recer的數據量。默認情況下,輸出是不壓縮的,但可以通過設置mapred.compress.map.output值為true,就可以啟用壓縮。使用的壓縮庫是由mapred.map.output.compression.codec制定。
recer獲得文件分區的工作線程:recer通過http方式得到輸出文件的分區,用於文件分區的工作線程數量由tracker.http.threads屬性指定,此設置針對的是每個tasktracker,而不是每個map任務槽。默認值為40,在大型集群上此值可以根據需要而增加。
Rece端:
復制階段:rece會定期向JobTracker獲取map的輸出位置,一旦拿到輸出位置,rece就會從對應的TaskTracker上復制map輸出到本地(如果map輸出很小,則會被復制到TaskTracker節點的內存中,否則會被讓如磁碟),而不會等到所有map任務結束(當然這個也有參數控制)。
合並階段:從各個TaskTracker上復制的map輸出文件(無論在磁碟還是內存)進行整合,並維持數據原來的順序。
Rece階段:從合並的文件中順序拿出一條數據進行rece函數處理,然後將結果輸出到本地HDFS。
Map的輸出文件位於運行map任務的tasktracker的本地磁碟,現在,tasktracker要為分區文件運行rece任務。每個任務完成時間可能不同,但是只要有一個任務完成,rece任務就開始復制其輸出,這就是rece任務的復制階段( phase)。rece任務有少量復制線程,因此能夠並行取得map輸出。默認值是5個線程,可以通過mapred.rece.parallel.copies屬性設置。
Recer如何得知從哪個tasktracker獲得map輸出:map任務完成後會通知其父tasktracker狀態已更新,tasktracker進而通知(通過heart beat)jobtracker。因此,JobTracker就知道map輸出和tasktracker之間的映射關系,recer中的一個線程定期詢問jobtracker以便獲知map輸出位置。由於recer有可能失敗,因此tasktracker並沒有在第一個recer檢索到map輸出時就立即從磁碟上刪除它們,相反他會等待jobtracker告示它可以刪除map輸出時才刪除,這是作業完成後最後執行的。
如果map輸出很小,則會被直接復制到rece tasktracker的內存緩沖區(大小由mapred.job.shuffle.input.buffer.percent控制,占堆空間的百分比),否則,map輸出被復制到磁碟。一旦內存緩沖區達到閾值大小(由mapred.iob.shuffle.merge.percent)
或達到map輸出閾值大小(mapred.inmem.threadhold),則合並後溢出寫到磁碟中。
隨著磁碟上副本增多,後台線程會將他們合並為更大的、排好序的文件。注意:為了合並,壓縮的map輸出必須在內存中被解壓縮。
排序階段:復制階段完成後,rece任務會進入排序階段,更確切的說是合並階段,這個階段將合並map輸出,維持其順序排列。合並是循環進行的,由合並因子決定每次合並的輸出文件數量。但讓有可能會產生中間文件。
rece階段:在最後rece階段,會直接把排序好的文件輸入rece函數,不會對中間文件進行再合並,最後的合並即可來自內存,也可來自磁碟。此階段的輸出會直接寫到文件系統,一般為hdfs。
細節:這里合並是並非平均合並,比如有40個文件,合並因子為10,我們並不是每趟合並10個,合並四趟。而是第一趟合並4個,後三趟合並10,在最後一趟中4個已合並的文件和餘下6個未合並會直接並入rece。
㈥ 以下哪一項不屬於hdfs的存儲機制
數據容罩凱錯與恢復機制不屬於hdfs的存儲機制。根據查詢相關資凳納料信息,HDFS用來為大數據提供可靠存儲,不屬於HDFS高可靠性與可用性機制的是數物粗喚據容錯與恢復機制。
㈦ HDFS的副本機制和機架感知策略
hdfs上的文件是按照塊方式進行存儲的
塊的大小通過hdfs-site.xml裡面的參數進行配置,value值是以B為單位的
hadoop1默認塊大小64M,hadoop2默認塊大小128M
機架感知策略是hdfs的副本放置的方式
2.7以友謹團前是第一個復本而言:
如果是外部客戶端上傳數據,則此時namenode會選擇一個相對空閑節點存放第一個復本,
如果DataNode本晌賀身就是客戶端,本身上傳,好比偽分布式,都在你這台電腦上,內部上傳,則第一個復本放在本節點上
第二個副本,在2.7以前,第二個副本要放到和第一個副本不同機架的節點上,為了防止一個機架掛了,都消失了
第三個副本在2.7以前,放到和第二個副本相同機架上,相同機架之間傳輸的快
如果是外部客戶端上傳數據,則此時namenode會選擇一個相對空閑節點存放第一個復本,
如果DataNode本身就是客戶端,本身上傳,好比偽分布式,都在你這台電腦上,內部上傳,則第一個復本放在本節點上
第二個副本,在2.7後,第二個副本要放到和第一個副本相同機架的節點上,
第三個副本在2.7後,放到和第二個副本不同機架上
默認是不開啟的,需要如好橘下配置
hadoop-site.xml配置文件中配置一個選項:
㈧ hdfs等分布式文件系統真的會存儲數據嗎
HDFS(Hadoop分布式文件系統)是一種分布式文件系統,它主要用於存儲大量的數據,並提供高可靠性和高吞吐量的數據訪問。因此,HDFS是能夠真正存儲數據的分布式文件系統。
與傳統的文件系統相比,HDFS有如下優點:
容錯性:HDFS可以自動修復硬體故障,並保證數據的完整性和安全性。
可配李擴展性:HDFS可以根據數據量的增長而慶賣掘擴展容量,並可以支持數千個節點。
數據並行處理:HDFS可以分割數據塊並並行處理,提高數據處理速度。
總之,HDFS是真正的分布式文件系統,可以用於存儲大量的數據,譽核並提供高性能的數據訪問。
㈨ 什麼是HDFS硬碟分布式存儲
Namenode 是一個中心伺服器,單一節點(簡化系統的設計和實現),負責管理文件系統的名字空間(namespace)以及客戶端對文件的訪問。
文件操作,NameNode 負責文件元數據的操作,DataNode負責處理文件內容的讀寫請求,跟文件內容相關的數據流不經過NameNode,只會詢問它跟哪個DataNode聯系,否則NameNode會成為系統的瓶頸。
副本存放在哪些DataNode上由 NameNode來控制,根據全局情況做出塊放置決定,讀取文件時NameNode盡量讓用戶先讀取最近的副本,降低帶塊消耗和讀取時延
Namenode 全權管理數據塊的復制,它周期性地從集群中的每個Datanode接收心跳信號和塊狀態報告(Blockreport)。接收到心跳信號意味著該Datanode節點工作正常。塊狀態報告包含了一個該Datanode上所有數據塊的列表。
NameNode支持對HDFS中的目錄、文件和塊做類似文件系統的創建、修改、刪除、列表文件和目錄等基本操作。 塊存儲管理,在整個HDFS集群中有且只有唯一一個處於active狀態NameNode節點,該節點負責對這個命名空間(HDFS)進行管理。
1、Name啟動的時候首先將fsimage(鏡像)載入內存,並執行(replay)編輯日誌editlog的的各項操作;
2、一旦在內存中建立文件系統元數據映射,則創建一個新的fsimage文件(這個過程不需SecondaryNameNode) 和一個空的editlog;
3、在安全模式下,各個datanode會向namenode發送塊列表的最新情況;
4、此刻namenode運行在安全模式。即NameNode的文件系統對於客服端來說是只讀的。(顯示目錄,顯示文件內容等。寫、刪除、重命名都會失敗);
5、NameNode開始監聽RPC和HTTP請求
解釋RPC:RPC(Remote Procere Call Protocol)——遠程過程通過協議,它是一種通過網路從遠程計算機程序上請求服務,而不需要了解底層網路技術的協議;
6、系統中數據塊的位置並不是由namenode維護的,而是以塊列表形式存儲在datanode中;
7、在系統的正常操作期間,namenode會在內存中保留所有塊信息的映射信息。
存儲文件,文件被分成block存儲在磁碟上,為保證數據安全,文件會有多個副本 namenode和client的指令進行存儲或者檢索block,並且周期性的向namenode節點報告它存了哪些文件的blo
文件切分成塊(默認大小128M),以塊為單位,每個塊有多個副本存儲在不同的機器上,副本數可在文件生成時指定(默認3)
NameNode 是主節點,存儲文件的元數據如文件名,文件目錄結構,文件屬性(生成時間,副本數,文件許可權),以及每個文件的塊列表以及塊所在的DataNode等等
DataNode 在本地文件系統存儲文件塊數據,以及塊數據的校驗和。
可以創建、刪除、移動或重命名文件,當文件創建、寫入和關閉之後不能修改文件內容。
NameNode啟動流程
1、Name啟動的時候首先將fsimage(鏡像)載入內存,並執行(replay)編輯日誌editlog的的各項操作;
2、一旦在內存中建立文件系統元數據映射,則創建一個新的fsimage文件(這個過程不需SecondaryNameNode) 和一個空的editlog;
3、在安全模式下,各個datanode會向namenode發送塊列表的最新情況;
4、此刻namenode運行在安全模式。即NameNode的文件系統對於客服端來說是只讀的。(顯示目錄,顯示文件內容等。寫、刪除、重命名都會失敗);
5、NameNode開始監聽RPC和HTTP請求
解釋RPC:RPC(Remote Procere Call Protocol)——遠程過程通過協議,它是一種通過網路從遠程計算機程序上請求服務,而不需要了解底層網路技術的協議;
6、系統中數據塊的位置並不是由namenode維護的,而是以塊列表形式存儲在datanode中;
7、在系統的正常操作期間,namenode會在內存中保留所有塊信息的映射信息。
HDFS的特點
優點:
1)處理超大文件
這里的超大文件通常是指百MB、數百TB大小的文件。目前在實際應用中,HDFS已經能用來存儲管理PB級的數據了。
2)流式的訪問數據
HDFS的設計建立在更多地響應"一次寫入、多次讀取"任務的基礎上。這意味著一個數據集一旦由數據源生成,就會被復制分發到不同的存儲節點中,然後響應各種各樣的數據分析任務請求。在多數情況下,分析任務都會涉及數據集中的大部分數據,也就是說,對HDFS來說,請求讀取整個數據集要比讀取一條記錄更加高效。
3)運行於廉價的商用機器集群上
Hadoop設計對硬體需求比較低,只須運行在低廉的商用硬體集群上,而無需昂貴的高可用性機器上。廉價的商用機也就意味著大型集群中出現節點故障情況的概率非常高。這就要求設計HDFS時要充分考慮數據的可靠性,安全性及高可用性。
缺點:
1)不適合低延遲數據訪問
如果要處理一些用戶要求時間比較短的低延遲應用請求,則HDFS不適合。HDFS是為了處理大型數據集分析任務的,主要是為達到高的數據吞吐量而設計的,這就可能要求以高延遲作為代價。
2)無法高效存儲大量小文件
因為Namenode把文件系統的元數據放置在內存中,所以文件系統所能容納的文件數目是由Namenode的內存大小來決定。一般來說,每一個文件、文件夾和Block需要佔據150位元組左右的空間,所以,如果你有100萬個文件,每一個占據一個Block,你就至少需要300MB內存。當前來說,數百萬的文件還是可行的,當擴展到數十億時,對於當前的硬體水平來說就沒法實現了。還有一個問題就是,因為Map task的數量是由splits來決定的,所以用MR處理大量的小文件時,就會產生過多的Maptask,線程管理開銷將會增加作業時間。舉個例子,處理10000M的文件,若每個split為1M,那就會有10000個Maptasks,會有很大的線程開銷;若每個split為100M,則只有100個Maptasks,每個Maptask將會有更多的事情做,而線程的管理開銷也將減小很多。
1280M 1個文件 10block*150位元組 = 1500 位元組 =1.5KB
1280M 12.8M 100個 100個block*150位元組 = 15000位元組 = 15KB
3)不支持多用戶寫入及任意修改文件
在HDFS的一個文件中只有一個寫入者,而且寫操作只能在文件末尾完成,即只能執行追加操作。目前HDFS還不支持多個用戶對同一文件的寫操作,以及在文件任意位置進行修改。
四、HDFS文件 讀寫流程
4.1 讀文件流程
(1) 打開分布式文件
調用 分布式文件 DistributedFileSystem.open()方法。
(2) 從 NameNode 獲得 DataNode 地址
DistributedFileSystem 使用 RPC 調用 NameNode, NameNode返回存有該副本的 DataNode 地址, DistributedFileSystem 返回一個輸入流 FSDataInputStream對象, 該對象封存了輸入流DFSInputStream。
(3) 連接到DataNode
調用 輸入流 FSDataInputStream 的 read() 方法, 從而輸入流DFSInputStream 連接 DataNodes。
(4) 讀取DataNode
反復調用 read()方法, 從而將數據從 DataNode 傳輸到客戶端。
(5) 讀取另外的DataNode直到完成
到達塊的末端時候, 輸入流 DFSInputStream 關閉與DataNode 連接,尋找下一個 DataNode。
(6) 完成讀取, 關閉連接
即調用輸入流 FSDataInputStream.close() 。
4.2 寫文件流程
(1) 發送創建文件請求: 調用分布式文件系統DistributedFileSystem.create()方法;
(2) NameNode中創建文件記錄: 分布式文件系統DistributedFileSystem 發送 RPC 請求給namenode, namenode 檢查許可權後創建一條記錄, 返回輸出流 FSDataOutputStream, 封裝了輸出流 DFSOutputDtream;
(3) 客戶端寫入數據: 輸出流 DFSOutputDtream 將數據分成一個個的數據包, 並寫入內部隊列。 DataStreamer 根據 DataNode 列表來要求 namenode 分配適合的新塊來存儲數據備份。一組DataNode 構成管線(管線的 DataNode 之間使用 Socket 流式通信)
(4) 使用管線傳輸數據: DataStreamer 將數據包流式傳輸到管線第一個DataNode, 第一個DataNode 再傳到第二個DataNode ,直到完成。
(5) 確認隊列: DataNode 收到數據後發送確認, 管線的DataNode所有的確認組成一個確認隊列。 所有DataNode 都確認, 管線數據包刪除。
(6) 關閉: 客戶端對數據量調用close() 方法。 將剩餘所有數據寫入DataNode管線, 並聯系NameNode且發送文件寫入完成信息之前等待確認。
(7) NameNode確認
(8) 故障處理: 若過程中發生故障, 則先關閉管線, 把隊列中所有數據包添加回去隊列, 確保數據包不漏。 為另一個正常DataNode的當前數據塊指定一個新的標識, 並將該標識傳送給NameNode, 一遍故障DataNode在恢復後刪除上面的不完整數據塊. 從管線中刪除故障DataNode 並把餘下的數據塊寫入餘下正常的DataNode。 NameNode發現復本兩不足時, 會在另一個節點創建一個新的復本
㈩ hadoop面試題之HDFS
1、簡單介紹下hadoop吧?
廣義上hadoop是指與hadoop相關的大數據生態圈。包含hive、spark、hbase等。
狹義上hadoop指的是apache的開源框架。有三個核心組件:
----hdfs:分布式文件存儲系統
----yarn:分布式資源管理調度平台
----mr:分布式計算引擎
2、介紹下hdfs?
全稱為Hadoop Distributed File System。有三個核心組件:
namenode:有三個作用,第一是負責保存集群的元數據信息,第二是負責維護整個集群節點的正常運行。
第三是負責處理客戶端的請求。
datanode:負責實際保存數據。實際執行數據塊的讀寫操作。
secondarynamenode:輔助namenode進行元數據的管理。不是namenode的備份。
3、namenode的工作機制?
namenode在內存中保存著整個內存系統的名稱空間和文件數據塊的地址映射。整個hdfs可存儲的文件數受限於namenode的內存大小。所以hdfs不適合大量小文件的存儲。
---namenode有三種元數據存儲方式來管理元數據:
》內存元數據:內存中保存了完整的元數據
》保存在磁碟上的元數據鏡像文件(fsimage):該文件時hdfs存在磁碟中的元數據檢查點,裡面保存的是最後一次檢查點之前的hdfs文件系統中所有目錄和文件的序列化信息。
》數據操作日誌文件(edits):用於銜接內存meta data和持久化元數據鏡像fsimage之間的操作日誌文件。保存了自最後一次檢查點之後所有針對hdfs文件系統的操作。如對文件的增刪改查。
4、如何查看元數據信息?
因為edits和fsimage文件是經過序列化的,所以不能直接查看。hadoop2.0以上提供了查看兩種文件的工具。
----命令:hdfs oiv 可以將fsimage文件轉換成其他格式,如xml和文本文件。-i 表示輸入fsimage文件。-o 輸出文件路徑,-p 指定輸出文件
hdfs oev可以查看edits文件。同理需要指定相關參數。
詳情查看: https://www.imooc.com/article/79705
4、datanode的工作機制?
1)以數據塊的形式存儲hdfs文件
2)datanode響應客戶端的讀寫請求
3)周期性的向namenode匯報心跳信息、數據塊信息、緩存數據塊信息
5、secondary namenode工作機制?
當發生checkpoint機制時會觸發second namenode進行工作。checkpoint:
新的edists文件不會立即和fsimage文件合並,是在edits文件大小超過(默認)64m,或者時間超過(默認)1小時,會觸發checkpoint操作。當checkpoint時,namenode會新建一個edits.new的文件,此時second namenode將文件fsimage文件和edits文件(http get)到本地,然後載入到內存中進行合並,完成的文件名稱為fsimage.ckpt。最後 second namenode將該文件(http post)到namenode,然後edits.new和fsimage.ckpt文件轉換為fsimage和edits。
6、hdfs的文件副本機制?
所有的文件都是以塊的形式保存到hdfs中。塊的大小默認為128m。在hdfs-site文件中進行指定。
動態副本創建策略:默認副本數是3,可以在上傳文件時,顯式設定replication。也可以通過指令修改文件的副本數 hadoop fs -setrep -R 1
7、為實現高可用,hdfs採用了哪些策略?
副本機制、機架感知、心跳機制、安全模式、校驗和、回收站、元數據保護、快照機制(具體介紹導航- https://www.jianshu.com/writer#/notebooks/44567747/notes/66453316 )
8、hdfs的存儲過程?
①client向hdfs發起寫請求,通過RPC與namenode建立通訊。namenode檢查文件是否存在等信息,返回是否可以存儲。
②client將文件切割為一個個block塊,client申請存儲第一塊block。namenode返回可以存儲這個block塊的datanode的地址,假設為ABC。
③A到B到C逐級構建pipeline。client向A上傳第一個packet,默認為64k。A收到一個packet後會將packet傳給B,再傳給C。pipeline反方向返回ack信息。最終由第一個節點A將pipelineack發送給client
④一個block完成之後,再進行下一個block的存儲過程。
9、hdfs的讀過程?
10、hdfs的垃圾桶機制?
hdfs的垃圾桶機制默認是關閉的,需要手動開啟。hdfs刪除的文件不會立刻就刪除,而是在設定的時間後進行刪除。
11、hdfs的擴容和縮容
【
12、