1. 程式人生 > >Hadoop — HDFS的概念、原理及基本操作

Hadoop — HDFS的概念、原理及基本操作

IE 觀察 poi 如何恢復 滾動 4.3 python metadata 元數據

1. HDFS的基本概念和特性

設計思想——分而治之:將大文件、大批量文件分布式存放在大量服務器上,以便於采取分而治之的方式對海量數據進行運算分析。在大數據系統中作用:為各類分布式運算框架(如:mapreduce,spark,tez,....)提供數據存儲服務。

1.1 HDFS的概念

首先,它是一個文件系統,用於存儲文件,通過統一的命名空間--目錄樹來定位文件;

其次,它是分布式的,有很多服務器聯合起來實現其功能,集群中的服務器有各自的角色;

重點概念:文件切塊,副本存放,元數據(目錄結構及文件分塊信息)

1.2 HDFS的重要特性

(1) HDFS中的文件在物理上是分塊存儲(block),塊的大小可以通過配置參數(dfs.blocksize)來規定,默認大小在hadoop2.x版本中是128M,老版本中是64M;

(2) HDFS文件系統會給客戶端提供一個統一的抽象目錄樹,客戶端通過路徑來訪問文件,形如:hdfs://namenode:port/dir-a/dir-b/file.data;

(3) 目錄結構及文件分塊信息(元數據)的管理由namenode節點承擔
namenode是HDFS集群主節點,負責維護整個hdfs文件系統的目錄樹,以及每一個路徑(文件)所對應block塊信息(block的id,及所在的datanode服務器)

(4) 文件的各個block的存儲管理由datanode節點承擔
datanode是HDFS集群從節點,每一個block都可以在多個datanode上存儲多個副本(副本數量也可以通過參數設置dfs.replication)

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

註意:適合用來做數據分析,並不合適用來做網盤應用,因為,不便修改,延遲大,網絡開銷大,成本高。

2. HDFS的shell(命令行客戶端)常用操作

命令參數 功能描述 示例
-help 輸出這個命令參數手冊詳細內容 hadoop fs -help
輸出命令行客戶端支持的命令參數,命令參數手冊縮小版 hadoop fs
-ls 顯示目錄信息 hadoop fs /
-mkdir 在hdfs上創建目錄 hadoop fs -mkdir -p /aaa/bbb
-mv 在hdfs目錄中移動文件 hadoop fs -mv /aaa/jdk.tar.gz /bbb
-moveFromLocal 從本地剪切粘貼到hdfs hadoop fs -moveFromLocal /home/hadoop/a.txt /aaa/bbb
-moveToLocal 從hdfs剪切粘貼到本地 hadoop fs -moveToLocal /aaa/bbb /home/hadoop/a.txt
-cp 從hdfs的一個路徑拷貝到hdfs的另一個路徑 hadoop fs -cp /aaa/jdk.tar.gz /bbb/jdk.tar.gz
-copyFromLocal 從本地文件系統中拷貝文件到hdfs路徑去 hadoop fs -copyFromLocal ./jdk.tar.gz /aaa/
-copyToLocal 從hdfs拷貝到本地 hadoop fs -copyToLocal /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,從本地文件系統中拷貝文件到hdfs路徑去 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
-cat 顯示文件內容 hadoop fs -cat /hello.txt
-tail 顯示一個文件的末尾 hadoop fs -tail /weblog/access_log.1
-text 以字符形式打印一個文件的內容 hadoop fs -text /weblog/access_log.1
-appendToFile 追加一個文件到已經存在的文件末尾 hadoop fs -appendToFile ./hellotx /hello.tx
-chmod linux文件系統中的用法一樣,對文件所屬權限 hadoop fs -chmod 666 /hello.txt
-chown linux文件系統中的用法一樣,對文件所屬用戶以及用戶組的修改 hadoop fs -chown hadoop:hadoop /hello.tx
-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

註意:-setrep設置的副本數只是記錄在namenode的元數據中,是否真的會有這麽多副本,還得看datanode的數量。

3. HDFS的工作機制

3.1 概述

(1) HDFS集群分為兩大角色:NameNode、DataNode;

(2) NameNode負責管理整個文件系統的元數據;

(3) DataNode負責管理用戶的文件數據塊;

(4) 文件會按照固定的大小(blocksize)切成若幹塊分布式存儲在若幹臺datanode上;

(5) 每一個文件塊可以有多個副本,並存放在不同的datanode上;

(6) DatanNode會定期向NameNode匯報自身所保存的文件block信息,而NameNode則會負責保持文件的副本數量;

(7) HDFS的內部工作機制對客戶端保持透明,客戶端請求訪問HDFS都是通過向NameNode申請來進行。

3.2 HDFS寫數據流程

3.2.1 概述

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

3.2.3 HDFS寫數據詳細流程圖

技術分享圖片

(1) 向namenode通信請求上傳文件hello.txt;

(2) namenode通過目錄樹檢查目標文件是否已存在,父目錄是否存在;

(3) namenode返回是否可以上傳信息;

(4) client向namenode請求第一個block應該傳輸到哪些datanode服務器上;

(5) namenode在datanode信息池查詢可用的datanode信息;

(6) namenode返回3個可用的datanode服務器node1、node3、node4;

(7) client向3臺datanode服務器中的一臺node1請求建立傳輸通道channel(本質上是一個RPC調用,建立pipeline),node1收到請求會繼續向node3請求,然後node3請求node4,將整個pipeline建立完成。

(8) 承接第7步,將響應逐級返回給客戶端;

(9) client開始往node1上傳第一個block(先從磁盤讀取數據放到一個本地內存緩存),以packet為單位,node1收到一個packet就會傳給node3,node3傳給node4;node1每傳一個packet會放入一個應答隊列等待應答;

(10) 當一個block傳輸完成之後,client再次請求namenode上傳第二個block的服務器。

3.3 HDFS讀數據流程

3.3.1 概述

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

3.3.2 HDFS讀數據詳細流程

技術分享圖片

(1) 向namenode通信請求讀取文件hello.txt;

(2) namenode查詢hello.txt的元數據,找到文件塊所在的datanode服務器;

(3) namenode向client返回目標文件的元數據;

(4) client挑選一臺datanode服務器(就近原則,然後隨機),請求讀取數據塊BLK_1並請求建立socket流;

(5) datanode與client建立socket流,並開始傳輸數據;

(6) 然後client隨機挑選第二臺datanode服務器並獲取第二個block "BLK_2";

(7) 接著client再次隨機挑選另一臺datanode服務器並獲取第三個block "BLK_3";

(8) 客戶端以packet為單位接收來自datanode服務器的數據,先本地緩存,以追加的模式合並成目標文件,最後把目標文件寫入到本地。

3.4 NAMENODE工作機制

學習目標:理解namenode的工作機制尤其是元數據管理機制,以增強對HDFS工作原理的理解,及培養hadoop集群運營中“性能調優”、“namenode”故障問題的分析解決能力。

3.4.1 概述

NAMENODE職責:

① 負責客戶端請求的響應;
元數據的管理(查詢、修改)

3.4.2 元數據管理與存儲機制

namenode對元數據的管理采用了三種存儲形式:

①內存元數據(NameSystem);
②磁盤元數據鏡像文件;
③數據操作日誌文件(可通過日誌運算出元數據);

元數據的存儲機制

A、內存中有一份完整的元數據(內存 meta data)

B、磁盤有一個“準完整”的元數據鏡像(fsimage)文件,在namenode的工作目錄中;

C、用於銜接內存metadata和持久化元數據鏡像fsimage之間的操作日誌(edits日誌文件);

註意:當客戶端對hdfs中的文件進行新增或修改操作,操作記錄首先被記入edits日誌文件中,當客戶端操作成功後,相應的元數據會更新到內存meta.data中。

3.4.3 元數據手動查看

可以通過hdfs的一個工具來查看edits中的信息

bin/hdfs oev -i edits -o edits.xml
bin/hdfs oiv -i fsimage_0000000000000000087 -p XML -o fsimage.xml

3.4.4 元數據的checkpoint

每隔一段時間,會由secondary namenode 將 namenode上積累的所有edits和一個最新的fsimage下載到本地,並加載到內存進行merge(這個過程稱為checkpiont)。

3.4.4.1 checkpoint的詳細過程

技術分享圖片

3.4.4.2 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之間最大的操作記錄

3.4.4.3 checkpoint的附帶作用

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

3.4.5 元數據目錄說明

在第一次部署好Hadoop集群的時候,我們需要在NameNode節點上格式化磁盤:

$HADOOP_HOME/bin/hdfs namenode -format

格式化完成之後,將會在$dfs.namenode.name.dir/current目錄下創建如下文件結構:

current/
|-- VERSION
|-- edits_*
|-- fsimage_0000000000008547077
|-- fsimage_0000000000008547077.md5
`-- seen_txid

下面對$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) 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。

(3) cTime表示NameNode存儲時間的創建時間,由於我的NameNode沒有更新過,所以這裏的記錄為0,以後對NameNode升級之後,cTime將會記錄更新時間戳;

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

(5) blockpoolID:是針對每一個NameSpace所對應的blockpool的ID,上面的這個BP-893790215-192.168.24.72-1383809616115就是在我的ns1的namespace下的存儲塊池的ID,這個ID包括了其對應的NameNode節點的ip地址。

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

2. $dfs.namenode.name.dir/current目錄下在format的同時也會生成fsimage和edits文件,及其對應的md5校驗文件。

3. $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的資訊。

註意:seen_txid。文件中記錄的edits滾動的序號,每次重啟namenode時,namenode就知道要將哪些edits進行加載edits。

補充說明

其中dfs.name.dir是在hdfs-site.xml文件中配置的,而hadoop.tmp.dir是在core-site.xml中配置的,默認值如下: 

#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)之上,即使你這臺機器損壞了,元數據也得到保存。

3.5 DATANODE的工作機制

3.5.1 概述

(1) Data工作職責:

①存儲管理用戶的文件塊數據;
②定期向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設置為50000(毫秒),dfs.heartbeat.interval設置為3(秒,默認),則總的超時時間為40秒。

<property>
        <name>heartbeat.recheck.interval</name>
        <value>300000</value>
</property>
<property>
        <name>dfs.heartbeat.interval</name>
        <value>3</value>
</property>

3.5.2 觀察驗證DATANODE功能

上傳一個文件,觀察文件的block具體的物理存放情況:

在每一臺datanode機器上的data存放目錄中能找到文件的切塊,假設data目錄設定為/opt/app/hadoop-2.4.1/data,則文件切塊目錄為/opt/app/hadoop-2.4.1/data/current/BP-*****/current/finalized

Hadoop — HDFS的概念、原理及基本操作