1. 程式人生 > >Hadoop簡介及HDFS

Hadoop簡介及HDFS

1.Hadoop簡介

Hadoop是Apache基金會開發的分散式系統基礎架構。開創者是Lucene–Doug Cutting,而Google是hadoop的思想之源(GFS–>HDFS,Map-Reduce–>MR,BigTable–>HBase)。 目前主流的是2.0x版本的Hadoop,它由HDFS、Mapreduce、Yarn、Core四個部分組成。

Hadoop 的優勢

1)高可靠性:因為 Hadoop 假設計算元素和儲存會出現故障,因為它維護多個工作資料副 本,在出現故障時可以對失敗的節點重新分佈處理。 2)高擴充套件性:在叢集間分配任務資料,可方便的擴充套件數以千計的節點。 3)高效性:在 MapReduce 的思想下,Hadoop 是並行工作的,以加快任務處理速度。 4)高容錯性:自動儲存多份副本資料,並且能夠自動將失敗的任務重新分配。

Hadoop 組成

1)Hadoop HDFS:一個高可靠、高吞吐量的分散式檔案系統。 2)Hadoop MapReduce:一個分散式的離線平行計算框架。 3)Hadoop YARN:作業排程與叢集資源管理的框架。 4)Hadoop Common:支援其他模組的工具模組(Configuration、RPC、序列化機制、日誌操作)。

2.HDFS

HDFS架構

在這裡插入圖片描述

這種架構主要由四個部分組成,分別為 HDFS Client、NameNode、DataNode 和 Secondary NameNode。下面我們分別介紹這四個組成部分。 1)Client:就是客戶端。 (1)檔案切分。檔案上傳 HDFS 的時候,Client 將檔案切分成一個一個的 Block,然後進行儲存。 (2)與 NameNode 互動,獲取檔案的位置資訊。 (3)與 DataNode 互動,讀取或者寫入資料。 (4)Client 提供一些命令來管理 HDFS,比如啟動或者關閉HDFS。 (5)Client 可以通過一些命令來訪問 HDFS。 2)NameNode:就是 master,它是一個主管、管理者。 (1)管理 HDFS 的名稱空間。 (2)管理資料塊(Block)對映資訊 (3)配置副本策略 (4)處理客戶端讀寫請求。 3)DataNode:就是 Slave。NameNode 下達命令,DataNode 執行實際的操作。 (1)儲存實際的資料塊。 (2)執行資料塊的讀/寫操作。 4)Secondary NameNode:並非 NameNode 的熱備。當 NameNode 掛掉的時候,它並不能馬上替換 NameNode 並提供服務。 (1)輔助 NameNode,分擔其工作量。 (2)定期合併 Fsimage 和 Edits,並推送給 NameNode。 (3)在緊急情況下,可輔助恢復 NameNode。

HDFS讀/寫操作

在這裡插入圖片描述 客戶端在讀取資料時,會有一個就近原則,挑選最近的datenode來讀取資料。

在這裡插入圖片描述 在寫資料時,因為副本數預設為3,所以第一個副本在client所在的節點,第二個副本在第一個副本所在的機架的隨機節點上,第三個副本在不同機架的隨機節點。這裡體現了HDFS的高容錯性。

DataNode的工作機制

在這裡插入圖片描述 這裡需要注意的是datanode向namenode註冊之後,每3s返回一次心跳;若10分鐘namenode沒有收到來自datanode的心跳訊息,則判定datanode死亡;datanode每小時上報所有的塊訊息給namenode。還有datanode的block中的資料有校驗和,它會在讀取資料時,通過orc奇偶校驗判斷資料是否損壞,保證了資料的完整性。

HDFS的高可用

可以通過兩個NameNode實現避免單點故障導致的服務中斷。 若要實現高可用,元資料的管理方式需要改變,在之前是儲存在namenode,可以通過secondrynamenode來幫助namenode恢復資料、整合資料。需要改變為,兩個namenode都儲存有元資料,但是隻有active狀態的namenode來實現寫edits,共享的edits可以放在jounalnode中。 但是上面說的這種方式,如果一臺namenode宕機了,另一臺機器還需要我們手動來從standby狀態轉為active狀態。所以要通過zookeeper這個提供協調服務的軟體,namenode會在zookeeper中維護一個持久會話,如果這個會話中斷了,zookeeper就知道該namenode發生了故障,立即通知另一臺namenode轉換為active提供服務。每臺執行namenode的機器也運行了zkfc的程序,該程序對namenode進行監控,並可以獲得znode鎖,保證了只有一個namenode為active。 在這裡插入圖片描述

3.HDFS配置

前提條件

  1. 準備幾臺虛擬機器,最少三臺
  2. 將機器的網路配置好,如果後面幾臺機器的是克隆的話,需要進行下面3、4、5、6步,若不是克隆的就跳過。
  3. 需要修改/etc/udev/rules.d/70-persistent-net.rules 將eth0網絡卡刪除,再將eth1改為eth0,複製mac地址
  4. vi /etc/sysconfig/network 中的hostname
  5. vi /etc/sysconfig/network-scripts/ifcfg-eth0 將HWADDR改為剛才複製的mac地址,IPADDR修改ip地址。
  6. vi /etc/hosts 對主機名進行ip對映。
  7. 裝好JDK和Hadoop,在/etc/profile下配置/jdk/bin和/hadoop/bin以及/hadoop/sbin
  8. 關閉防火牆,service iptables stop
  9. 開啟免密登入。通過ssh-keygen 生成私鑰和公鑰,再用ssh-copy-id將公鑰拷給需要免密登入的機器。

單機版

只需要將jdk配置好,hadoop解壓後,在hadoop/etc/hadoop/hadoop-env.sh中配置下jdk的路徑,這樣就實現了單機版的配置。

偽分散式

修改core-site.xml

 	<!-- 指定HDFS 中 NameNode 的地址 -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://hadoop101:9000</value>
</property>

<!-- 指定 hadoop 執行時產生檔案的儲存目錄 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/module/hadoop-2.7.2/data/tmp</value>
</property>

修改hdfs-site.xml

<property>
<name>dfs.replication</name>
<value>1</value>
</property>

全分散式

  1. cd /usr/local/hadoop/etc/hadoop/ 進入該路徑中配置hadoop檔案

  2. mv mapred-site.xml.template mapred-site.xml 將檔案改名

  3. vi core-site.xml (以下紅色的均為看實際情況可變的)

     <property>
     <name>fs.defaultFS</name>
     <value>hdfs://hadoop01:9000</value>
     </property> 
     <!-- 指定 hadoop 執行時產生檔案的儲存目錄 -->
     <property>
     <name>hadoop.tmp.dir</name>
     <value>/usr/local/hadoop-2.7.2/data/tmp</value>
     </property>
    
  4. vi hdfs-site.xml

     <!--文字副本數為3-->
     <property>
     <name>dfs.replication</name>
     <value>3</value>
     </property>
     <!--SecondaryNameNode地址-->
     <property>
     <name>dfs.namenode.secondary.http-address</name>
     <value>hadoop03:50090</value>
     </property>
    
  5. vi yarn-site.xml

     <property>
     <name>yarn.nodemanager.aux-services</name>
     <value>mapreduce_shuffle</value>
     </property>
     <!-- 指定 YARN 的 ResourceManager 的地址 -->
     <property>
     <name>yarn.resourcemanager.hostname</name>
     <value>hadoop02</value>
     </property>
     <!-- 日誌聚集功能使能 -->
     <property>
     <name>yarn.log-aggregation-enable</name>
     <value>true</value>
     </property>
     <!-- 日誌保留時間設定 7 天 -->
     <property>
     <name>yarn.log-aggregation.retain-seconds</name>
     <value>604800</value>
     </property>
    
  6. vi mapred-site.xml

     <property>
     <name>mapreduce.jobhistory.address</name>
     <value>hadoop02:10020</value>
     </property>
     <property>
     <name>mapreduce.jobhistory.webapp.address</name>
     <value>hadoop02:19888</value>
     </property>
     <!-- 指定 mr 執行在 yarn 上 -->
     <property>
     <name>mapreduce.framework.name</name>
     <value>yarn</value>
     </property>
    

高可用HA

  1. 配置hdfs-site.xml

     	<name>dfs.replication</name>
     	<value>3</value>
     	</property>
     				<!--配置nameservice-->
     	<property>
     				<name>dfs.nameservices</name>
     				<value>mycluster</value>
     			</property>
     		<!--myucluster下的名稱節點兩個id -->
     <property>
     			<name>dfs.ha.namenodes.mycluster</name>
     			<value>nn1,nn2</value>
     		</property>
     					<!--配置每個nn的rpc地址-->
     <property>
     			<name>dfs.namenode.rpc-address.mycluster.nn1</name>
     			<value>hadoop01:8020</value>
     		</property>
     <property>
     			<name>dfs.namenode.rpc-address.mycluster.nn2</name>
     			<value>hadoop02:8020</value>
     		</property>
     		
     					<!--配置webui埠-->
     	<property>
     			<name>dfs.namenode.http-address.mycluster.nn1</name>
     			<value>hadoop01:50070</value>
     		</property>
     		<property>
     			<name>dfs.namenode.http-address.mycluster.nn2</name>
     			<value>hadoop02:50070</value>
     		</property>
     		
     					<!--名稱節點共享編輯目錄-->
     		<property>
     			<name>dfs.namenode.shared.edits.dir</name>
     			<value>qjournal://hadoop01:8485;hadoop02:8485;hadoop03:8485/mycluster</value>
     		</property>
     		
     		<!--java類,client使用它判斷哪個節點是啟用態-->
     		<property>
     			<name>dfs.client.failover.proxy.provider.mycluster</name>
     			<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
     		</property>
     		
     		<!--指令碼列表或者java類,在容災保護啟用態的nn-->
     		<property>
     			<name>dfs.ha.fencing.methods</name>
     			<value>
     					sshfence
     					shell(/bin/true)
     			</value>
     		</property>
     
     		<property>
     			<name>dfs.ha.fencing.ssh.private-key-files</name>
     			<value>/root/.ssh/id_rsa</value>
     		</property>
     		
     		<!--配置JN存放edit的本地路徑-->
     				<property>
     			<name>dfs.journalnode.edits.dir</name>
     			<value>/usr/local/hadoop-2.7.2/data/jn</value>
     		</property>
     <!-- 訪問代理類:client,mycluster,active 配置失敗自動切換實現方式-->
     <property>
     <name>dfs.client.failover.proxy.provider.mycluster</name>
     <value>
     org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider
     </value>
     </property>
     <!-- 關閉許可權檢查-->
     <property>
     <name>dfs.permissions.enable</name>
     <value>false</value>
     </property>
    
  2. 配置core-site.xml

     <property>
     			<name>fs.defaultFS</name>
     			<value>hdfs://mycluster</value>
     		</property>
     		
     		
     <!-- 指定 hadoop 執行時產生檔案的儲存目錄 -->
     <property>
     <name>hadoop.tmp.dir</name>
     <value>/usr/local/hadoop-2.7.2/data/tmp</value>
     </property>
    
  3. 同步core-site.xml和hdfs-site.xml

  4. 檢測

     1)在jn節點分別啟動jn程序
     				hadoop-daemon.sh start journalnode
     		2)啟動jn之後,在兩個NN之間進行disk元資料同步
     					a)如果是全新叢集,先format檔案系統,只需要在一個nn上執行。
     					$>hadoop namenode -format
     				b)如果將非HA叢集轉換成HA叢集,複製原NN的metadata到另一個nn.
     					1.步驟一
     						在hadoop01中
     						$>scp -r /usr/local/hadoop-2.7.2/data/tmp/dfs/name   hadoop02:/usr/local/hadoop-2.7.2/data/tmp/dfs/
     					2.步驟二
     						在新的nn(未格式化的nn)上執行一下命令,實現待命狀態引導。
     		在[nn2]上,同步 nn1 的元資料資訊:
     						$>hdfs namenode -bootstrapStandby		//需要hadoop01的namenode為啟動狀態,提示是否格式化,選擇N.
     					3)在一個NN上執行以下命令,完成edit日誌到jn節點的傳輸。
     						$>hdfs namenode -initializeSharedEdits
     					4)啟動所有節點.
     		在hadoop02中
     						$>hadoop-daemon.sh start namenode		//啟動名稱節點
     						$>hadoop-daemons.sh start datanode		//啟動所有資料節點
     		在hadoop02中
     						$>hadoop-daemon.sh start namenode		//啟動名稱節點
    

hdfs haadmin -transitionToActive nn1 //切成啟用態 hdfs haadmin -transitionToStandby nn1 //切成待命態 hdfs haadmin -transitionToActive --forceactive nn2//強行啟用 hdfs haadmin -failover nn1 nn2 //模擬容災演示,從nn1切換到nn2 hdfs haadmin -getServiceState nn1 //檢視狀態

配置 HDFS-HA 自動故障轉移

  1. 在hdfs-site.xml中

     <property>
     	<name>dfs.ha.automatic-failover.enabled</name>
     	<value>true</value>
     	</property>
     	在core-site.xml中
     	<property>
     	<name>ha.zookeeper.quorum</name>
     	<value>hadoop01:2181,hadoop02:2181,hadoop03:2181</value>
     	</property>
    
  2. 同步!!!

  3. 啟動 (1) 關閉所有 HDFS 服務: sbin/stop-dfs.sh (2) 啟動 Zookeeper 叢集: bin/zkServer.sh start (3) 初始化HA 在 Zookeeper 中狀態: bin/hdfs zkfc -formatZK 成都 (4) 啟動HDFS 服務: sbin/start-dfs.sh (5) 在各個 NameNode 節點上啟動 DFSZK Failover Controller,先在哪臺機器啟動,哪個機器的NameNode 就是 Active NameNode sbin/hadoop-daemon.sh start zkfc (6) 驗證 (1) 將 Active NameNode 程序 kill kill -9 namenode 的程序 id (2) 將 Active NameNode 機器斷開網路 service network stop

YARN的高可用

  1. 在yarn-site.xml中

     <property>
     <name>yarn.nodemanager.aux-services</name>
     <value>mapreduce_shuffle</value>
     </property>
     
     <!-- 指定 YARN 的 ResourceManager 的地址 
     <property>
     <name>yarn.resourcemanager.hostname</name>
     <value>hadoop02</value>
     </property>-->
     
     <property>
       <name>yarn.resourcemanager.ha.enabled</name>
       <value>true</value>
     </property>
     <property>
       <name>yarn.resourcemanager.cluster-id</name>
       <value>cluster1</value>
     </property>
     <property>
       <name>yarn.resourcemanager.ha.rm-ids</name>
       <value>rm1,rm2</value>
     </property>
     <property>
       <name>yarn.resourcemanager.hostname.rm1</name>
       <value>hadoop01</value>
     </property>
     <property>
       <name>yarn.resourcemanager.hostname.rm2</name>
       <value>hadoop03</value>
     </property>
     <property>
       <name>yarn.resourcemanager.webapp.address.rm1</name>
       <value>hadoop01:8088</value>
     </property>
     <property>
       <name>yarn.resourcemanager.webapp.address.rm2</name>
       <value>hadoop03:8088</value>
     </property>
     <property>
       <name>yarn.resourcemanager.zk-address</name>
       <value>hadoop01:2181,hadoop02:2181,hadoop03:2181</value>
     </property>
     
     <!--啟用自動恢復-->
     <property>
     <name>yarn.resourcemanager.recovery.enabled</name>
     <value>true</value>
     </property>
     <!--指定 resourcemanager 的狀態資訊儲存在zookeeper 叢集-->
     <property>
     <name>yarn.resourcemanager.store.class</name>
     <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
     </property>
     <!-- 日誌聚集功能使能 -->
     <property>
     <name>yarn.log-aggregation-enable</name>
     <value>true</value>
     </property>
     <!-- 日誌保留時間設定 7 天 -->
     <property>
     <name>yarn.log-aggregation.retain-seconds</name>
     <value>604800</value>
     </property>
    
  2. 同步yarn-site.xml

  3. 先啟動hdfs

  4. 啟動 yarn (1) 在 hadoop102 中執行: sbin/start-yarn.sh (2) 在 hadoop103 中執行: sbin/yarn-daemon.sh start resourcemanager (3) 檢視服務狀態 bin/yarn rmadmin -getServiceState rm1

補充:如果沒有配置高可用的話,namenode出現故障了怎麼辦???

在主namenode發生故障時 ( 假設 沒 有 及 時 備 份 數 據 ) ,可以 從SecondaryNameNode 恢復資料。

方法一:將 SecondaryNameNode 中資料拷貝到 namenode 儲存資料的目錄; 方法 二: 使用 -importCheckpoint 選項 啟動 namenode 守 護 進 程 ,從而將SecondaryNameNode 中資料拷貝到 namenode 目錄中。

一、手動拷貝 SecondaryNameNode 資料: 模擬 namenode 故障,並採用方法一,恢復 namenode 資料 1) kill -9 namenode 程序

 jps檢視一下

2) 刪除 namenode 儲存的資料(data/tmp/dfs/name)

  rm -rf    name

3) 拷貝 SecondaryNameNode 中資料到原 namenode 儲存資料目錄

scp -r [email protected]:/usr/local/hadoop-2.7.2/data/tmp/dfs/namesecondary/*   拷貝到原來name地方
 namesecondary 改名name  並把current in_use.lock刪除掉。

4) 重新啟動 namenode

   sbin/hadoop-daemon.sh start namenode

二、採用 importCheckpoint 命令拷貝 SecondaryNameNode 資料 模擬 namenode 故障,並採用方法二,恢復 namenode 資料

修改 hdfs-site.xml 中的

<property>
<name>dfs.namenode.checkpoint.period</name>
<value>120</value>
</property>
 
<property>
<name>dfs.namenode.name.dir</name>
<value>/usr/local/hadoop-2.7.2/data/tmp/dfs/name</value>
</property>

1) kill -9 namenode 程序 2) 刪除 namenode 儲存的資料(data/tmp/dfs/name) 一般上namenode都是name下的

   rm -rf /etc/local/hadoop-2.7.2/data/tmp/dfs/name/*

3 )如果 SecondaryNameNode 不和 Namenode 在 一個 主機 節點上,需要將 SecondaryNameNode 儲存資料的目錄拷貝到 Namenode 儲存資料的平級目錄, 並刪除 in_use.lock 檔案。

   scp -r [email protected]:/usr/local/had../data/tmp/dfs/namesecondary   ./
   rm -rf in_use.lock

4)匯入檢查點資料(等待一會 ctrl+c 結束掉)

bin/hdfs namenode -importCheckpoint

5)啟動 namenode

   sbin/hadoop-daemon.sh start namenode

總結

   通過以上對於Hadoop的簡介可以看出來,Hadoop其實就是一個分散式的大資料處理架構平臺,如今Hadoop已經成為一個生
態圈,它的生態圈中有許多元件,可以幫我們儲存海量的資料,也可以幫助我們對海量的資料進行處理分析。
   而HDFS是Hadoop生態圈中的一個很厲害的元件,它是一個分散式檔案儲存系統,為我們的以後處理的資料提供了一個儲存數
據的平臺。而且它的容錯機制為我們儲存資料提供了保障,防止某臺機器發生故障導致資料丟失。但是它的缺點也很明顯,不能像
我們儲存在本地那樣可以隨意修改,只支援一個執行緒去修改,而且不適合去儲存很多小檔案。因為在每次namenode啟動時,會將
fsimage載入到記憶體中,小檔案元資料資訊太多會浪費namenode的記憶體,但正因為namenode記錄著元資料資訊,我們讀取或寫
資料的時候,我們並不需要知道檔案儲存在哪臺datanode,我們只需要對檔案進行拉取或者寫入操作就行,方便了我們的操作。
   但對於剛學習Hadoop的人們,沒必要配置HA,配置全分佈就行。因為HA確實很耗費資源,會導致以後hive之類以MR為底層的
計算過程耗時比較長。

										summed up by JiaMingcan
										轉載請署名:JiaMingcan