Hadoop 基石HDFS 一文了解檔案儲存系統

流年細品溫如言發表於2021-06-04

@

前言:淺談Hadoop

Hadoop作為大資料入門的基石內容,其中HDFS更是所有生態的地基,so,我們有必要更深入去理解HDFS,以及HDFS在高可用的演變過程。如果有小可愛說hadoop和HDFS有啥區別的。の。。。,那容我之後在做背書來說明,暖男行為的先提一下:目前我們所說的Hadoop更多是指Hadoop的生態,包括hadoop本身及其他元件,如flume、kafka、hive、Hbase等等,如下圖所示:
在這裡插入圖片描述
其中hadoop本身的結構(以Hadoop2.x為例,3.x亦復如是)如下:
在這裡插入圖片描述

Hadoop的發展歷程

1.1 Hadoop產生背景

Hadoop最早起源於Nutch 。Nutch是一個開源的網路搜尋引擎,由Doug Cutting於2002年建立。Nutch的設計目標是構建一個大型的全網搜尋引擎,包括網 頁抓取、索引、查詢等功能,但隨著抓取網頁數量的增加,遇到了嚴重的可擴充套件性問 題,即不能解決數十億網頁的儲存和索引問題。之後,谷歌發表的兩篇論文為該問題 提供了可行的解決方案。一篇是2003年發表的關於谷歌分散式檔案系統(GFS)的論 文。該論文描述了谷歌搜尋引擎網頁相關資料的儲存架構,該架構可解決Nutch遇 到的網頁抓取和索引過程中產生的超大檔案儲存需求的問題。但由於谷歌僅開源了思 想而未開原始碼,Nutch專案組便根據論文完成了一個開源實現,即Nutch的分散式 檔案系統(NDFS)。另一篇是2004年發表的關於谷歌分散式計算框架MapReduce 的論文。該論文描述了谷歌內部最重要的分散式計算框架MapReduce的設計藝術, 該框架可用於處理海量網頁的索引問題。同樣,由於谷歌未開原始碼,Nutch的開發 人員完成了一個開源實現。由於NDFS和MapReduce不僅適用於搜尋領域,2006年 年初,開發人員便將其移出Nutch,成為Lucene [4]的一個子專案,稱為Hadoop。大 約同一時間,Doug Cutting加入雅虎公司,且公司同意組織一個專門的團隊繼續發 展Hadoop。同年2月,Apache Hadoop專案正式啟動以支援MapReduce和HDFS 的獨立發展。2008年1月,Hadoop成為Apache頂級專案,迎來了它的快速發展期。
文字必定是比較枯燥的,貼心為大家準備一個時間樹:
在這裡插入圖片描述

1.引入HDFS設計

HDFS作為Hadoop的旗艦級檔案系統(也就是說除了HDFS,Hadoop也可以與其他檔案儲存系統整合,所以不能簡單認為HDFS和Hadoop是有等價關係的哦。),被定義為以流式資料訪問模式來儲存超大檔案,執行於廉價的商用硬體叢集上。
我們解讀一下其定義:

  • 超大檔案 。即超過幾百MB或者GB甚至幾百TB大小的檔案來充分發揮其優勢;
  • 流式資料訪問:也是HDFS的構建思想:一次寫入、多次讀取是最高效的訪問模式。資料集通常由資料來源生成或者從資料來源複製而來,此後長時間在此資料集上進行各種分析,因此其讀取資料的時間延遲不滿足即席查詢。HDFS是為高資料吞吐量應用優化的,對於低時間延遲的資料訪問是不適合的,這是其優點也在某種程度看是缺點。

1.1 HDFS主要特性

  • 支援超大檔案。超大檔案這裡指的是幾百MB、幾百GB甚至幾TB大小的檔案,一般來說,一個Hadoop檔案系統會儲存T(1T=1024GB)、P(1P=1024TB)級別的資料。Hadoop需要能夠支援這種級別的大檔案;
  • 檢測和快速應對硬體故障:在大量通用硬體平臺上構建叢集時,故障,特別是硬體故障是常見的問題。一般的HDFS系統是由數百臺甚至上千臺儲存者資料檔案的伺服器組成,這麼多的伺服器意味著高故障率。因此,過賬檢測和自動恢復是HDFS的一個設計目標;
  • 流式資料訪問:HDFS處理的資料規模都比較大,應用一般需要訪問大量的資料。同時,這些應用一般是批量處理,而不是使用者互動式處理。HDFS使應用程式能夠以流的形式訪問資料集,注重的是資料的吞吐量,而不是資料訪問的速度;
  • 簡化的一致性模型:大部分的HDFS程式操作檔案是需要一次寫入,多次讀取。在HDFS中,一個檔案一旦經過建立、寫入、關閉後,一半就不需要修改了。這樣簡單的一致性模型,有利於提供高吞吐量的資料訪問模型。

2.HDFS體系結構

在一個全配置的叢集上,“執行HDFS”意味著在網路分佈的不同伺服器上執行一些守護程式(daemon),這些程式有各自的特殊角色,並相互配合,一起形成一個分散式檔案系統。
HDFS採用了主從(Master/Slaver)體系結構,名位元組點 NameNode、資料節點DataNode和客戶端Client是HDFS的三個重要的角色。
在這裡插入圖片描述

  • NameNode 管理檔案系統的名稱空間,維護者檔案系統及整棵樹內所有的檔案和目錄。這些資訊以兩個檔案形式永久儲存在本地磁碟中:名稱空間映象檔案(Fsimagexxx)和編輯日誌檔案(editxxx)。NameNode 也記錄著每個檔案中各個塊所在的資料節點資訊,但是並不會永久儲存塊的位置資訊,而是在系統啟動的時候根據資料節點資訊重建(在系統啟動的時候,各個DataNode會向NameNode進行註冊,同時彙報資料節點的資訊)。
  • SecondaryNameNode,也稱SNN或2NN,是用於定期合併名稱空間映象和映象編輯日誌的輔助守護程式。其與NameNode的區別是,2NN不接受或者說不記錄HDFS的任何實時變化,而只是根據叢集配置的時間間隔,不停的獲取HDFS某一個時間點的名稱空間映象和映象編輯日誌,合併得到一個新的名稱空間映象。該新映象會上傳到NameNode,替換原有的名稱空間映象,並清空上述日誌。2NN配合NameNode,為NameNode提供了一個簡單的檢查點(checkpoint)機制,並避免出現編輯日誌過大,導致NameNode啟動時間過長的問題。
  • DataNode 是檔案系統的工作節點,再其內部都會駐留一個資料節點的守護程式,來執行分散式檔案系統中最忙碌的部分:將HDFS資料塊寫到Linux本地檔案系統的事件檔案中,或者從這些實際檔案讀取資料塊。它們根據需要儲存並檢索資料塊(受客戶端和NameNode排程),並定期(心跳為每三秒一次,當NameNode10分鐘沒有接受到DataNode的心跳就認為節點不可用,傳送資訊為每一小時一次)向NameNode傳送他們所儲存的塊的列表。
    通常DataNode從磁碟讀取資料塊,但是對於訪問頻繁的檔案,其對應的塊可能被顯式的快取在DataNode的記憶體中,以堆外快快取的形式存在。預設情況下一個塊僅快取一個DataNode的記憶體中。作業排程器(用於MapReduce、Spark和其他框架的)通過在快取塊的DataNode上執行任務,可以利用塊快取的優勢提高讀操作的效能。
  • 客戶端:使用者與HDFS進行互動的手段。HDFS提供了各種各樣的客戶端,包括命令列介面、JavaAPI、使用者檔案系統等等。

此外,由於NameNode將檔案系統的後設資料儲存在記憶體中,因此一個HDFS檔案系統所能儲存的檔案總數受限於NameNode的記憶體容量(一般一個檔案、目錄和資料塊的儲存資訊即後設資料大約佔150位元組)。因此當有一百萬個檔案,且每個檔案佔一個資料塊,至少需要300M的記憶體。注意一點:Hadoop的資料是分塊在物理儲存的(hadoop2.x及之後版本,塊預設其大小為128M,塊的劃分大小隻和磁碟的傳輸速率強正相關),但是在DataNode節點實際佔用的空間大小和檔案真實大小一致,而不是佔據整個塊的空間(當一個1MB的檔案存在一個一個128MB的塊中時,檔案只是用1MB的磁碟空間,而不是128MB)。

簡單的速算,當定址時間為10ms,磁碟傳輸速率為100M/S,一般經驗認為定址時間佔傳輸時間的1%為佳,so,傳輸時間即為1s,故大小為100M,儲存單位都是二進位制,故設定為128MB,如果磁碟傳輸速率為500M時,那麼相應的塊大小可以設定為512MB,可以通過配置引數dfs.blocksize 來設定。

有必要說明一下:分散式檔案系統中的塊抽象帶來的好處:

1.一個檔案的大小可以大於網路中任意一個磁碟的容量,(也就是說我們需要的檔案有2T,但是單個節點的儲存只有1T,這也是Hadoop應用的得意之處)。檔案的塊並不需要儲存在同一個磁碟上,我們將大檔案按塊劃分為多個檔案,並將這些塊儲存在任意的節點磁碟進行儲存。

2.使用抽象塊而不是整個檔案作為儲存單元,大大簡化了儲存子系統的設計。將儲存子系統的處理獨享設定為塊,可簡化儲存管理,由於塊的大小是固定,因此計算單個磁碟可以儲存多少個塊就相對簡單。同事也消除了對後設資料的顧慮,塊只是來儲存資料,並不儲存檔案的後設資料,就可以將資料和後設資料分離,單獨管理後設資料。

3.塊的抽象非常適合資料備份,將每個塊複製到幾個物理上互相獨立的節點(預設為3),可以確保在塊、磁碟或者機器發生故障後資料不會丟失。如果發現一個塊不可用,系統會從其他地方讀取另一個副本,而這個過程對使用者是透明的。且當一個損壞或機器故障而丟失的塊可以從其他儲存的節點複製到另一臺正常執行的機器上,保證複本數量是滿足設定的。進而提供了系統資料容錯能力和可用性。

HDFS工作流程機制

當我們向HDFS上傳資料的時候是怎麼進行,HDFS是如何工作的呢?基於NameNode和DataNode分別都做了那些工作呢?我們一一道來。

1.各個節點是如何互通有無的?

分散式系統,如瀏覽器和伺服器端的通訊,需要在不同的實體中顯示交換資訊,處理諸如訊息的編解碼、傳送和接收等具體任務。Hadoop中各個實體間的互動通過遠端過程呼叫(RPC),讓使用者可以像呼叫本地方法一樣呼叫另外一個應用程式提供的服務,而不必關注具體的實現。從而提升了可操作性和互動性。那我們先來了解一下什麼是RPC。

RPC原理

簡要地說,RPC就是允許程式呼叫位於其他機器上的過程(也可以是同一臺機器上的不同的程式)。當機器A上的程式呼叫機器B上的程式時,A上的呼叫程式被掛起,而B上的被呼叫程式開始執行。呼叫方使用引數將資訊傳送給到被呼叫方,然後通過傳回的結果得到資訊。在這個過程中,A是RPC客戶端,B是RPC服務端。同時我們不用關注任何訊息的傳遞,就像在一個過程到另一個過程的呼叫一樣,如同方法的呼叫。

class ProgressDemo{
	public static void main(String[] args){
		...
		func(a1,a2,...,an);
		...
	}
	
	public static int func(int p1,int p2,... ,int pn){
		...
	}
}

上邊是一個簡單的常規過程呼叫
在這裡插入圖片描述
RPC呼叫示例
在這裡插入圖片描述
RPC的Server執行時會阻塞在接受訊息的呼叫上,當接到客戶端的請求後,它會解包以獲取請求引數,類似於傳統過程呼叫,被呼叫函式從棧中接受引數,然後確定呼叫過程的名字並呼叫相應過程。呼叫結束後,返回值通過主程式打包併傳送回客戶端,通知客戶端呼叫結束。

我們對於RPC先有一個大致映象,幫助我們理解後續的一些內容,具體的RPC實現可以參考分散式系統相關內容。

客戶端操作檔案與目錄

我們從客戶端到NameNode有大量的後設資料操作,比如修改檔名,建立子目錄等。這些操作只涉及到客戶端和NameNode的互動。

剖析檔案寫入HDFS
在這裡插入圖片描述

  • 1 (步驟1)客戶端通過對Distributed FileSystem物件呼叫create() 來新建檔案

  • 2(步驟2、3).Distributed FileSystem 對NameNode 建立一個RPC(Remote Procedure Call Protocol 遠端過程呼叫協議)呼叫(關於RPC呼叫,可看這裡什麼是RPC呼叫),讓NameNode執行同名方法,在檔案系統中的名稱空間中新建一個檔案,此時該檔案還沒有相應的資料塊。NameNode建立新檔案時,執行各種不同的檢查以確保這個檔案不存在以及客戶端有新建該檔案的許可權等等。如果這些檢查通過,NameNode就會構建一個新檔案,並記錄建立操作到編輯日誌edits中;否則,當使用者沒有許可權或者預設情況下沒有說明覆蓋檔案的情況下,會發生檔案建立失敗並向客戶端丟擲一個IOException異常。通過檢查之後,DistributedFileSystem向客戶端返回一個FSDataOutputStream物件,FSDataOutputStream封裝一個DFSOutputStream物件(DFSOutputStream是對應的例項物件),此物件處理DataNode和NameNode之間的通訊。
    用更通俗的話來說,這一步可以細分為兩個步驟,Distributed FileSystem 一下簡寫DFS。

    • I 客戶端通過DFS物件對NameNode傳送請求建立一個和上傳檔案同名的空檔案,此時NameNode會檢測是否有同名檔案以及請求方是否有建立檔案的許可權。這個時候會根據檢查結果返回不同的響應結果。
    • II 若檢查通過,DFS物件會給客戶端一個FSDataOutputStream物件,就像是給客戶端一個寫入資料的入口,客戶端不必關心具體是向那些DataNode傳送資料的,這些工作都交給FSDataOutputStream中的DFSOutputStream例項物件來完成,客戶端就向此物件寫入資料流即可。
  • 3(步驟4、5) 在客戶端寫入資料時,DFSOutputStream將它分成一個個資料包,並寫入內部佇列,稱為“資料佇列”。DataStreamer處理資料佇列,其責任是挑選出適合儲存資料複本的一組DataNode(此處挑選DataNode的原則要素為複本數量和節點就近距離(拓撲網路)),並要求NameNode分配新的資料塊,因為上步我們只是建立了一個空檔案,所以DFSOutputStream例項首先向NameNode節點申請資料塊,申請成功之後(內部呼叫addBlock()方法,返回是否成功),就獲得對應的資料塊物件(此物件包含資料塊的資料塊表示和版本號)。這一組DataNode就構成了一個管線,複本數量決定了管線中節點的數量,預設複本數為3,則節點有三臺。DataStreamer將資料包流式傳輸到管線中第一個DataNode,該DataNode儲存資料包並將它傳送到管線中的第2個DataNode。同樣,第2個DataNode儲存該資料包並且傳送給第3個(也就是最後一個)DataNode。
    在這裡插入圖片描述

  • 4(步驟6)DFSOutputStream也維護著一個內部資料包佇列來等待DataNode的收到確認回執,成為“確認佇列(ack queue)”。收到管道中所有DataNode確認資訊後,該資料包才會從確認佇列刪除。
    如果任何DataNode在資料寫入期間發生故障,則執行以下操作(對客戶端是透明的)。首先關閉管線,確認把佇列中的所有資料包都新增回資料佇列的最前端,以確保故障節點下游的DataNode不會漏掉任何一個資料包。為儲存在另一正常DataNode的當前資料塊指定一個新的標識,並將該標識傳送給NameNode,以便故障DataNode在恢復後可以刪除儲存的部分資料塊。從管線中刪除故障DataNode,基於正常的DataNode重新構建一條新管線。餘下的資料塊寫入管線中正常的DataNode。NameNode注意到塊複本量不足時,會在另一個節點上建立一個新的複本。
    在這裡插入圖片描述

  • 5(步驟7、8)客戶端完成資料寫入後,對資料流呼叫close()方法,意味著客戶單不會再向六中寫入資料。該操作將剩餘的所有資料包寫入DataNode管線,並在聯絡到NameNode告知其檔案寫入完成之前,等待確認(步驟8)。NameNode已經知道檔案有哪些塊組成(因為DataStreamer請求分配資料塊),所以他在返回成功前只需要等待資料塊進行最小量的複製。

剖析HDFS檔案讀取
在這裡插入圖片描述
為了瞭解客戶端及與之互動的HDFS、NameNode和DataNode之間的資料流,我們參考上圖解釋一下讀取檔案是發生的事件順序。

  • 1)客戶端通過呼叫FileSystem(Java API )物件的open()方法來開啟希望讀取的檔案,對於HDFS來說,該物件是DistributedFileSystem的一個例項;
  • 2)DFS(DistributedFileSystem)通過使用遠端過程呼叫(RPC)來呼叫NameNode,以確定檔案起始塊的位置,對於每一個塊,NameNode返回存有該副本的DataNode地址。DataNode的選擇依舊是依據叢集的網路拓撲排序。(如果該客戶端本身就是一個DataNode【比如:在一個MapReduce任務中】,那麼客戶端就會從儲存有相應資料塊複本的本地DataNode讀取資料);
  • 3)DFS類返回一個FSDataInputStream物件(一個支援檔案的輸入流)給客戶端以便讀取資料。FSDataInputStream 類內封裝DFSInputStream物件,由該物件管理DataNode和NameNode的I/O。接著客戶端對這個輸入流呼叫read()方法。
  • 4)儲存檔案起始幾個塊的DataNode地址的DFSInputStream隨機連線距離最近的檔案中第一個塊所在的DataNode。通過對資料流反覆呼叫read()方法,將資料從DataNode傳輸到客戶端。到達塊的末端時,DFSInputStream關閉與該DataNode的連線,然後尋找下一個塊的最佳DataNode。所有操作對於客戶端都是透明的,對客戶端而言都是讀取一個連續的流。
  • 5)客戶端從流中讀取資料時,塊是按照開啟DFSInputStream與DataNode新建連線的順序讀取的。會根據需要詢問NameNode來檢索下一批資料塊的DataNode位置。一旦客戶端完成讀取,就對FSDataInputStream呼叫close()方法。

在整個讀取過程中,如果DFSInputStream與DataNode通訊時遇到錯誤,會嘗試從這個快的另外一個最近鄰DataNode讀取資料,也會記住故障DataNode,保證以後不會反覆讀取該節點上後續的塊。DFSInputStream也會通過校驗和確認從DataNode發來的資料是否完整。如果發現有損壞的塊,DFSInputStream會試圖從其他DataNode讀取其複本,同時會將損壞的塊通知NameNode。

結論

因而,沒有NameNode,整個HDFS將無法使用。事實上,如果執行NameNode服務的及其損壞,檔案系統上所有的檔案將會丟失,因為我們不知道如何根據DataNode的塊重建檔案。

HDFS是怎麼保證執行的?

NameNode 容錯機制

因此,對於NameNode實現容錯非常重要,Hadoop為此提供了兩種機制。

  • 1.第一種機制是備份那些組成檔案系統後設資料持久狀態的檔案。Hadoop可以通過配置使NameNode在多個檔案系統上儲存後設資料的持久狀態。這些寫操作是實時同步且是原子性的。當時NameNode的處理效率會變低,實時去持久化是不被接受的。一般的配置:將持久狀態寫入本地磁碟的同時,寫入一個遠端掛在的網路檔案系統(NFS)。
  • 2執行一個輔助NameNode,但不能被用作NameNode。這個輔助NameNode的重要作用是 定期合併編輯日誌與名稱空間映象,以防止編輯日誌過大。這個輔助NameNode一般在另一臺單獨的物理計算機上執行,他需要佔用大量CPU時間,並且需要和NameNode一樣多的記憶體來執行合併操作。他會儲存合併後的名稱空間映象的副本,並在NameNode發生故障時啟動。但是輔助NameNode儲存的狀態總是滯後於主節點,所以在主節點全部失效時,難免會丟失部分資料。這種情況下,一般是將儲存在NFS的NameNode後設資料複製到輔助NameNode並作為新的主NameNode執行。

方式二的部分也正是hadoop2.x就有的方式,配置NameNode(NN)和secondNameNode(2NN)。且2NN可以將NameNode的映象檔案和編輯日誌檔案合併過程接手處理,減少NameNode的額外開銷。具體的NN和2NN之間的處理關係會稍後詳細在講。

如何NN突破記憶體限制?聯邦HDFS設計思想

NameNode在記憶體中儲存檔案系統中每個檔案和每個資料塊的引用關係。意味著對於一個擁有大量檔案的超級叢集而言,單臺NameNode記憶體限制了系統橫向擴充套件的瓶頸。
且根據NameNode的架構侷限性:
1)Namespace(名稱空間)的限制
由於NameNode在記憶體中儲存所有的後設資料(metadata),因此單個NameNode所能儲存的物件(檔案+塊)數目受到NameNode所在JVM的heap size的限制。50G的heap能夠儲存20億(200million)個物件,這20億個物件支援4000個DataNode,12PB的儲存(假設檔案平均大小為40MB)。隨著資料的飛速增長,儲存的需求也隨之增長。單個DataNode從4T增長到36T,叢集的尺寸增長到8000個DataNode。儲存的需求從12PB增長到大於100PB。
2)隔離問題
由於HDFS僅有一個NameNode,無法隔離各個程式,因此HDFS上的一個實驗程式就很有可能影響整個HDFS上執行的程式。
3)效能的瓶頸
由於是單個NameNode的HDFS架構,因此整個HDFS檔案系統的吞吐量受限於單個NameNode的吞吐量。

在2.x的發行版本引入了 HDFS Federation(聯邦HDFS),該方案允許系統通過新增NameNode實現擴充套件,其中每個NameNode管理檔案系統名稱空間中的一部分。例如,一個NameNode可能管理/user目錄下的所有檔案,而另一個NameNode管理/share 目錄下的所有檔案。

如何解決單點故障問題?

通過聯合使用在多個檔案系統中備份NameNode的後設資料和通過備用NameNode建立檢測點能防止資料丟失,但是依舊無法實現檔案系統的高可用性。NameNode依舊存在單點失效(SPOF,single point of failure )的問題。如果NameNode失效了,那麼所有的客戶端包括MapReduce作業,均無法工作,以為內NameNode是唯一儲存後設資料與檔案到資料塊對映的地方。

想要一個失效的NameNode恢復,系統管理員的啟動一個擁有檔案系統後設資料副本的新的NameNode,並配置DataNode和客戶端使用這個新的NameNode。新的NameNode需要滿足以下情況才能響應服務:

  • 1)將名稱空間的映像匯入記憶體中
  • 2) 重演編輯日誌;
  • 3) 接受到足夠多的來自DataNode的資料塊報告並退出安全模式。
    對於一個大型並擁有大量檔案和資料塊的叢集,NameNode的冷啟動需要30分鐘,或者更長時間。系統恢復時間太長,也會影響到日常維護。

Hadoop2 針對以上問題增加了對HDFS的高可用性(HA)的支援。通過配置一對活動-備用 NameNode。當活動NameNode失效, 備用NameNode就會接管他的任務並開始服務與來自客戶端的請求,不會有任何明顯的中斷。也就是NN和2NN之間的處理邏輯。HA會在後邊再開一篇來討論它的實現以及好處。

我們先來了解一下NN和2NN的工作機制。
我們在上邊已經說了NameNode的後設資料儲存是通過FsImage和Edits日誌檔案來完成的。為什麼會有這樣的設計?

我們不妨假設,如果後設資料儲存在NameNode節點的磁碟中,因為經常需要進行隨機訪問,還有響應客戶請求,必然是效率過低。因此,後設資料需要存放在記憶體中。
但如果只存在記憶體中,一旦斷電,後設資料丟失,整個叢集就無法工作了。因此產生在磁碟中備份後設資料的FsImage。這樣又會帶來新的問題,當在記憶體中的後設資料更新時,如果同時更新FsImage,就會導致效率過低,但如果不更新,就會發生一致性問題,一旦NameNode節點斷電,就會產生資料丟失。

因此,引入Edits檔案(只進行追加操作,效率很高)。每當後設資料有更新或者新增後設資料時,修改記憶體中的後設資料並追加到Edits中。這樣,一旦NameNode節點斷電,可以通過FsImage和Edits的合併,合成後設資料。

但是,如果長時間新增資料到Edits中,會導致該檔案資料過大,效率降低,而且一旦斷電,恢復後設資料需要的時間過長。因此,需要定期進行FsImage和Edits的合併,如果這個操作由NameNode節點完成,又會效率過低。因此,引入一個新的節點SecondaryNamenode,專門用於FsImage和Edits的合併。

在這裡插入圖片描述

NameNode啟動

  • (1)第一次啟動NameNode格式化後,建立Fsimage和Edits檔案。如果不是第一次啟動,直接載入編輯日誌和映象檔案到記憶體。
  • (2)客戶端對後設資料進行增刪改的請求。
  • (3)NameNode記錄操作日誌,更新滾動日誌。
  • (4)NameNode在記憶體中對後設資料進行增刪改。

Secondary NameNode工作

  • (1)Secondary NameNode詢問NameNode是否需要CheckPoint(checkpoint在2NN預設每隔一小時執行一次checkpoint檢測,檢視是否需要execute checkpoint,並每一分鐘進行一次運算元檢測,當運算元達100萬時,2NN執行checkpoint)。直接帶回NameNode是否檢查結果。
  • (2)Secondary NameNode請求執行CheckPoint。
  • (3)NameNode滾動正在寫的Edits日誌。
  • (4)將滾動前的編輯日誌和映象檔案拷貝到Secondary NameNode。
  • (5)Secondary NameNode載入編輯日誌和映象檔案到記憶體,併合並。
  • (6)生成新的映象檔案fsimage.chkpoint。
  • (7)拷貝fsimage.chkpoint到NameNode。
  • (8)NameNode將fsimage.chkpoint重新命名成fsimage。

相關文章