HDFS概述
HDFS產生背景
隨著數據量越來越大,在一個操作系統存不下所有的數據,那麼就分配到更多的操作系統管理的磁盤中,但是不方便管理和維護,迫切需要一種系統來管理多臺機器上的文件,這就是分佈式文件管理系統。HDFS只是分佈式文件管理系統的一種。
HDFS定義
HDFS(Hadoop Distributed File System),它是一個文件系統,用於存儲文件,通過目錄樹來定位文件,其次,它是分佈式的,由很多服務器聯合起來來實現其功能,集群中的服務器有各自的角色。
HDFS的使用場景:適合一次寫入,多次讀出的場景,且不支持文件的修改,適合用來做數據分析,並不適合用來網盤應用。
HDFS優缺點
優點:
1.高容錯性
(1)數據自動保存多個副本,它通過增加副本的形式,提高容錯性。
(2)某一個副本丟失以後,它可以自動恢復。
2.適合處理大數據
(1)數據規模:能夠處理數據規模達到GB,TB甚至PB級別的數據
(2)文件規模:能夠處理百萬規模以上的文件數量,數量相當之大。
3.可構建在廉價的機器上,通過多副本機制,提高可靠性。
缺點:
1.不適合低延時數據訪問,比如毫秒級的存儲數據,是做不到的。
2.無法高效的對大量小文件進行存儲。
(1)存儲大量的小文件的話,它只會佔用NameNode大量的內存來存儲文件目錄和塊信息。這樣是不可取的,因為NameNode的內存總是有限的。
(2)小文件存儲的是尋址時間會超過讀取時間,它違反了HDFS的設計目標。
(3)不支持併發寫入,文件隨機修改
一個文件只能有一個寫,不允許多個線程同時寫。
僅支持數據的append(追加),不支持文件的隨機修改。
HDFS組成架構
1.NameNode(nn):就是Master,它是一個主管,管理者。
(1)管理HDFS的名稱空間
(2)配置副本策略
(3)管理數據塊(Block)映射信息
(4)處理客戶端讀寫請求
2.DataNode:就是Slave,NameNode下達命令,DataNode執行實際的操作。
(1)存儲實際的數據塊
(2)執行數據塊的讀/寫操作
3.Client:就是客戶端
(1)文件切分,文件上傳HDFS的時候,Client將文件切分成一個一個的Block,然後上傳。
(2)與NameNode交互,獲取文件的位置信息
(3)與DataNode交互,讀取或者寫入數據
(4)Client提供一些命令來管理HDFS,比如NameNode格式化
(5)Client可以通過一些命令來訪問HDFS,比如對HDFS增刪改查操作
4.Secondary NamNode:並非NameNode的熱備,當NameNode掛掉的時候,它並不能馬上替換NameNode並提供服務。
(1)輔助NameNode,分擔其工作量,比如定期合併Fsimage和Edits,並推送給NameNode。
(2)在緊急情況下,可輔助恢復NameNode。
HDFS文件塊大小
HDFS中的文件在物理上是分塊存儲(Block),塊的大小可以通過配置參數(dfs.blocksize)來規定,默認大小在Hadoop2.x版本中是128M,在老版本是64M。
為什麼塊的大小不能設置太小,也不能設置太大?
(1)HDFS的塊設置太小,會增加尋址時間,程序一直在找塊的開始位置
(2)如果塊設置的太大,從磁盤傳輸數據的時間會明顯大於定位這個塊的開始位置所需的時間,導致程序在處理這塊數據時,會非常的慢。
HDFS塊的大小設置主要取決於磁盤的傳輸速率。
HDFS的Shell操作
bin/hadoop fs 具體命令 OR bin/hdfs dfs 具體命令
dfs是fs的實現類。
常用命令實操
(1)啟動Hadoop集群
<code> sbin/start-dfs.sh sbin/start-yarn.sh/<code>
(2)-help:輸出這個命令參數
<code>hadoop fs -help rm/<code>
(3)-ls: 顯示目錄信息
<code>hadoop fs -ls //<code>
(4)-mkdir:在HDFS上創建目錄
<code>hadoop fs -mkdir -p /test/my/<code>
(5)-moveFromLocal:從本地剪切粘貼到HDFS
<code>touch 111.txt hadoop fs -moveFromLocal ./111.txt /test/my/<code>
(6)-appendToFile:追加一個文件到已經存在的文件末尾
<code>touch 222.txt vi 222.txt #輸入 12345678 hadoop fs -appendToFile 222.txt /test/my/111.txt/<code>
(7) -cat:顯示文件內容
<code>hadoop fs -cat /test/my/111.txt/<code>
(8) -chgrp 、-chmod、-chown:Linux文件系統中的用法一樣,修改文件所屬權限
<code>hadoop fs -chmod 666 /test/my/111.txt/<code>
(9)-copyFromLocal:從本地文件系統中拷貝文件到HDFS路徑去
<code>hadoop fs -copyFromLocal README.txt //<code>
(10)-copyToLocal:從HDFS拷貝到本地
<code>hadoop fs -copyToLocal /test/my/111.txt .//<code>
(11)-cp :從HDFS的一個路徑拷貝到HDFS的另一個路徑
<code>hadoop fs -cp /test/my/111.txt /333.txt/<code>
(12)-mv:在HDFS目錄中移動文件
<code>hadoop fs -mv /333.txt /test/my//<code>
(13)-get:等同於copyToLocal,就是從HDFS下載文件到本地
<code>hadoop fs -get /test/my/111.txt .//<code>
(14)-getmerge:合併下載多個文件,比如HDFS的目錄 /user/hadoop/test下有多個文件:log.1, log.2,log.3,...
<code>hadoop fs -getmerge /user/hadoop/test/* ./444.txt/<code>
(15)-put:等同於copyFromLocal
<code>hadoop fs -put ./444.txt /user/hadoop/test//<code>
(16)-tail:顯示一個文件的末尾
<code>hadoop fs -tail /test/my/111.txt/<code>
(17)-rm:刪除文件或文件夾
<code>hadoop fs -rm /user/hadoop/test/444.txt/<code>
(18)-rmdir:刪除空目錄
<code>hadoop fs -mkdir /test hadoop fs -rmdir /test/<code>
(19)-du統計文件夾的大小信息
<code>hadoop fs -du -s -h /user/hadoop/test 2.7 K /user/hadoop/test/<code>
(20)-setrep:設置HDFS中文件的副本數量
<code>hadoop fs -setrep 10 /test/my/111.txt/<code>
這裡設置的副本數只是記錄在NameNode的元數據中,是否真的會有這麼多副本,還得看DataNode的數量。因為目前只有3臺設備,最多也就3個副本,只有節點數的增加到10臺時,副本數才能達到10。
HDFS客戶端操作
下載Hadoopjar包,配置環境變量。
創建一個Maven工程HdfsClientDemo
導入相應的依賴座標+日誌添加
<code> junit junit RELEASE org.apache.logging.log4j log4j-core 2.8.2 org.apache.hadoop hadoop-common 2.7.2 org.apache.hadoop hadoop-client 2.7.2 org.apache.hadoop hadoop-hdfs 2.7.2 jdk.tools jdk.tools 1.8 system ${JAVA_HOME}/lib/tools.jar /<code>
在項目的src/main/resources目錄下,新建一個文件,命名為“log4j.properties”
<code>log4j.rootLogger=INFO, stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n log4j.appender.logfile=org.apache.log4j.FileAppender log4j.appender.logfile.File=target/spring.log log4j.appender.logfile.layout=org.apache.log4j.PatternLayout log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n/<code>
創建包,創建HdfsClient類
<code>public class HdfsClient{ @Test public void testMkdirs() throws IOException, InterruptedException, URISyntaxException{ // 1 獲取文件系統 Configuration configuration = new Configuration(); // 配置在集群上運行 // configuration.set("fs.defaultFS", "hdfs://hadoop102:9000"); // FileSystem fs = FileSystem.get(configuration); FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "hadoop"); // 2 創建目錄 fs.mkdirs(new Path("/1108/daxian/banzhang")); // 3 關閉資源 fs.close(); } }/<code>
運行時需要配置用戶名稱
客戶端去操作HDFS時,是有一個用戶身份的。默認情況下,HDFS客戶端API會從JVM中獲取一個參數來作為自己的用戶身份:-DHADOOP_USER_NAME=hadoop,hadoop為用戶名稱。
HDFS文件上傳(測試參數優先級)
1.編寫源代碼
<code>@Test public void testCopyFromLocalFile() throws IOException, InterruptedException, URISyntaxException { // 1 獲取文件系統 Configuration configuration = new Configuration(); configuration.set("dfs.replication", "2"); FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "hadoop"); // 2 上傳文件 fs.copyFromLocalFile(new Path("e:/banzhang.txt"), new Path("/banzhang.txt")); // 3 關閉資源 fs.close(); System.out.println("over"); }/<code>
2.將hdfs-site.xml拷貝到項目的根目錄下
<code> dfs.replication 1 /<code>
3.參數優先級
參數優先級排序:(1)客戶端代碼中設置的值 >(2)ClassPath下的用戶自定義配置文件 >(3)然後是服務器的默認配置
HDFS文件下載
<code>@Test public void testCopyToLocalFile() throws IOException, InterruptedException, URISyntaxException{ // 1 獲取文件系統 Configuration configuration = new Configuration(); FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "hadoop"); // 2 執行下載操作 // boolean delSrc 指是否將原文件刪除 // Path src 指要下載的文件路徑 // Path dst 指將文件下載到的路徑 // boolean useRawLocalFileSystem 是否開啟文件校驗 fs.copyToLocalFile(false, new Path("/banzhang.txt"), new Path("e:/banhua.txt"), true); // 3 關閉資源 fs.close(); }/<code>
HDFS文件夾刪除
<code>@Test public void testDelete() throws IOException, InterruptedException, URISyntaxException{ // 1 獲取文件系統 Configuration configuration = new Configuration(); FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "hadoop"); // 2 執行刪除 fs.delete(new Path("/0508/"), true); // 3 關閉資源 fs.close(); }/<code>
HDFS文件名更改
<code>@Test public void testRename() throws IOException, InterruptedException, URISyntaxException{ // 1 獲取文件系統 Configuration configuration = new Configuration(); FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "hadoop"); // 2 修改文件名稱 fs.rename(new Path("/banzhang.txt"), new Path("/banhua.txt")); // 3 關閉資源 fs.close(); }/<code>
HDFS文件詳情查看
查看文件名稱、權限、長度、塊信息
<code>@Test public void testListFiles() throws IOException, InterruptedException, URISyntaxException{ // 1獲取文件系統 Configuration configuration = new Configuration(); FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "hadoop"); // 2 獲取文件詳情 RemoteIterator listFiles = fs.listFiles(new Path("/"), true); while(listFiles.hasNext()){ LocatedFileStatus status = listFiles.next(); // 輸出詳情 // 文件名稱 System.out.println(status.getPath().getName()); // 長度 System.out.println(status.getLen()); // 權限 System.out.println(status.getPermission()); // 分組 System.out.println(status.getGroup()); // 獲取存儲的塊信息 BlockLocation[] blockLocations = status.getBlockLocations(); for (BlockLocation blockLocation : blockLocations) { // 獲取塊存儲的主機節點 String[] hosts = blockLocation.getHosts(); for (String host : hosts) { System.out.println(host); } } System.out.println("-----------班長的分割線----------"); } // 3 關閉資源 fs.close(); }/<code>
HDFS文件和文件夾判斷
<code>@Test public void testListStatus() throws IOException, InterruptedException, URISyntaxException{ // 1 獲取文件配置信息 Configuration configuration = new Configuration(); FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "hadoop"); // 2 判斷是文件還是文件夾 FileStatus[] listStatus = fs.listStatus(new Path("/")); for (FileStatus fileStatus : listStatus) { // 如果是文件 if (fileStatus.isFile()) { System.out.println("f:"+fileStatus.getPath().getName()); }else { System.out.println("d:"+fileStatus.getPath().getName()); } } // 3 關閉資源 fs.close(); }/<code>
HDFS的I/O流操作(擴展)
API操作HDFS系統都是框架封裝好的。那麼如果我們想自己實現上述API的操作該怎麼實現呢?
我們可以採用IO流的方式實現數據的上傳和下載。
HDFS文件上傳
需求:把本地e盤上的banhua.txt文件上傳到HDFS根目錄
<code>@Test public void putFileToHDFS() throws IOException, InterruptedException, URISyntaxException { // 1 獲取文件系統 Configuration configuration = new Configuration(); FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "hadoop"); // 2 創建輸入流 FileInputStream fis = new FileInputStream(new File("e:/banhua.txt")); // 3 獲取輸出流 FSDataOutputStream fos = fs.create(new Path("/banhua.txt")); // 4 流對拷 IOUtils.copyBytes(fis, fos, configuration); // 5 關閉資源 IOUtils.closeStream(fos); IOUtils.closeStream(fis); fs.close(); }/<code>
定位文件讀取
需求:分塊讀取HDFS上的大文件,比如根目錄下的/hadoop-2.7.2.tar.gz
(1)下載第一塊
<code>@Test public void readFileSeek1() throws IOException, InterruptedException, URISyntaxException{ // 1 獲取文件系統 Configuration configuration = new Configuration(); FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "hadoop"); // 2 獲取輸入流 FSDataInputStream fis = fs.open(new Path("/hadoop-2.7.2.tar.gz")); // 3 創建輸出流 FileOutputStream fos = new FileOutputStream(new File("e:/hadoop-2.7.2.tar.gz.part1")); // 4 流的拷貝 byte[] buf = new byte[1024]; for(int i =0 ; i < 1024 * 128; i++){ fis.read(buf); fos.write(buf); } // 5關閉資源 IOUtils.closeStream(fis); IOUtils.closeStream(fos); fs.close(); }/<code>
(2)下載第二塊
<code>@Test public void readFileSeek2() throws IOException, InterruptedException, URISyntaxException{ // 1 獲取文件系統 Configuration configuration = new Configuration(); FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "atguigu"); // 2 打開輸入流 FSDataInputStream fis = fs.open(new Path("/hadoop-2.7.2.tar.gz")); // 3 定位輸入數據位置 fis.seek(1024*1024*128); // 4 創建輸出流 FileOutputStream fos = new FileOutputStream(new File("e:/hadoop-2.7.2.tar.gz.part2")); // 5 流的對拷 IOUtils.copyBytes(fis, fos, configuration); // 6 關閉資源 IOUtils.closeStream(fis); IOUtils.closeStream(fos); }/<code>
(3)合併文件
在Window命令窗口中進入到目錄E:\,然後執行如下命令,對數據進行合併
type hadoop-2.7.2.tar.gz.part2 >> hadoop-2.7.2.tar.gz.part1
合併完成後,將hadoop-2.7.2.tar.gz.part1重新命名為hadoop-2.7.2.tar.gz。解壓發現該tar包非常完整。
HDFS的數據流
HDFS寫數據流程
1)客戶端通過Distributed FileSystem模塊向NameNode請求上傳文件,NameNode檢查目標文件是否已存在,父目錄是否存在。
2)NameNode返回是否可以上傳。
3)客戶端請求第一個 Block上傳到哪幾個DataNode服務器上。
4)NameNode返回3個DataNode節點,分別為dn1、dn2、dn3。
5)客戶端通過FSDataOutputStream模塊請求dn1上傳數據,dn1收到請求會繼續調用dn2,然後dn2調用dn3,將這個通信管道建立完成。
6)dn1、dn2、dn3逐級應答客戶端。
7)客戶端開始往dn1上傳第一個Block(先從磁盤讀取數據放到一個本地內存緩存),以Packet為單位,dn1收到一個Packet就會傳給dn2,dn2傳給dn3;dn1每傳一個packet會放入一個應答隊列等待應答。
8)當一個Block傳輸完成之後,客戶端再次請求NameNode上傳第二個Block的服務器。(重複執行3-7步)。
網絡拓撲-節點距離計算
在HDFS寫數據的過程中,NameNode會選擇距離待上傳數據最近距離的DataNode接收數據。那麼這個最近距離怎麼計算呢?
節點距離:兩個節點到達最近的共同祖先的距離總和。
例如,假設有數據中心d1機架r1中的節點n1。該節點可以表示為/d1/r1/n1。
機架感知
第一個副本在Client所處的節點上,如果客戶在集群外,隨機選一個。
第二個副本和第一個副本位於相同的機架,隨機節點。
第三個副本位於不同的機架,隨機節點。
HDFS讀數據流程
1)客戶端通過Distributed FileSystem向NameNode請求下載文件,NameNode通過查詢元數據,找到文件塊所在的DataNode地址。
2)挑選一臺DataNode(就近原則,然後隨機)服務器,請求讀取數據。
3)DataNode開始傳輸數據給客戶端(從磁盤裡面讀取數據輸入流,以Packet為單位來做校驗)。
4)客戶端以Packet為單位接收,先在本地緩存,然後寫入目標文件。
NameNode和SecondaryNameNode
NN和2NN工作機制
思考:NameNode中的元數據是存儲在哪裡的?
首先,我們做個假設,如果存儲在NameNode節點的磁盤中,因為經常需要進行隨機訪問,還有響應客戶請求,必然是效率過低。因此,元數據需要存放在內存中。但如果只存在內存中,一旦斷電,元數據丟失,整個集群就無法工作了。因此產生在磁盤中備份元數據的FsImage。
這樣又會帶來新的問題,當在內存中的元數據更新時,如果同時更新FsImage,就會導致效率過低,但如果不更新,就會發生一致性問題,一旦NameNode節點斷電,就會產生數據丟失。因此,引入Edits文件(只進行追加操作,效率很高)。每當元數據有更新或者添加元數據時,修改內存中的元數據並追加到Edits中。這樣,一旦NameNode節點斷電,可以通過FsImage和Edits的合併,合成元數據。
但是,如果長時間添加數據到Edits中,會導致該文件數據過大,效率降低,而且一旦斷電,恢復元數據需要的時間過長。因此,需要定期進行FsImage和Edits的合併,如果這個操作由NameNode節點完成,又會效率過低。因此,引入一個新的節點SecondaryNamenode,專門用於FsImage和Edits的合併。
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。
NN和2NN工作機制詳解:
Fsimage:NameNode內存中元數據序列化後形成的文件。
Edits:記錄客戶端更新元數據信息的每一步操作(可通過Edits運算出元數據)。
NameNode啟動時,先滾動Edits並生成一個空的edits.inprogress,然後加載Edits和Fsimage到內存中,此時NameNode內存就持有最新的元數據信息。Client開始對NameNode發送元數據的增刪改的請求,這些請求的操作首先會被記錄到edits.inprogress中(查詢元數據的操作不會被記錄在Edits中,因為查詢操作不會更改元數據信息),如果此時NameNode掛掉,重啟後會從Edits中讀取元數據的信息。然後,NameNode會在內存中執行元數據的增刪改的操作。
由於Edits中記錄的操作會越來越多,Edits文件會越來越大,導致NameNode在啟動加載Edits時會很慢,所以需要對Edits和Fsimage進行合併(所謂合併,就是將Edits和Fsimage加載到內存中,照著Edits中的操作一步步執行,最終形成新的Fsimage)。SecondaryNameNode的作用就是幫助NameNode進行Edits和Fsimage的合併工作。
SecondaryNameNode首先會詢問NameNode是否需要CheckPoint(觸發CheckPoint需要滿足兩個條件中的任意一個,定時時間到和Edits中數據寫滿了)。直接帶回NameNode是否檢查結果。SecondaryNameNode執行CheckPoint操作,首先會讓NameNode滾動Edits並生成一個空的edits.inprogress,滾動Edits的目的是給Edits打個標記,以後所有新的操作都寫入edits.inprogress,其他未合併的Edits和Fsimage會拷貝到SecondaryNameNode的本地,然後將拷貝的Edits和Fsimage加載到內存中進行合併,生成fsimage.chkpoint,然後將fsimage.chkpoint拷貝給NameNode,重命名為Fsimage後替換掉原來的Fsimage。NameNode在啟動時就只需要加載之前未合併的Edits和Fsimage即可,因為合併過的Edits中的元數據信息已經被記錄在Fsimage中。
Fsimage和Edits解析
NameNode被格式化之後,將在/opt/module/hadoop-2.7.2/data/tmp/dfs/name/current目錄中產生如下文件:
fsimage_0000000000000000000
fsimage_0000000000000000000.md5
seen_txid
VERSION
(1)Fsimage文件:HDFS文件系統元數據的一個永久性檢查點,其中包含HDFS文件系統的所有目錄和文件inode的序列化信息。
(2)Edits文件:存放HDFS文件系統的所有更新操作,文件系統客戶端執行的所有寫操作首先會記錄到Edits文件中。
(3)seen_txid文件保存的是一個數字,就是最後一個edits_數字
(4)每次NameNode啟動的時候都會 將Fsimage文件讀入內存,加載Edits裡面的更新操作,保證內存中的元數據信息是最新的,同步的,可以看成NameNode啟動的時候就將Fsimage和Edits文件進行了合併。
oiv查看Fsimage文件
(1)查看oiv和oev命令
<code>hdfs oiv apply the offline fsimage viewer to an fsimage oev apply the offline edits viewer to an edits file/<code>
(2)基本語法
hdfs oiv -p 文件類型 -i鏡像文件 -o 轉換後文件輸出路徑
(3)案例實操
<code>pwd /opt/module/hadoop-2.7.2/data/tmp/dfs/name/current/<code>
<code>hdfs oiv -p XML -i fsimage_0000000000000000025 -o /opt/module/hadoop-2.7.2/fsimage.xml/<code>
<code>cat /opt/module/hadoop-2.7.2/fsimage.xml/<code>
將顯示的xml文件內容拷貝到Eclipse中創建的xml文件中,並格式化。部分顯示結果如下。
<code> 16386 DIRECTORY user 1512722284477 atguigu:supergroup:rwxr-xr-x -1 -1 16387 DIRECTORY atguigu 1512790549080 atguigu:supergroup:rwxr-xr-x -1 -1 16389 FILE wc.input 3 1512722322219 1512722321610 134217728 atguigu:supergroup:rw-r--r-- 1073741825 1001 59 /<code>
可以看出,Fsimage中沒有記錄塊所對應DataNode。因為在集群啟動後,要求DataNode上報數據塊信息,並間隔一段時間後再次上報。
oev查看Edits文件
(1)基本語法
hdfs oev -p 文件類型 -i編輯日誌 -o 轉換後文件輸出路徑
(2)案例實操
<code>hdfs oev -p XML -i edits_0000000000000000012-0000000000000000013 -o /opt/module/hadoop-2.7.2/edits.xml/<code>
<code>cat /opt/module/hadoop-2.7.2/edits.xml/<code>
將顯示的xml文件內容拷貝到Eclipse中創建的xml文件中,並格式化。顯示結果如下。
<code> -63 OP_START_LOG_SEGMENT 129 OP_ADD 130 0 16407 /hello7.txt 2 1512943607866 1512943607866 134217728 DFSClient_NONMAPREDUCE_-1544295051_1 192.168.1.5 true atguigu supergroup 420 908eafd4-9aec-4288-96f1-e8011d181561 0 OP_ALLOCATE_BLOCK_ID 131 1073741839 OP_SET_GENSTAMP_V2 132 1016 OP_ADD_BLOCK 133 /hello7.txt 1073741839 0 1016 -2 OP_CLOSE 134 0 0 /hello7.txt 2 1512943608761 1512943607866 134217728 false 1073741839 25 1016 atguigu supergroup 420 /<code>
NameNode如何確定下次開機啟動的時候合併哪些Edits?
CheckPoint時間設置
(1)通常情況下,SecondaryNameNode每隔一小時執行一次。
[hdfs-default.xml]
<code> dfs.namenode.checkpoint.period 3600 /<code>
(2)一分鐘檢查一次操作次數,當操作次數達到1百萬時,SecondaryNameNode執行一次。
<code> dfs.namenode.checkpoint.txns 1000000 操作動作次數 dfs.namenode.checkpoint.check.period 60 1分鐘檢查一次操作次數 /<code>
NameNode故障處理
NameNode故障後,可以採用如下兩種方法恢復數據。
方法一:將SecondaryNameNode中數據拷貝到NameNode存儲數據的目錄;
1. kill -9 NameNode進程
2. 刪除NameNode存儲的數據(/opt/module/hadoop-2.7.2/data/tmp/dfs/name)
<code>rm -rf /opt/module/hadoop-2.7.2/data/tmp/dfs/name/*/<code>
3. 拷貝SecondaryNameNode中數據到原NameNode存儲數據目錄
<code>scp -r hadoop@hadoop104:/opt/module/hadoop-2.7.2/data/tmp/dfs/namesecondary/* ./name//<code>
4. 重新啟動NameNode
<code>sbin/hadoop-daemon.sh start namenode/<code>
方法二:使用-importCheckpoint選項啟動NameNode守護進程,從而將SecondaryNameNode中數據拷貝到NameNode目錄中。
1. 修改hdfs-site.xml中的
<code> dfs.namenode.checkpoint.period 120 dfs.namenode.name.dir /opt/module/hadoop-2.7.2/data/tmp/dfs/name /<code>
2. kill -9 NameNode進程
3. 刪除NameNode存儲的數據(/opt/module/hadoop-2.7.2/data/tmp/dfs/name)
<code>rm -rf /opt/module/hadoop-2.7.2/data/tmp/dfs/name/*/<code>
4. 如果SecondaryNameNode不和NameNode在一個主機節點上,需要將SecondaryNameNode存儲數據的目錄拷貝到NameNode存儲數據的平級目錄,並刪除in_use.lock文件
<code>scp -r atguigu@hadoop104:/opt/module/hadoop-2.7.2/data/tmp/dfs/namesecondary ./ rm -rf in_use.lock pwd /opt/module/hadoop-2.7.2/data/tmp/dfs ls data name namesecondary/<code>
5. 導入檢查點數據(等待一會ctrl+c結束掉)
<code>bin/hdfs namenode -importCheckpoint/<code>
6. 啟動NameNode
<code>sbin/hadoop-daemon.sh start namenode/<code>
集群安全模式
1.NameNode啟動
NameNode啟動時,首先將鏡像文件(Fsiamge)載入內存,並執行編輯日誌(Edits)中的各項操作。一旦在內存中成功建立文件系統元數據的映像,則創建一個新的Fsimage文件和一個空的編輯日誌。此時,NameNode開始監聽DataNode請求。這個過程期間,NameNode一直運行在安全模式,即NameNode的文件系統對與客戶端來說只是只讀的。
2.DataNode啟動
系統中的數據塊的位置並不是由NameNode維護的,而是以塊列表的形式存儲在DataNode中。在系統的正常操作期間,NameNode會在內存中保留所有垮位置的映射信息。在安全模式下,各個DataNode會向NameNode發送最新的塊列表信息。NameNode瞭解足夠多的塊位置信息之後,即可高效運行文件系統。
3.安全模式退出判斷
如果滿足“最小副本條件”,NameNode會在30秒鐘之後就退出安全模式。所謂的最小副本條件指的是在整個文件系統中99.9%的塊滿足最小副本級別(默認值:dfs:relication=1)。在啟動一個剛剛格式化的HDFS集群中,因為系統中還沒有任何塊,所以NameNode不會進入安全模式。
基本語法
集群處於安全模式,不能執行重要操作(寫操作)。集群啟動完成後,自動退出安全模式。
(1)bin/hdfs dfsadmin -safemode get (功能描述:查看安全模式狀態)
(2)bin/hdfs dfsadmin -safemode enter (功能描述:進入安全模式狀態)
(3)bin/hdfs dfsadmin -safemode leave (功能描述:離開安全模式狀態)
(4)bin/hdfs dfsadmin -safemode wait (功能描述:等待安全模式狀態)
模擬等待安全模式
(1)查看當前模式
<code>hdfs dfsadmin -safemode get Safe mode is OFF/<code>
(2)先進入安全模式
<code>bin/hdfs dfsadmin -safemode enter/<code>
(3)創建並執行下面的腳本
在/opt/module/hadoop-2.7.2路徑上,編輯一個腳本safemode.sh
<code>touch safemode.sh vim safemode.sh #!/bin/bash hdfs dfsadmin -safemode wait hdfs dfs -put /opt/module/hadoop-2.7.2/README.txt //<code>
<code>chmod 777 safemode.sh ./safemode.sh /<code>
(4)再打開一個窗口,執行
<code>bin/hdfs dfsadmin -safemode leave/<code>
(5)觀察
(a)再觀察上一個窗口
Safe mode is OFF
(b)HDFS集群上已經有上傳的數據了。
DataNode
DataNode工作機制
1)一個數據塊在DataNode上以文件形式存儲在磁盤上,包括兩個文件,一個是數據本身,一個是元數據包括數據塊的長度,塊數據的校驗和,以及時間戳。
2)DataNode啟動後向NameNode註冊,通過後,週期性(1小時)的向NameNode上報所有的塊信息。
3)心跳是每3秒一次,心跳返回結果帶有NameNode給該DataNode的命令如複製塊數據到另一臺機器,或刪除某個數據塊。如果超過10分鐘沒有收到某個DataNode的心跳,則認為該節點不可用。
4)集群運行中可以安全加入和退出一些機器。
數據完整性
思考:如果電腦磁盤裡面存儲的數據是控制高鐵信號燈的紅燈信號(1)和綠燈信號(0),但是存儲該數據的磁盤壞了,一直顯示是綠燈,是否很危險?同理DataNode節點上的數據損壞了,卻沒有發現,是否也很危險,那麼如何解決呢?
如下是DataNode節點保證數據完整性的方法。
1)當DataNode讀取Block的時候,它會計算CheckSum。
2)如果計算後的CheckSum,與Block創建時值不一樣,說明Block已經損壞。
3)Client讀取其他DataNode上的Block。
4)DataNode在其文件創建後周期驗證CheckSum,如圖3-16所示。
掉線時限參數設置
需要注意的是hdfs-site.xml 配置文件中的heartbeat.recheck.interval的單位為毫秒,dfs.heartbeat.interval的單位為秒。
<code> dfs.namenode.heartbeat.recheck-interval 300000 dfs.heartbeat.interval 3 /<code>
服役新數據節點
需求
隨著公司業務的增長,數據量越來越大,原有的數據節點的容量已經不能滿足存儲數據的需求,需要在原有集群基礎上動態添加新的數據節點。
1. 環境準備
(1)在hadoop104主機上再克隆一臺hadoop105主機
(2)修改IP地址和主機名稱
(3)刪除原來HDFS文件系統留存的文件(/opt/module/hadoop-2.7.2/data和log)
(4)source一下配置文件,source /etc/profile
2.服役新節點具體步驟
(1)直接啟動DataNode,即可關聯到集群
<code>sbin/hadoop-daemon.sh start datanode sbin/yarn-daemon.sh start nodemanager/<code>
(2)在hadoop105上上傳文件
<code>hadoop fs -put /opt/module/hadoop-2.7.2/LICENSE.txt //<code>
(3)如果數據不均衡,可以用命令實現集群的再平衡
<code>./start-balancer.sh/<code>
退役舊數據節點
添加白名單
添加到白名單的主機節點,都允許訪問NameNode,不在白名單的主機節點,都會被退出。
配置白名單的具體步驟如下:
(1)在NameNode的/opt/module/hadoop-2.7.2/etc/hadoop目錄下創建dfs.hosts文件
<code>pwd /opt/module/hadoop-2.7.2/etc/hadoop touch dfs.hosts vi dfs.hosts/<code>
添加如下主機名稱(不添加hadoop105)
<code>hadoop102 hadoop103 hadoop104/<code>
(2)在NameNode的hdfs-site.xml配置文件中增加dfs.hosts屬性
<code> dfs.hosts /opt/module/hadoop-2.7.2/etc/hadoop/dfs.hosts /<code>
(3)配置文件分發
<code>xsync hdfs-site.xml/<code>
(4)刷新NameNode
<code>hdfs dfsadmin -refreshNodes/<code>
(5)更新ResourceManager節點
<code>yarn rmadmin -refreshNodes 17/06/24 14:17:11 INFO client.RMProxy: Connecting to ResourceManager at hadoop103/192.168.1.103:8033/<code>
(6)在web瀏覽器上查看
4. 如果數據不均衡,可以用命令實現集群的再平衡
<code>./start-balancer.sh/<code>
黑名單退役
在黑名單上面的主機都會被強制退出。
1.在NameNode的/opt/module/hadoop-2.7.2/etc/hadoop目錄下創建dfs.hosts.exclude文件
<code> pwd /opt/module/hadoop-2.7.2/etc/hadoop touch dfs.hosts.exclude vi dfs.hosts.exclude/<code>
添加如下主機名稱(要退役的節點)
<code>hadoop105/<code>
2.在NameNode的hdfs-site.xml配置文件中增加dfs.hosts.exclude屬性
<code> dfs.hosts.exclude /opt/module/hadoop-2.7.2/etc/hadoop/dfs.hosts.exclude 3.刷新NameNode、刷新ResourceManager/<code>
3.刷新NameNode、刷新ResourceManager
<code>hdfs dfsadmin -refreshNodes Refresh nodes successful yarn rmadmin -refreshNodes/<code>
4. 檢查Web瀏覽器,退役節點的狀態為decommission in progress(退役中),說明數據節點正在複製塊到其他節點
等待退役節點狀態為decommissioned(所有塊已經複製完成),停止該節點及節點資源管理器。注意:如果副本數是3,服役的節點小於等於3,是不能退役成功的,需要修改副本數後才能退役。
<code>sbin/hadoop-daemon.sh stop datanode/<code>
<code>sbin/yarn-daemon.sh stop nodemanager/<code>
6. 如果數據不均衡,可以用命令實現集群的再平衡
<code>sbin/start-balancer.sh /<code>
Datanode多目錄配置
1. DataNode也可以配置成多個目錄,每個目錄存儲的數據不一樣。即:數據不是副本
2.具體配置如下
hdfs-site.xml
<code> dfs.datanode.data.dir file:///${hadoop.tmp.dir}/dfs/data1,file:///${hadoop.tmp.dir}/dfs/data2 /<code>
Hadoop小文件
每個文件均按塊存儲,每個塊的元數據存儲在NameNode的內存中,因此HDFS存儲小文件會非常低效。因為大量的小文件會耗盡NameNode中的大部分內存。但注意,存儲小文件所需要的磁盤容量和數據塊的大小無關。例如,一個1MB的文件設置為128M的塊存儲,實際使用的是1MB的磁盤空間。
HDFS存檔文件或HAR文件,是一個高效的文件存檔工具,它將文件存入HDFS塊,在減少NameNode內存使用的同時,允許對文件進行透明的訪問。具體來說,HDFS存檔文件對內還是一個一個獨立文件,對NameNode而言卻是一個整體,減少了NameNode的內存。
(1)需要啟動Yarn進程
<code>start-yarn.sh/<code>
(2)歸檔文件
把/user/hadoop/input目錄裡面的所有文件歸檔成一個叫input.har的歸檔文件,並把歸檔後文件存儲到/user/hadoop/output路徑下。
<code>bin/hadoop archive -archiveName input.har –p /user/hadoop/input /user/hadoop/output/<code>
(3)查看歸檔
<code>hadoop fs -lsr /user/hadoop/output/input.har hadoop fs -lsr har:///user/hadoop/output/input.har/<code>
(4)解歸檔文件
<code>hadoop fs -cp har:/// user/hadoop/output/input.har/* /user/hadoop/<code>
HDFS HA高可用
HA概述
1)所謂HA(High Available),即高可用(7*24小時不中斷服務)。
2)實現高可用最關鍵的策略是消除單點故障。HA嚴格來說應該分成各個組件的HA機制:
HDFS的HA和YARN的HA。
3)Hadoop2.0之前,在HDFS集群中NameNode存在單點故障(SPOF)。
4)NameNode主要在以下兩個方面影響HDFS集群
NameNode機器發生意外,如宕機,集群將無法使用,直到管理員重啟
NameNode機器需要升級,包括軟件、硬件升級,此時集群也將無法使用
HDFS HA功能通過配置Active/Standby兩個NameNodes實現在集群中對NameNode的熱備來解決上述問題。如果出現故障,如機器崩潰或機器需要升級維護,這時可通過此種方式將NameNode很快的切換到另外一臺機器。
HDFS-HA工作機制
通過雙NameNode消除單點故障
HDFS-HA工作要點
1. 元數據管理方式需要改變
內存中各自保存一份元數據;
Edits日誌只有Active狀態的NameNode節點可以做寫操作;
兩個NameNode都可以讀取Edits;
共享的Edits放在一個共享存儲中管理(qjournal和NFS兩個主流實現);
2. 需要一個狀態管理功能模塊
實現了一個zkfailover,常駐在每一個namenode所在的節點,每一個zkfailover負責監控自己所在NameNode節點,利用zk進行狀態標識,當需要進行狀態切換時,由zkfailover來負責切換,切換時需要防止brain split現象的發生。
3. 必須保證兩個NameNode之間能夠ssh無密碼登錄
4. 隔離(Fence),即同一時刻僅僅有一個NameNode對外提供服務
HDFS-HA自動故障轉移工作機制
使用命令hdfs haadmin -failover手動進行故障轉移,在該模式下,即使現役NameNode已經失效,系統也不會自動從現役NameNode轉移到待機NameNode。如何配置部署HA自動進行故障轉移?自動故障轉移為HDFS部署增加了兩個新組件:ZooKeeper和ZKFailoverController(ZKFC)進程,ZooKeeper是維護少量協調數據,通知客戶端這些數據的改變和監視客戶端故障的高可用服務。HA的自動故障轉移依賴於ZooKeeper的以下功能:
1)故障檢測:集群中的每個NameNode在ZooKeeper中維護了一個持久會話,如果機器崩潰,ZooKeeper中的會話將終止,ZooKeeper通知另一個NameNode需要觸發故障轉移。
2)現役NameNode選擇: ZooKeeper提供了一個簡單的機制用於唯一的選擇一個節點為active狀態。如果目前現役NameNode崩潰,另一個節點可能從ZooKeeper獲得特殊的排外鎖以表明它應該成為現役NameNode。
ZKFC是自動故障轉移中的另一個新組件,是ZooKeeper的客戶端,也監視和管理NameNode的狀態。每個運行NameNode的主機也運行了一個ZKFC進程,ZKFC負責:
1)健康監測:ZKFC使用一個健康檢查命令定期地ping與之在相同主機的NameNode,只要該NameNode及時地恢復康狀態,ZKFC認為該節點是健康的。如果該節點崩潰,凍結或進入不健康狀態,健康監測器標識該節點為非健康的。
2)ZooKeeper會話管理:當本地NameNode是健康的,ZKFC保持一個在ZooKeeper中打開的會話。如果本地NameNode處於active狀態,ZKFC也保持一個特殊的znode鎖,該鎖使用了ZooKeeper對短暫節點的支持,如果會話終止,鎖節點將自動刪除。
3)基於ZooKeeper的選擇:如果本地NameNode是健康的,且ZKFC發現沒有其它的節點當前持有znode鎖,它將為自己獲取該鎖。如果成功,則它已經贏得了選擇,並負責運行故障轉移進程以使它的本地NameNode為Active。故障轉移進程與前面描述的手動故障轉移相似,首先如果必要保護之前的現役NameNode,然後本地NameNode轉換為Active狀態。
HDFS-HA集群配置
環境準備
1. 修改IP
2. 修改主機名及主機名和IP地址的映射
3. 關閉防火牆
4. ssh免密登錄
5. 安裝JDK,配置環境變量等
配置Zookeeper集群
1. 集群規劃
在hadoop102、hadoop103和hadoop104三個節點上部署Zookeeper。
2. 解壓安裝
(1)解壓Zookeeper安裝包到/opt/module/目錄下
<code>tar -zxvf zookeeper-3.4.10.tar.gz -C /opt/module//<code>
(2)在/opt/module/zookeeper-3.4.10/這個目錄下創建zkData
<code>mkdir -p zkData/<code>
(3)重命名/opt/module/zookeeper-3.4.10/conf這個目錄下的zoo_sample.cfg為zoo.cfg
<code>mv zoo_sample.cfg zoo.cfg/<code>
3. 配置zoo.cfg文件
(1)具體配置
<code>dataDir=/opt/module/zookeeper-3.4.10/zkData/<code>
增加如下配置
<code>#######################cluster########################## server.2=hadoop102:2888:3888 server.3=hadoop103:2888:3888 server.4=hadoop104:2888:3888/<code>
(2)配置參數解讀
Server.A=B:C:D。
A是一個數字,表示這個是第幾號服務器;
B是這個服務器的IP地址;
C是這個服務器與集群中的Leader服務器交換信息的端口;
D是萬一集群中的Leader服務器掛了,需要一個端口來重新進行選舉,選出一個新的Leader,而這個端口就是用來執行選舉時服務器相互通信的端口。
集群模式下配置一個文件myid,這個文件在dataDir目錄下,這個文件裡面有一個數據就是A的值,Zookeeper啟動時讀取此文件,拿到裡面的數據與zoo.cfg裡面的配置信息比較從而判斷到底是哪個server。
4. 集群操作
(1)在/opt/module/zookeeper-3.4.10/zkData目錄下創建一個myid的文件
<code>touch myid/<code>
添加myid文件,注意一定要在linux裡面創建,在notepad++裡面很可能亂碼
(2)編輯myid文件
<code>vi myid/<code>
在文件中添加與server對應的編號:如2
(3)拷貝配置好的zookeeper到其他機器上
<code>scp -r zookeeper-3.4.10/ [email protected]:/opt/app/ scp -r zookeeper-3.4.10/ [email protected]:/opt/app//<code>
並分別修改myid文件中內容為3、4
(4)分別啟動zookeeper
<code>[root@hadoop102 zookeeper-3.4.10]# bin/zkServer.sh start [root@hadoop103 zookeeper-3.4.10]# bin/zkServer.sh start [root@hadoop104 zookeeper-3.4.10]# bin/zkServer.sh start/<code>
(5)查看狀態
<code>bin/zkServer.sh status/<code>
配置HDFS-HA集群
1. 官方地址:http://hadoop.apache.org/
2. 在opt目錄下創建一個ha文件夾
<code>mkdir ha/<code>
3. 將/opt/app/下的 hadoop-2.7.2拷貝到/opt/ha目錄下
<code>cp -r hadoop-2.7.2/ /opt/ha//<code>
4. 配置hadoop-env.sh
<code>export JAVA_HOME=/opt/module/jdk1.8.0_144/<code>
5. 配置core-site.xml
<code> fs.defaultFS hdfs://mycluster hadoop.tmp.dir /opt/ha/hadoop-2.7.2/data/tmp /<code>
6. 配置hdfs-site.xml
<code> dfs.nameservices mycluster dfs.ha.namenodes.mycluster nn1,nn2 dfs.namenode.rpc-address.mycluster.nn1 hadoop102:9000 dfs.namenode.rpc-address.mycluster.nn2 hadoop103:9000 dfs.namenode.http-address.mycluster.nn1 hadoop102:50070 dfs.namenode.http-address.mycluster.nn2 hadoop103:50070 dfs.namenode.shared.edits.dir qjournal://hadoop102:8485;hadoop103:8485;hadoop104:8485/mycluster dfs.ha.fencing.methods sshfence dfs.ha.fencing.ssh.private-key-files /home/atguigu/.ssh/id_rsa dfs.journalnode.edits.dir /opt/ha/hadoop-2.7.2/data/jn dfs.permissions.enable false dfs.client.failover.proxy.provider.mycluster org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider /<code>
7. 拷貝配置好的hadoop環境到其他節點
啟動HDFS-HA集群
1. 在各個JournalNode節點上,輸入以下命令啟動journalnode服務
<code> sbin/hadoop-daemon.sh start journalnode/<code>
2. 在[nn1]上,對其進行格式化,並啟動
<code> bin/hdfs namenode -format sbin/hadoop-daemon.sh start namenode/<code>
3. 在[nn2]上,同步nn1的元數據信息
<code>bin/hdfs namenode -bootstrapStandby/<code>
4. 啟動[nn2]
<code>sbin/hadoop-daemon.sh start namenode/<code>
5. 查看web頁面顯示
6. 在[nn1]上,啟動所有datanode
<code>sbin/hadoop-daemons.sh start datanode/<code>
7. 將[nn1]切換為Active
<code>bin/hdfs haadmin -transitionToActive nn1/<code>
8. 查看是否Active
<code>bin/hdfs haadmin -getServiceState nn1/<code>
配置HDFS-HA自動故障轉移
1. 具體配置
(1)在hdfs-site.xml中增加
<code> dfs.ha.automatic-failover.enabled true /<code>
(2)在core-site.xml文件中增加
<code> ha.zookeeper.quorum hadoop102:2181,hadoop103:2181,hadoop104:2181 /<code>
2. 啟動
(1)關閉所有HDFS服務:
<code>sbin/stop-dfs.sh/<code>
(2)啟動Zookeeper集群:
<code>bin/zkServer.sh start/<code>
(3)初始化HA在Zookeeper中狀態:
<code>bin/hdfs zkfc -formatZK/<code>
(4)啟動HDFS服務:
<code>sbin/start-dfs.sh/<code>
3. 驗證
(1)將Active NameNode進程kill
<code>kill -9 namenode的進程id/<code>
(2)將Active NameNode機器斷開網絡
<code>service network stop/<code>
YARN-HA配置
YARN-HA工作機制
1. 官方文檔:
http://hadoop.apache.org/docs/r2.7.2/hadoop-yarn/hadoop-yarn-site/ResourceManagerHA.html
2. YARN-HA工作機制
配置YARN-HA集群
1. 環境準備
(1)修改IP
(2)修改主機名及主機名和IP地址的映射
(3)關閉防火牆
(4)ssh免密登錄
(5)安裝JDK,配置環境變量等
(6)配置Zookeeper集群
2. 規劃集群
3. 具體配置
(1)yarn-site.xml
<code> yarn.nodemanager.aux-services mapreduce_shuffle yarn.resourcemanager.ha.enabled true yarn.resourcemanager.cluster-id cluster-yarn1 yarn.resourcemanager.ha.rm-ids rm1,rm2 yarn.resourcemanager.hostname.rm1 hadoop102 yarn.resourcemanager.hostname.rm2 hadoop103 yarn.resourcemanager.zk-address hadoop102:2181,hadoop103:2181,hadoop104:2181 yarn.resourcemanager.recovery.enabled true yarn.resourcemanager.store.class org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore /<code>
(2)同步更新其他節點的配置信息
4. 啟動hdfs
(1)在各個JournalNode節點上,輸入以下命令啟動journalnode服務:
<code>sbin/hadoop-daemon.sh start journalnode/<code>
(2)在[nn1]上,對其進行格式化,並啟動:
<code>bin/hdfs namenode -format/<code>
<code>sbin/hadoop-daemon.sh start namenode/<code>
(3)在[nn2]上,同步nn1的元數據信息:
<code>bin/hdfs namenode -bootstrapStandby/<code>
(4)啟動[nn2]:
<code>sbin/hadoop-daemon.sh start namenode/<code>
(5)啟動所有DataNode
<code>sbin/hadoop-daemons.sh start datanode/<code>
(6)將[nn1]切換為Active
<code>bin/hdfs haadmin -transitionToActive nn1/<code>
5. 啟動YARN
(1)在hadoop102中執行:
<code>sbin/start-yarn.sh/<code>
(2)在hadoop103中執行:
<code>sbin/yarn-daemon.sh start resourcemanager/<code>
(3)查看服務狀態
<code>bin/yarn rmadmin -getServiceState rm1/<code>