<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>

                [TOC] # HDFS原理 ## 1. HDFS前言 1) 設計思想 > 分而治之:將大文件、大批量文件,分布式存放在大量服務器上,以便于采取分而治之的方式對海量數據進行運算分析; 2) 在大數據系統中作用: > 為各類分布式運算框架(如:mapreduce,spark,tez,……)提供數據存儲服務 3) 重點概念:文件切塊,副本存放,元數據 ## 2. 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基本操作篇****** ## 3. HDFS的shell(命令行客戶端)操作 ### 3.1 HDFS命令行客戶端使用 > HDFS提供shell命令行客戶端,使用方法如下: > 可以使用一下兩種形式: ~~~ hadoop fs -… <args> hdfs dfs -… <args> ~~~ ![](https://box.kancloud.cn/abb32facf00ce2a8848f9812bd02e931_554x95.png) 3.2 命令行客戶端支持的命令參數 ~~~ [-appendToFile <localsrc> ... <dst>] [-cat [-ignoreCrc] <src> ...] [-checksum <src> ...] [-chgrp [-R] GROUP PATH...] [-chmod [-R] <MODE[,MODE]... | OCTALMODE> PATH...] [-chown [-R] [OWNER][:[GROUP]] PATH...] [-copyFromLocal [-f] [-p] <localsrc> ... <dst>] [-copyToLocal [-p] [-ignoreCrc] [-crc] <src> ... <localdst>] [-count [-q] <path> ...] [-cp [-f] [-p] <src> ... <dst>] [-createSnapshot <snapshotDir> [<snapshotName>]] [-deleteSnapshot <snapshotDir> <snapshotName>] [-df [-h] [<path> ...]] [-du [-s] [-h] <path> ...] [-expunge] [-get [-p] [-ignoreCrc] [-crc] <src> ... <localdst>] [-getfacl [-R] <path>] [-getmerge [-nl] <src> <localdst>] [-help [cmd ...]] [-ls [-d] [-h] [-R] [<path> ...]] [-mkdir [-p] <path> ...] [-moveFromLocal <localsrc> ... <dst>] [-moveToLocal <src> <localdst>] [-mv <src> ... <dst>] [-put [-f] [-p] <localsrc> ... <dst>] [-renameSnapshot <snapshotDir> <oldName> <newName>] [-rm [-f] [-r|-R] [-skipTrash] <src> ...] [-rmdir [--ignore-fail-on-non-empty] <dir> ...] [-setfacl [-R] [{-b|-k} {-m|-x <acl_spec>} <path>]|[--set <acl_spec> <path>]] [-setrep [-R] [-w] <rep> <path> ...] [-stat [format] <path> ...] [-tail [-f] <file>] [-test -[defsz] <path>] [-text [-ignoreCrc] <src> ...] [-touchz <path> ...] [-usage [cmd ...]] ~~~ ### 3.2 常用命令參數介紹 > -help > 功能:輸出這個命令參數手冊 > -ls > 功能:顯示目錄信息 > 示例: hadoop fs -ls hdfs://hadoop-server01:9000/ > 備注:這些參數中,所有的hdfs路徑都可以簡寫 > -->hadoop fs -ls / 等同于上一條命令的效果 > -mkdir > 功能:在hdfs上創建目錄 > 示例:hadoop fs -mkdir -p /aaa/bbb/cc/dd > -moveFromLocal > 功能:從本地剪切粘貼到hdfs > 示例:hadoop fs - moveFromLocal /home/hadoop/a.txt /aaa/bbb/cc/dd > -moveToLocal > 功能:從hdfs剪切粘貼到本地 > 示例:hadoop fs - moveToLocal /aaa/bbb/cc/dd /home/hadoop/a.txt > --appendToFile > 功能:追加一個文件到已經存在的文件末尾 > 示例:hadoop fs -appendToFile ./hello.txt hdfs://hadoop-server01:9000/hello.txt > 可以簡寫為: > Hadoop fs -appendToFile ./hello.txt /hello.txt > -cat > 功能:顯示文件內容 > 示例:hadoop fs -cat /hello.txt > -tail > 功能:顯示一個文件的末尾 > 示例:hadoop fs -tail /weblog/access_log.1 > -text > 功能:以字符形式打印一個文件的內容 > 示例:hadoop fs -text /weblog/access_log.1 > -chgrp > -chmod > -chown > 功能:linux文件系統中的用法一樣,對文件所屬權限 > 示例: > hadoop fs -chmod 666 /hello.txt > hadoop fs -chown someuser:somegrp /hello.txt > -copyFromLocal > 功能:從本地文件系統中拷貝文件到hdfs路徑去 > 示例:hadoop fs -copyFromLocal ./jdk.tar.gz /aaa/ > -copyToLocal > 功能:從hdfs拷貝到本地 > 示例:hadoop fs -copyToLocal /aaa/jdk.tar.gz > -cp > 功能:從hdfs的一個路徑拷貝hdfs的另一個路徑 > 示例: hadoop fs -cp /aaa/jdk.tar.gz /bbb/jdk.tar.gz.2 > -mv > 功能:在hdfs目錄中移動文件 > 示例: hadoop fs -mv /aaa/jdk.tar.gz / > -get > 功能:等同于copyToLocal,就是從hdfs下載文件到本地 > 示例:hadoop fs -get /aaa/jdk.tar.gz > 功能:合并下載多個文件 > 示例:比getmerge 如hdfs的目錄 /aaa/下有多個文件:log.1, log.2,log.3,... > hadoop fs -getmerge /aaa/log.* ./log.sum > -put > 功能:等同于copyFromLocal > 示例:hadoop fs -put /aaa/jdk.tar.gz /bbb/jdk.tar.gz.2 > -rm > 功能:刪除文件或文件夾 > 示例:hadoop fs -rm -r /aaa/bbb/ > -rmdir > 功能:刪除空目錄 > 示例:hadoop fs -rmdir /aaa/bbb/ccc > -df > 功能:統計文件系統的可用空間信息 > 示例:hadoop fs -df -h / > -du > 功能:統計文件夾的大小信息 > 示例: > hadoop fs -du -s -h /aaa/* > -count > 功能:統計一個指定目錄下的文件節點數量 > 示例:hadoop fs -count /aaa/ > -setrep > 功能:設置hdfs中文件的副本數量 > 示例:hadoop fs -setrep 3 /aaa/jdk.tar.gz > 補充:查看dfs集群工作狀態的命令 ~~~ hdfs dfsadmin -report ~~~ # ******HDFS原理篇****** ## 4. hdfs的工作機制 > (工作機制的學習主要是為加深對分布式系統的理解,以及增強遇到各種問題時的分析解決能力,形成一定的集群運維能力) > 注:很多不是真正理解hadoop技術體系的人會常常覺得HDFS可用于網盤類應用,但實際并非如此。要想將技術準確用在恰當的地方,必須對技術有深刻的理解 ### 4.1 概述 1. HDFS集群分為兩大角色:NameNode、DataNode (Secondary Namenode) 2. NameNode負責管理整個文件系統的元數據 3. DataNode 負責管理用戶的文件數據塊 4. 文件會按照固定的大小(blocksize)切成若干塊后分布式存儲在若干臺datanode上 5. 每一個文件塊可以有多個副本,并存放在不同的datanode上 6. Datanode會定期向Namenode匯報自身所保存的文件block信息,而namenode則會負責保持文件的副本數量 7. HDFS的內部工作機制對客戶端保持透明,客戶端請求訪問HDFS都是通過向namenode申請來進行 ? ### 4.2 HDFS寫數據流程 #### 4.2.1 概述 > 客戶端要向HDFS寫數據,首先要跟namenode通信以確認可以寫文件并獲得接收文件block的datanode,然后,客戶端按順序將文件逐個block傳遞給相應datanode,并由接收到block的datanode負責向其他datanode復制block的副本 ### 4.2.2 詳細步驟圖 ![](https://box.kancloud.cn/64711058d91e276453f9d06b93ffca53_554x354.png) ![](https://box.kancloud.cn/26ab0c2b3dcdab0312c41e23edba2b19_1473x889.png) #### 4.2.3 詳細步驟解析 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的服務器。 ### 4.3. HDFS讀數據流程 #### 4.3.1 概述 > 客戶端將要讀取的文件路徑發送給namenode,namenode獲取文件的元信息(主要是block的存放位置信息)返回給客戶端,客戶端根據返回的信息找到相應datanode逐個獲取文件的block并在客戶端本地進行數據追加合并從而獲得整個文件 #### 4.3.2 詳細步驟圖 ![](https://box.kancloud.cn/02be4cf5cc8c10b4626da03d345e819f_1022x496.png) #### 4.3.3 詳細步驟解析 1. 跟namenode通信查詢元數據,找到文件塊所在的datanode服務器 2. 挑選一臺datanode(就近原則,然后隨機)服務器,請求建立socket流 3. datanode開始發送數據(從磁盤里面讀取數據放入流,以packet為單位來做校驗) 4. 客戶端以packet為單位接收,現在本地緩存,然后寫入目標文件 ## 5 NAMENODE工作機制 > 學習目標:理解namenode的工作機制尤其是元數據管理機制,以增強對HDFS工作原理的理解,及培養hadoop集群運營中“性能調優”、“namenode”故障問題的分析解決能力 > 問題場景: 1) 集群啟動后,可以查看目錄,但是上傳文件時報錯,打開web頁面可看到namenode正處于safemode狀態,怎么處理? > 解釋: > safemode是namenode的一種狀態(active/standby/safemode安全模式) > namenode進入安全模式的原理: 1) namenode發現集群中的block丟失率達到一定比例時(0.01%),namenode就會進入安全模式,在安全模式下,客戶端不能對任何數據進行操作,只能查看元數據信息(比如ls/mkdir) 2) 如何退出安全模式? > 找到問題所在,進行修復(比如修復宕機的datanode) > 或者可以手動強行退出安全模式(沒有真正解決問題): hdfs namenode --safemode leave 3) 在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宕機,如何挽救集群及數據? 3) Namenode是否可以有多個?namenode內存要配置多大?namenode跟集群數據存儲能力有關系嗎? 4) 文件的blocksize究竟調大好還是調小好?--結合mapreduce 5) …… > 諸如此類問題的回答,都需要基于對namenode自身的工作原理的深刻理解 ### 5.1 NAMENODE職責 > NAMENODE職責: 1. 負責客戶端請求的響應 2. 元數據的管理(查詢,修改) #### 5.2 元數據管理 > namenode對數據的管理采用了三種存儲形式: 1. 內存元數據(NameSystem) 2. 磁盤元數據鏡像文件 3. 數據操作日志文件(可通過日志運算出元數據) > namenode元數據恢復 ![](https://box.kancloud.cn/c5b4f45c5f1db7aabf58760675fb9a56_1536x836.png) ##### 5.2.1 元數據存儲機制 1) 內存中有一份完整的元數據(內存meta data) 2) 磁盤有一個“準完整”的元數據鏡像(fsimage)文件(在namenode的工作目錄中) 3) 用于銜接內存metadata和持久化元數據鏡像fsimage之間的操作日志(edits文件)注:當客戶端對hdfs中的文件進行新增或者修改操作,操作記錄首先被記入edits日志文件中,當客戶端操作成功后,相應的元數據會更新到內存meta.data中 ##### 5.2.2 元數據手動查看 > 可以通過hdfs的一個工具來查看edits中的信息 ~~~ bin/hdfs oev -i edits -o edits.xml bin/hdfs oiv -i fsimage_0000000000000000087 -p XML -o fsimage.xml ~~~ ##### 5.2.3 元數據的checkpoint > 每隔一段時間,會由secondary namenode將namenode上積累的所有edits和一個最新的fsimage下載到本地,并加載到內存進行merge(這個過程稱為checkpoint) > checkpoint的詳細過程 ![](https://box.kancloud.cn/6410da16eafa9ee5bdca97fcda105c55_1340x612.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之間最大的操作記錄 ~~~ > checkpoint的附帶作用 > namenode和secondary namenode的工作目錄存儲結構完全相同,所以,當namenode故障退出需要重新恢復時,可以從secondary namenode的工作目錄中將fsimage拷貝到namenode的工作目錄,以恢復namenode的元數據 ##### 5.2.4 元數據目錄說明 > 在第一次部署好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 ~~~ > 其中 * namespaceID是文件系統的唯一標識符,在文件系統首次格式化之后生成的; * storageType說明這個文件存儲的是什么進程的數據結構信息(如果是DataNode,storageType=DATA_NODE); * cTime表示NameNode存儲時間的創建時間,由于我的NameNode沒有更新過,所以這里的記錄值為0,以后對NameNode升級之后,cTime將會記錄更新時間戳; * layoutVersion表示HDFS永久性數據結構的版本信息, 只要數據結構變更,版本號也要遞減,此時的HDFS也需要升級,否則磁盤仍舊是使用舊版本的數據結構,這會導致新版本的NameNode無法使用; * 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。 * 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進行加載edits ## 6. DATANODE的工作機制 > 問題場景: 1. 集群容量不夠,怎么擴容? 2. 如果有一些datanode宕機,該怎么辦? 3. datanode明明已啟動,但是集群中的可用datanode列表中就是沒有,怎么辦? > 以上這類問題的解答,有賴于對datanode工作機制的深刻理解 ### 6.1 概述 1) Datanode工作職責: > 存儲管理用戶的文件塊數據 > 定期向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> ~~~ ### 6.2 觀察驗證DATANODE功能 > 上傳一個文件,觀察文件的block具體的物理存放情況: > 在每一臺datanode機器上的這個目錄中能找到文件的切塊: ~~~ /home/hadoop/app/hadoop-2.4.1/tmp/dfs/data/current/BP-193442119-192.168.2.120-1432457733977/current/finalized ~~~
                  <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>

                              哎呀哎呀视频在线观看