7.hdfs工作流程及機制


1. hdfs基本工作流程

1. hdfs初始化目錄結構

hdfs namenode -format 只是初始化了namenode的工作目錄
而datanode的工作目錄是在datanode啟動后自己初始化的

namenode在format初始化的時候會形成兩個標識:
blockPoolId:
clusterId:

新的datanode加入時,會獲取這兩個標識作為自己工作目錄中的標識

一旦namenode重新format后,namenode的身份標識已變,而datanode如果依然
持有原來的id,就不會被namenode識別

2. hdfs的工作機制

  1. hdfs集群分為兩大角色:NameNode,DataNode (Secondary NameNode)
  2. NameNode負責管理整個文件的元數據(命名空間信息,塊信息) 相當於Master
  3. DataNode負責管理用戶的文件數據塊 相當於Salve
  4. 文件會按照固定的大小(block=128M)切成若干塊后分布式存儲在若干個datanode節點上
  5. 每一個文件塊有多個副本(默認是三個),存在不同的datanode上
  6. DataNode會定期向NameNode匯報自身所保存的文件block信息,而namenode則會負責保持文件副本數量
  7. hdfs的內部工作機制會對客戶的保持透明,客戶端請求方法hdfs都是通過向namenode申請來進行訪問
  8. SecondaryNameNode有兩個作用,一是鏡像備份,二是日志與鏡像的定期合並

3. hdfs寫入數據流程

1.客戶端要向hdfs寫入數據,首先要跟namenode通信以確認可以寫文件並獲得接收文件block的datanode,然后,客戶端按照順序將文件block逐個傳給相應datanode,並由接收到block的datanode負責向其他datanode復制block副本

-w 1000

4. 寫入數據步驟詳細解析

  1. 客戶端向namenode通信,請求上傳文件,namenode檢查目標文件是否已經存在,父目錄是否存在
  2. namenode返回給客戶端,告知是否可以上傳
  3. 客戶端請求第一個block該傳輸到那些datanode服務器上
  4. namenode返回3個datanode服務器abc
  5. 客戶端請求3台datanode的一台a上傳數據(本質上是一個rpc調用,建立pipeline),A收到請求后會繼續調用b,然后b調用c,將整個pipeline建立完成,逐級返回客戶端。
  6. 客戶端開始忘a上傳第一個block(先從磁盤讀取數據放入本地內存緩存),以packet為單位,a收到一個packet將會傳給b,b傳給c,a每傳一個packet會放入一個應答隊列等待應答
  7. 宕一個block傳輸完之后,客戶端再次請求namenode上傳第二個block的服務器

5. hdfs讀取數據流程

  1. 客戶端將要讀取的文件路徑發送給namenode
  2. namenode獲取文件的元信息(主要是block的存放位置信息)返回給客戶端
  3. 客戶端根據返回的信息找到相應的datanode逐個獲取文件的block
  4. 客戶端本地進行數據的追加合並從而獲得整個文件

6. 讀取數據詳細步驟解析

  1. 客戶端跟namenode通信查詢元數據,找到文件塊所在的datanode服務器
  2. 挑選一台datanode(就近原則,然后隨機)服務器,請求建立socket流
  3. datanode開始發送數據(從磁盤里面讀取數據放入流,以packet為單位做校驗)
  4. 客戶端以packet為單位接收,先在本地緩存,然后寫入目標文件。

2. namenode工作機制

1. namenode常見問題

  1. 集群啟動后,可以查看文件,但是上傳文件報錯,打開web頁面看到namenode正在處於sofemode狀態,怎么處理?
  2. namenode服務器磁盤故障導致namenode宕機,如何解決?
  3. namenode是否可以有多個?
  4. namenode內存要配置多大?
  5. namenode跟集群數據存儲能力有關系嗎?
  6. 文件的blocksize究竟調大好,還是調小好?

2. namenode的工作職責

  1. 負責客戶端的請求及相應
  2. 元數據的管理(查詢,修改)

3. 元數據管理

  1. namenode對數據的管理采用三種存儲形式
  2. 內存元數據(NameSystem)
  3. 磁盤元數據鏡像文件
  4. 數據操作日志文件(可通過日志運算出元數據)類似於mysql的binlog

4. 元數據存儲機制

  1. 內存中有一份完整的元數據(內存 metadata)
  2. 磁盤有一個 “准完整” 的元數據鏡像(fsimage)文件(在namenode工作目錄中)
  3. 用於銜接內存metadata和持久化元數據鏡像fsimage之間的操作日志(edits log文件)
  4. 當客戶端對hdfs中的文件進行新增或者修改操作,操作記錄首先被記入edits日志文件中,當客戶端操作成功后,相應的元數據會更新到內存metadata中

5. 元數據查看

  1. hdfs oev -i edits_0000000000000000162-0000000000000000163 -o edits.xml
  2. hdfs oiv -i fsimage_0000000000000000262 -p XML -o fsimage.xml

6.  元數據的checkpoint

  1. 每隔一段時間,secondary namenode 將namenode上積累的所有edits和一個最新的fsimage下載到本地,並加載到內存進行merge(這個過程為checkpoint)
  2. 詳細過程
    ![圖片 1](http://img.liuyao.me/圖片 1.png)

7. 解決namenode的災難性錯誤的方法

  1. 首先在hdfs-site.xml配置

    <property>
             <name>dfs.name.dir</name>
             <value>/data/hadoop/name1,/data/hadoop/name2</value>
        </property>
    
    
  2. 停止集群

  3. 重新格式化

    hadoop namenode -format
    
  4. 開始集群

8. checkpoint操作的觸發條件配置參數

#dfs.namenode.checkpoint.check.period=60  #檢查觸發條件是否滿足的頻率,60秒
#hdfs.namenode.checkpoint.dir=file://${hadoop.tmp.dir}/dfs/namesecondary
#以上兩個參數做checkpoint操作時,secondary namenode的本地工作目錄
#dfs.namenode.checkpoint.edits.dir=${dfs.namenode.checkpoint.dir}
#dfs.namenode.checkpoint.max-retries=3  #最大重試次數
#dfs.namenode.checkpoint.period=3600  #兩次checkpoint之間的時間間隔3600秒
#dfs.namenode.checkpoint.txns=1000000 #兩次checkpoint之間最大的操作記錄

9. checkpoint的附帶作用

  1. namenode和secondary namenode的工作目錄存儲結構完全相同,所以當namenode故障退出需要重新恢復時,可以從secondary namenode 的工作目錄將fsimage拷貝到namenode的工作目錄。以恢復namenode的元數據

10. 元數據目錄說明

  1. 當第一次部署好hadoop集群的時候,在namenode上格式化硬盤后會在${dfs.namenode.name.dir}/current目錄產生如下文件結構:

    #ls /tmp/hadoop-root/dfs/name/current
    ---VERSION
    ---edits_*
    ---fsimage_*
    ---seen_txid
    
  2. dfs.namenode.name.dir在hdfs-site.xml文件中配置

    <property>
        <name>dfs.namenode.name.dir</name>
         <value>file://${hadoop.tmp.dir}/dfs/name</value>
    </property>
    

注:dfs.namenode.name.dir的屬性可以配置多個目錄,每個目錄存在的文件結構和內容都是一樣的,相當於備份,好處是其中有一個目錄損壞了,也不會影響到hadoop的元數據。

  1. hadoop.tmp.dir在core-site.xml文件中配置

    <property>
        <name>hadoop.tmp.dir</name>
        <value>/tmp/hadoop-${user.name}</value>
        <description>A base for other temporary directories.</description>
    </property>
    
  2. VERSION文件是java屬性文件

    [root@hadoop-1 current]# cat VERSION
    #Thu Jun 22 11:42:19 EDT 2017
    namespaceID=1169207959
    clusterID=CID-ce01b250-9850-4da5-b81f-ab24905fbdd7
    cTime=0
    storageType=NAME_NODE
    blockpoolID=BP-1786918471-172.16.1.207-1498146139482
    layoutVersion=-63
    
    1. namespace

      文件系統的唯一標識符,在文件系統首次格式化后生成的

    2. StorageType

      說明這個文件存儲的是什么進程的數據結構信息(如果是DataNode,storageType=DATA_NODE);

    3. cTime

      NameNode存儲時間的創建時間,由於我的NameNode沒有更新過,所以這里的記錄值為0,如果NameNode升級后,cTime將會記錄更新時間戳

    4. layoutVersion

      HDFS永久性數據結構的版本信息,只要數據結構變更,版本號也要遞減,此時的hdfs也需要升級,否則磁盤仍舊是使用舊版本的數據結構,這會導致新版本的NameNode無法使用。

    5. clusterID

      系統生成或者手動指定的集群id,在-clusterid選項中可以使用它

      1. $HADOOP_HOME/bin/hdfs namenode -format [-clusterId <cluster_id>]
      選擇一個唯一的cluster_id,並且這個cluster_id不能與環境中其他集群有沖突。如果沒       
      有提供cluster_id,則會自動生成一個唯一的ClusterID。
      2. 使用如下命令格式化其他Namenode:
       $HADOOP_HOME/bin/hdfs namenode -format -clusterId <cluster_id>
      3. 升級集群至最新版本。在升級過程中需要提供一個ClusterID,例如:                                  
      $HADOOP_PREFIX_HOME/bin/hdfs start namenode --config
      $HADOOP_CONF_DIR  -upgrade -clusterId <cluster_ID>
      如果沒有提供ClusterID,則會自動生成一個ClusterID。
      
    6. blockpoolID

      針對每一個NameSpace所對應的blockpool的ID,上面的這個
      BP-1786918471-172.16.1.207-1498146139482 就是我在ns1的namespace下的存儲塊池的ID,這個id包括了對應的namenode節點服務器ip地址

  3. seen_teid文件

    存放transactionid的文件,format之后是0,它代表的是namenode里面的edits_*文件的尾數,namenode重啟的時候,會按照seen_txid的數字,循序從頭跑edits_0000001~到seen_txid的數字。所以當你的hdfs發生異常重啟的時候,一定要比對seen_txid內的數字是不是你edits最后的尾數,不然會發生建置namenode時metaData的資料有缺少,導致誤刪Datanode上多余Block.
    文件中記錄的是edits滾動的序號,每次重啟namenode時,namenode就知道要將哪些edits進行加載edits

  4. current目錄下在format的同時也好生成fsimage和edits文件及其對應的md5校驗文件,

3. DataNode的工作機制

  1. Datanode工作職責:

    存儲管理用戶的文件塊數據
    定期向namenode匯報自身所持有的block信息(通過心跳信息上報)

  2. Datanode掉線判斷的時限參數:

    datanode進程死亡或網絡故障造成datanode無法與namenode通信,namenode不會立即把該節點判斷為死亡,要經過一段時間,它這段時間暫稱為超時時長,hdfs默認的超時時長為10分鍾+30秒,如果定義超時時間為timeout,則超時時長的計算公式為:
    timeout = 2* heartbeat.recheck.interval + 10 * dfs.heartbeat.interval

    默認的heartbeat.recheck.interval 大小為5分鍾,dfs.heartbeat.interval默認為3秒

    需要注意的是 hdfs-site.xml配置文件中的heartbeat.recheck.interval的單位為毫秒
    dfs.heartbeat.interva的單位為秒,所以,舉個例子,如果heartbeat.recheck.interval設置為5000(毫秒),dfs.heartbeat.interval設置為3(秒,默認),則總的超時時間為40秒。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM