首先我們看一下NAMENODE:
我們已經知道了NAMENODE作為DATANODE的管理者,其重要性不言而喻,那么NAMENODE是怎么管理數據的呢?
首先,我們看一下上面這張圖,每次客戶端讀寫數據都要先經過NAMENODE,其實就是先查詢NAMENODE中的元數據,那么問題來了,NAMENODE中的元數據究竟是存在內存中還是存在硬盤中呢?如果存在內存中,一旦斷電就意味着數據的丟失;但是存在硬盤中,讀寫速度必然下降。下面將對其細節進行詳盡的闡述。
通過看以上這幅圖,我們可以看到NAMENODE中的元數據既存在在內存中,也存在在硬盤中。我們先看一下元數據的存儲細節:
從左到右依次是存儲路徑,有哪些副本,每個副本在哪些主機上面存儲。NAMENODE是整個文件系統的管理節點。它維護着整個文件系統的文件目錄樹,文件/目錄的元信息和每個文件對應的數據塊列表,接受用戶的操作請求。
文件包括:
1.fsimage:元數據鏡像文件,存儲某一時段NAMENODE內存元數據信息。
2.edits:操作日志文件。
3.fstime:保存最近一次checkpoint的時間。
現在我們回到上一幅圖,
1.NAMENODE始終在內存中保存meta.data,用於處理“讀請求”。
2.到有“寫請求”到來時,NAMENODE會首先寫edits到磁盤,即向edits文件中寫日志,成功返回后,才會修改內存,並且向客戶端返回。
3.Hadoop會維護一個fsimage文件,也就是namenode中meta.data的鏡像,但是fsimage不會隨時與NAMENODE內存中的meta.data保持一致,而是每隔一段時間通過合並edits文件來更新內容。Secondary NAMENODE就是用來合並fsimage和edits文件來更新NAMENODE的meta.data的。
這里就用到了Secondary NAMENODE,我們再來看一張圖:
在這張圖中,我們可以看到SN的一些作用,當NN通知SN要進行checkpoint操作的時候,NN就停止向edits日志中寫數據了,但是寫操作又不能停止,這時候就會向一個edits.new日志文件中寫數據,而SN會把fsimage和edits里面的內容下載到SN中,在SN中進行合並,說白了,就是將日志格式轉化成要存儲的文件格式,產生fsimage.chkpoint文件,並將它上傳給NN,替換fsimage,並且重命名成fsimage,同時edits.new替換edits,並且重命名成edits。詳細過程就是:
那么什么時候checkpoint呢?有兩種判別方式:
1.fs.checkpoint.period:指定兩次checkpoint的最大時間間隔,默認是3600秒。
2.fs.checkpoint.size:規定edits文件的最大值,一旦超過這個值則強制checkpoint,不管是否達到最大時間間隔。默認大小是64M。
兩種判定方式先達到哪個判定條件,則先采用哪個。
我們再來看一下DATANODE:
DataNode
提供真實文件數據的存儲服務
文件塊:最基本的存儲單位,對於文件內容而言,一個文件的長度大小是size,那么從文件的0偏移,按照固定的大小,順序對文件進行划分並編號。划分好的每一塊稱為一個Block,默認Block的大小是128M。開始不同於普通文件系統的是HDFS中,如果一個文件小於一個數據塊的大小,並不占用整個數據塊存儲空間。datanode與namenode保存心跳機制,當長時間未向namenode報告,則視為該datanode死機,namenode會重新備份該datanode上的數據塊。
讀程圖:
1、客戶端發送請求,調用DistributedFileSystem API的open方法發送請求到Namenode,獲得block的位置信息,因為真正的block是存在Datanode節點上的,而namenode里存放了block位置信息的元數據。
2、Namenode返回所有block的位置信息,並將這些信息返回給客戶端。
3、客戶端拿到block的位置信息后調用FSDataInputStream API的read方法並行的讀取block信息,圖中4和5流程是並發的,block默認有3個副本,所以每一個block只需要從一個副本讀取就可以。
4、datanode返回給客戶端。
寫流程:
1、客戶端發送請求,調用DistributedFileSystem API的create方法去請求namenode,並告訴namenode上傳文件的文件名、文件大小、文件擁有者。
2、namenode根據以上信息算出文件需要切成多少塊block,以及block要存放在哪個datanode上,並將這些信息返回給客戶端。
3、客戶端調用FSDataInputStream API的write方法首先將其中一個block寫在datanode上,每一個block默認都有3個副本,並不是由客戶端分別往3個datanode上寫3份,而是由
已經上傳了block的datanode產生新的線程,由這個namenode按照放置副本規則往其它datanode寫副本,這樣的優勢就是快。
4、寫完后返回給客戶端一個信息,然后客戶端在將信息反饋給namenode。
5、需要注意的是上傳文件的擁有者就是客戶端上傳文件的用戶名,舉個例子用windows客戶端上傳文件,那么這個文件的擁有者就是administrator,和linux上的系統用戶名不是一樣的。
補充:
我們在文件系統寫內容,其實也是先在日志中寫,然后同步到內存,接着返回寫入成功,內存中的內容會在達到閾值后寫入到磁盤中。
推薦這篇文章: