<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                [TOC] # 前言 * 設計思想 分而治之:將大文件、大批量文件,分布式存放在大量服務器上,以便于采取分而治之的方式對海量數據進行運算分析; * 在大數據系統中作用: 為各類分布式運算框架(如:mapreduce,spark,tez,……)提供數據存儲服務 * 重點概念:文件切塊,副本存放,元數據 # HDFS的概念和特性 首先,它是一個文件系統,用于存儲文件,通過統一的命名空間——目錄樹來定位文件 其次,它是分布式的,由很多服務器聯合起來實現其功能,集群中的服務器有各自的角色; 重要特性如下: 1. HDFS中的文件在物理上是分塊存儲(block),塊的大小可以通過配置參數( dfs.blocksize)來規定,默認大小在hadoop2.x版本中是128M,老版本中是64M 2. HDFS文件系統會給客戶端提供一個統一的抽象目錄樹,客戶端通過路徑來訪問文件,形如:`hdfs://namenode:port/dir-a/dir-b/dir-c/file.data` 3. 目錄結構及文件分塊位置信息(元數據)的管理由namenode節點承擔 `——namenode`是HDFS集群主節點,負責維護整個hdfs文件系統的目錄樹,以及每一個路徑(文件)所對應的block塊信息(block的id,及所在的datanode服務器) 4. 文件的各個block的存儲管理由datanode節點承擔 `---- datanode`是HDFS集群從節點,每一個block都可以在多個datanode上存儲多個副本(副本數量也可以通過參數設置dfs.replication,默認是3) 5. HDFS是設計成適應一次寫入,多次讀出的場景,且不支持文件的修改 (注:適合用來做數據分析,并不適合用來做網盤應用,因為,不便修改,延遲大,網絡開銷大,成本太高) # HDFS文件塊大小 HDFS文件在物理上是分塊儲存(block),塊的大小可以通過配置參數(dfs.blocksize)來規定,默認大小在hadoop2.x版本中是128M,老版本中是64M HDFS的塊比磁盤的塊大,其目的是為了最小化尋址開銷.如果塊設置得足夠大,從磁盤傳輸數據的時間會明顯大于定位這個塊開始位置所需的時間.因而,傳輸一個由多個塊組成的文件的時間取決于磁盤傳輸速率 如果尋址時間約為10ms,而傳輸速率為100MB/S,為了使尋址時間僅占傳輸時間的1%,我們要將塊大小設置約為100MB.默認的塊大小128MB 尋址時間為傳輸時間的1%時候是最佳時間 塊的大小: `10ms*100*100M/s=100M` # 概述 1. HDFS集群分為兩大角色:NameNode、DataNode (Secondary Namenode) 2. NameNode負責管理整個文件系統的元數據 3. DataNode 負責管理用戶的文件數據塊 4. 文件會按照固定的大小(blocksize)切成若干塊后分布式存儲在若干臺datanode上 5. 每一個文件塊可以有多個副本,并存放在不同的datanode上 6. Datanode會定期向Namenode匯報自身所保存的文件block信息,而namenode則會負責保持文件的副本數量 7. HDFS的內部工作機制對客戶端保持透明,客戶端請求訪問HDFS都是通過向namenode申請來進行 ## HDFS寫概述 客戶端要向HDFS寫數據,首先要跟namenode通信以確認可以寫文件并獲得接收文件block的datanode,然后,客戶端按順序將文件逐個block傳遞給相應datanode,并由接收到block的datanode負責向其他datanode復制block的副本 ### 詳細步驟圖 ![](https://box.kancloud.cn/7fb1c790385d2841fba302d06fdd722a_925x606.png) 詳細步驟解析 1. 根namenode通信請求上傳文件,namenode檢查目標文件是否已存在,父目錄是否存在 2. namenode返回是否可以上傳 3. client請求第一個 block該傳輸到哪些datanode服務器上 4. namenode返回3個datanode服務器ABC 5. client請求3臺dn中的一臺A上傳數據(本質上是一個RPC調用,建立pipeline),A收到請求會繼續調用B,然后B調用C,將真個pipeline建立完成,逐級返回客戶端 6. client開始往A上傳第一個block(先從磁盤讀取數據放到一個本地內存緩存),以packet為單位,A收到一個packet就會傳給B,B傳給C;A每傳一個packet會放入一個應答隊列等待應答 7. 當一個block傳輸完成之后,client再次請求namenode上傳第二個block的服務器 ## HDFS讀數據流程 ### 概述 客戶端將要讀取的文件路徑發送給namenode,namenode獲取文件的元信息(主要是block的存放位置信息)返回給客戶端,客戶端根據返回的信息找到相應datanode逐個獲取文件的block并在客戶端本地進行數據追加合并從而獲得整個文件 ### HDFS讀數據流程 客戶端將要讀取的文件路徑發送給namenode,namenode獲取文件的元信息(主要是block的存放位置信息)返回給客戶端,客戶端根據返回的信息找到相應datanode逐個獲取文件的block并在客戶端本地進行數據追加合并從而獲得整個文件 ![](https://box.kancloud.cn/b9472ea84ab33fda272450618688c1a9_942x437.png) 有時候會發現有crc文件,這是校驗文件,校驗讀取的文件是不是完整的 詳細步驟解析 1. 跟namenode通信查詢元數據,找到文件塊所在的datanode服務器 2. 挑選一臺datanode(就近原則,然后隨機)服務器,請求建立socket流 3. datanode開始發送數據(從磁盤里面讀取數據放入流,以packet為單位來做校驗) 4. 客戶端以packet為單位接收,現在本地緩存,然后寫入目標文件 # NAMENODE工作機制 ## 問題場景: 1. 集群啟動后,可以查看目錄,但是上傳文件時報錯,打開web頁面可看到namenode正處于safemode狀態,怎么處理? 解釋: safemode是namenode的一種狀態(active/standby/safemode安全模式) namenode進入安全模式的原理: a. namenode發現集群中的block丟失率達到一定比例時(0.01%),namenode就會進入安全模式,在安全模式下,客戶端不能對任何數據進行操作,只能查看元數據信息(比如ls/mkdir) b. 如何退出安全模式? 找到問題所在,進行修復(比如修復宕機的datanode) 或者可以手動強行退出安全模式(沒有真正解決問題): `hdfs namenode --safemode leave` c. 在hdfs集群正常冷啟動時,namenode也會在safemode狀態下維持相當長的一段時間,此時你不需要去理會,等待它自動退出安全模式即可 (原理: namenode的內存元數據中,包含文件路徑、副本數、blockid,及每一個block所在datanode的信息,而fsimage中,不包含block所在的datanode信息,那么,當namenode冷啟動時,此時內存中的元數據只能從fsimage中加載而來,從而就沒有block所在的datanode信息——>就會導致namenode認為所有的block都已經丟失——>進入安全模式——>datanode啟動后,會定期向namenode匯報自身所持有的blockid信息,——>隨著datanode陸續啟動,從而陸續匯報block信息,namenode就會將內存元數據中的block所在datanode信息補全更新——>找到了所有block的位置,從而自動退出安全模式) 2. Namenode服務器的磁盤故障導致namenode宕機,如何挽救集群及數據? 解決: namenode配置多個路徑,也可以用網絡磁盤路徑 secondary namenode的目錄可以恢復 3. Namenode是否可以有多個?namenode內存要配置多大?namenode跟集群數據存儲能力有關系嗎? 解決: 可以多個 內存一般配置幾十G就行 跟集群存儲關系不是很大,和datanode有關,當然了要避免上傳小文件 4. 文件的blocksize究竟調大好還是調小好?--結合mapreduce 要看數據量和業務邏輯 最好mapreduce跑了不要太長 ## NAMENODE職責 負責客戶端請求的響應 元數據的管理(查詢,修改) 它維護著文件系統樹及整棵樹內所有的文件和目錄.這些信息以兩個文件形式永久保存在本地磁盤上,命名空間鏡像文件和編輯日志文件. namenode也記錄著每個文件中各個塊所在的數據節點信息,但它并不永久保存塊的位置信息,因為這些信息會在系統啟動時根據數據節點信息重建. ![](https://box.kancloud.cn/f730541a508271ddb6b93ce779598000_809x400.png) 1. 第一階段:namenode啟動 1. 第一次namenode格式化后,創建fsimage和edits文件.如果不是第一次啟動,直接加載編輯日志和鏡像文件到內存 2. 客戶端對元數據進行增刪改的請求 3. namenode記錄操作日志,更新滾動日志 4. namenode在內存對數據進行增刪改查 2. 第二階段:Secondary NameNode工作 1. Secondary NameNode詢問namenode是否需要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 ![](https://box.kancloud.cn/0dd427923f748d747517aba8e64aff10_825x520.png) ## 元數據管理 namenode對數據的管理采用了三種存儲形式: 1. 內存元數據(NameSystem)(namenode自己封裝一個文件系統) 2. 磁盤元數據鏡像文件 3. 數據操作日志文件(可通過日志運算出元數據) ### 元數據存儲機制 A. 內存中有一份完整的元數據(內存meta data) (內存meta data = fsimage + edits文件(編輯日志)) B. 磁盤有一個“準完整”的元數據鏡像(fsimage)文件(在namenode的工作目錄中) C. 用于銜接內存metadata和持久化元數據鏡像fsimage之間的操作日志(edits文件)注:當客戶端對hdfs中的文件進行新增或者修改操作,操作記錄首先被記入edits日志文件中,當客戶端操作成功后,相應的元數據會更新到內存meta.data中 ### 元數據手動查看 namenode被格式話后在/path/name/current目錄中產生文件 可以通過hdfs的一個工具來查看edits中的信息 ~~~ bin/hdfs oev -i edits -o edits.xml bin/hdfs oiv -i fsimage_0000000000000000087 -p XML -o fsimage.xml ~~~ * Fsimage文件:HDFS文件系統元數據的一個永久性的檢查點,其中包含HDFS文件系統的所有目錄和文件idnode的序列化信息 * Edits文件:存放HDFS文件系統的所有更新操作的路徑,文件系統客戶端執行的所有寫操作首先被記錄到edits文件中 * seen_txid文件保存的是一個數字,就是最后一個edits_的數字 * 每次Namenode啟動的時候都會將fsimage文件讀入內存,并從0001開始到seen_txid中記錄的數字依次執行每個edits里面的更新操作,保證內存中的元數據信息是最新的,同步的,可以看成Namenode啟動的時候就將fsimage和edits文件進行了合并 查看oiv和oev命令 基本語法 `hdfs oiv -p 文件類型 -i 鏡像文件 -o 轉換后文件輸出路徑` ### 元數據的checkpoint 每隔一段時間,會由secondary namenode將namenode上積累的所有edits和一個最新的fsimage下載到本地,并加載到內存進行merge(這個過程稱為checkpoint) **checkpoint的詳細過程** ![](https://box.kancloud.cn/5c1cb30ba240af72340815bec49ba783_918x496.png) **checkpoint操作的觸發條件配置參數** ~~~ dfs.namenode.checkpoint.check.period=60 #檢查觸發條件是否滿足的頻率,60秒 dfs.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之間最大的操作記錄 ~~~ **檢查時間參數設置** 通常情況下,SecondaryNameNode每隔一小時執行一次 hdfs-default.xml ~~~ <property> <name>dfs.namenode.checkpoint.period</name> <value>3600</value> </property> ~~~ 一分鐘檢查一次操作次數,當操作次數達到1百萬時,SecondaryNameNode執行一次 ~~~ <property> <name>dfs.namenode.checkpoint.txns</name> <value>1000000</value> <description>操作動作次數</description> </property> <property> <name>dfs.namenode.checkpoint.check.period</name> <value>60</value> <description>1分鐘檢查一次操作次數</description> </property> ~~~ **checkpoint的附帶作用** namenode和secondary namenode的工作目錄存儲結構完全相同,所以,當namenode故障退出需要重新恢復時,可以從secondary namenode的工作目錄中將fsimage拷貝到namenode的工作目錄,以恢復namenode的元數據 ### 元數據目錄說明 在第一次部署好Hadoop集群的時候,我們需要在NameNode(NN)節點上格式化磁盤: ~~~ $HADOOP_HOME/bin/hdfs namenode -format ~~~ 格式化完成之后,將會在$dfs.namenode.name.dir/current目錄下如下的文件結構 ~~~ current/ |-- VERSION |-- edits_* |-- fsimage_0000000000008547077 |-- fsimage_0000000000008547077.md5 `-- seen_txid ~~~ 其中的dfs.name.dir是在hdfs-site.xml文件中配置的,默認值如下: ~~~ <property> <name>dfs.name.dir</name> <value>file://${hadoop.tmp.dir}/dfs/name</value> </property> 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> ~~~ `dfs.namenode.name.dir`屬性可以配置多個目錄, 如`/data1/dfs/name,/data2/dfs/name,/data3/dfs/name,....。`各個目錄存儲的文件結構和內容都完全一樣,相當于備份,這樣做的好處是當其中一個目錄損壞了,也不會影響到Hadoop的元數據,特別是當其中一個目錄是NFS(網絡文件系統Network File System,NFS)之上,即使你這臺機器損壞了,元數據也得到保存。?下面對`$dfs.namenode.name.dir/current/目錄下的文件進行解釋。`? 1. VERSION文件是Java屬性文件,內容大致如下: ~~~ #Fri Nov 15 19:47:46 CST 2013 namespaceID=934548976 clusterID=CID-cdff7d73-93cd-4783-9399-0a22e6dce196 cTime=0 storageType=NAME_NODE blockpoolID=BP-893790215-192.168.24.72-1383809616115 layoutVersion=-47 ~~~ 其中 (1). namespaceID是文件系統的唯一標識符,在文件系統首次格式化之后生成的  (2). storageType說明這個文件存儲的是什么進程的數據結構信息(如果是DataNode,storageType=DATA_NODE) (3). cTime表示NameNode存儲時間的創建時間,由于我的NameNode沒有更新過,所以這里的記錄值為0,以后對NameNode升級之后,cTime將會記錄更新時間戳; (4). layoutVersion表示HDFS永久性數據結構的版本信息, 只要數據結構變更,版本號也要遞減,此時的HDFS也需要升級,否則磁盤仍舊是使用舊版本的數據結構,這會導致新版本的NameNode無法使用;?  (5)、clusterID是系統生成或手動指定的集群ID,在-clusterid選項中可以使用它;如下說明 a. 使用如下命令格式化一個Namenode: ~~~ $HADOOP_HOME/bin/hdfs namenode -format [-clusterId <cluster_id>] ~~~ 選擇一個唯一的cluster_id,并且這個cluster_id不能與環境中其他集群有沖突。如果沒有提供cluster_id,則會自動生成一個唯一的ClusterID。 b. 使用如下命令格式化其他Namenode: ~~~ $HADOOP_HOME/bin/hdfs namenode -format -clusterId <cluster_id> ~~~ c. 升級集群至最新版本。在升級過程中需要提供一個ClusterID,例如: ~~~ $HADOOP_PREFIX_HOME/bin/hdfs start namenode --config $HADOOP_CONF_DIR? -upgrade -clusterId <cluster_ID> ~~~ 如果沒有提供ClusterID,則會自動生成一個ClusterID。 (6). blockpoolID:是針對每一個Namespace所對應的blockpool的ID,上面的這個BP-893790215-192.168.24.72-1383809616115就是在我的ns1的namespace下的存儲塊池的ID,這個ID包括了其對應的NameNode節點的ip地址。 2. ` $dfs.namenode.name.dir/current/seen_txid`非常重要,是存放transactionId的文件,format之后是0,它代表的是namenode里面的`edits_*`文件的尾數,namenode重啟的時候,會按照seen_txid的數字,循序從頭跑`edits_0000001~`到seen_txid的數字。所以當你的hdfs發生異常重啟的時候,一定要比對seen_txid內的數字是不是你edits最后的尾數,不然會發生建置namenode時metaData的資料有缺少,導致誤刪Datanode上多余Block的資訊。 3.` $dfs.namenode.name.dir/current`目錄下在format的同時也會生成fsimage和edits文件,及其對應的md5校驗文件。 補充:seen_txid 文件中記錄的是edits滾動的序號,每次重啟namenode時,namenode就知道要將哪些edits ## SecondaryNameNode 并非NameNode的熱備.當NameNode掛掉的時候,它并不能馬上替換NameNode并提供服務 # DATANODE的工作機制 ![](https://box.kancloud.cn/21dee845b8698700a0723447cf9b28d8_1247x626.png) 1. 一個數據塊在datanode上以文件形式存儲在磁盤上,包括兩個文件,一個是數據本身,一個是元數據包括數據塊長度,塊數據的校驗和,以及時間戳 2. DataNode啟動后向namenode注冊,通過后,周期性(1小時)的向namenode上報所有塊信息 3. 心跳是每3秒一次,心跳返回結果帶有namenode給該datanode的命令如復制塊數據帶另一臺機器,或刪除到另一臺機器,或刪除某個數據塊.如果超過10分鐘沒有收到某個datanode的心跳,則認為該節點不可用 4. 集群運行中可以安全加入和退出一些機器 ## 問題場景 1. 集群容量不夠,怎么擴容? 2. 如果有一些datanode宕機,該怎么辦? 3. datanode明明已啟動,但是集群中的可用datanode列表中就是沒有,怎么辦? 以上這類問題的解答,有賴于對datanode工作機制的深刻理解 ## 概述 ### Datanode工作職責: 1. 存儲管理用戶的文件塊數據 定期向namenode匯報自身所持有的block信息(通過心跳信息上報) (這點很重要,因為,當集群中發生某些block副本失效時,集群如何恢復block初始副本數量的問題) ~~~ <property> <name>dfs.blockreport.intervalMsec</name> <value>3600000</value> <description>Determines block reporting interval in milliseconds.</description> </property> ~~~ 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.interval的單位為秒。所以,舉個例子,如果heartbeat.recheck.interval設置為5000(毫秒),dfs.heartbeat.interval設置為3(秒,默認),則總的超時時間為40秒。 ~~~ <property> <name>heartbeat.recheck.interval</name> <value>2000</value> </property> <property> <name>dfs.heartbeat.interval</name> <value>1</value> </property> ~~~ ## 觀察驗證DATANODE功能 上傳一個文件,觀察文件的block具體的物理存放情況: 在每一臺datanode機器上的這個目錄中能找到文件的切塊: ~~~ /home/hadoop/app/hadoop-2.4.1/tmp/dfs/data/current/BP-193442119-192.168.2.120-1432457733977/current/finalized ~~~ # datanode版本號 在/path/data/tmp/dfs/data/中有個VERSION cat下,會出 storageID集群的id clusterID存儲的id,機器的id cTime創建的時間 storageType機器類型,datanode還是什么 layoutVersion新特性的版號 然后在這層中`cd current/`也有個VERSION cat下會有namespaceID這是NameNode的id,集群中可能有多個namenode,這個表示屬于哪個namenode # maven依賴 ~~~ <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-common</artifactId> <version>2.6.4</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-hdfs</artifactId> <version>2.6.4</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-client</artifactId> <version>2.6.4</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-mapreduce-client-core</artifactId> <version>2.6.4</version> </dependency> ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看