HDFS 詳解

HDFS前言

l 設計思想
分而治之:將大文件、大批量文件,分佈式存放在大量服務器上,以便於採取分而治之的方式對海量數據進行運算分析;

l 在大數據系統中作用:
爲各類分佈式運算框架(如:mapreduce,spark,tez,……)提供數據存儲服務

l 重點概念:文件切塊,副本存放,元數據

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)

(5)HDFS是設計成適應一次寫入,多次讀出的場景,且不支持文件的修改

HDFS的shell(命令行客戶端)操作

HDFS命令行客戶端使用

HDFS提供shell命令行客戶端,使用方法如下:
在這裏插入圖片描述

命令行客戶端支持的命令參數

[-appendToFile … ]
[-cat [-ignoreCrc] …]
[-checksum …]
[-chgrp [-R] GROUP PATH…]
[-chmod [-R] <MODE[,MODE]… | OCTALMODE> PATH…]
[-chown [-R] [OWNER][:[GROUP]] PATH…]
[-copyFromLocal [-f] [-p] … ]
[-copyToLocal [-p] [-ignoreCrc] [-crc] … ]
[-count [-q] …]
[-cp [-f] [-p] … ]
[-createSnapshot []]
[-deleteSnapshot ]
[-df [-h] [ …]]
[-du [-s] [-h] …]
[-expunge]
[-get [-p] [-ignoreCrc] [-crc] … ]
[-getfacl [-R] ]
[-getmerge [-nl] ]
[-help [cmd …]]
[-ls [-d] [-h] [-R] [ …]]
[-mkdir [-p] …]
[-moveFromLocal … ]
[-moveToLocal ]
[-mv … ]
[-put [-f] [-p] … ]
[-renameSnapshot ]
[-rm [-f] [-r|-R] [-skipTrash] …]
[-rmdir [–ignore-fail-on-non-empty]

…]
[-setfacl [-R] [{-b|-k} {-m|-x <acl_spec>} ]|[–set <acl_spec> ]]
[-setrep [-R] [-w] …]
[-stat [format] …]
[-tail [-f] ]
[-test -[defsz] ]
[-text [-ignoreCrc] …]
[-touchz …]
[-usage [cmd …]]

常用命令參數介紹

命令 功能 例子 備註
-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

HDFS原理

概述

  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的副本

詳細步驟圖

在這裏插入圖片描述
詳細步驟解析
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並在客戶端本地進行數據追加合併從而獲得整個文件

詳細步驟圖

在這裏插入圖片描述
詳細步驟解析
1、跟namenode通信查詢元數據,找到文件塊所在的datanode服務器
2、挑選一臺datanode(就近原則,然後隨機)服務器,請求建立socket流
3、datanode開始發送數據(從磁盤裏面讀取數據放入流,以packet爲單位來做校驗)
4、客戶端以packet爲單位接收,現在本地緩存,然後寫入目標文件

NAMENODE工作機制

NAMENODE職責

NAMENODE職責:
負責客戶端請求的響應
元數據的管理(查詢,修改)

元數據管理

namenode對數據的管理採用了三種存儲形式:
內存元數據(NameSystem)
磁盤元數據鏡像文件
數據操作日誌文件(可通過日誌運算出元數據)

元數據存儲機制

A、內存中有一份完整的元數據(內存meta data)
B、磁盤有一個“準完整”的元數據鏡像(fsimage)文件(在namenode的工作目錄中)
C、用於銜接內存metadata和持久化元數據鏡像fsimage之間的操作日誌(edits文件)注:當客戶端對hdfs中的文件進行新增或者修改操作,操作記錄首先被記入edits日誌文件中,當客戶端操作成功後,相應的元數據會更新到內存meta.data中

元數據手動查看

可以通過hdfs的一個工具來查看edits中的信息
bin/hdfs oev -i edits -o edits.xml
bin/hdfs oiv -i fsimage_0000000000000000087 -p XML -o fsimage.xml

元數據的checkpoint

每隔一段時間,會由secondary namenode將namenode上積累的所有edits和一個最新的fsimage下載到本地,並加載到內存進行merge(這個過程稱爲checkpoint)
checkpoint的詳細過程
在這裏插入圖片描述
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的元數據

元數據目錄說明

在第一次部署好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 HADOOPCONFDIRupgradeclusterId&lt;clusterID&gt;ClusterIDClusterID  6blockpoolIDNamespaceblockpoolIDBP893790215192.168.24.721383809616115ns1namespaceIDIDNameNodeip  2HADOOP_CONF_DIR -upgrade -clusterId &lt;cluster_ID&gt; 如果沒有提供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進行加載edits

DATANODE的工作機制

概述

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>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章