Hadoop的API


大數據技術之Hadoop

HDFS文件系統)

HDFS概念

1.1 概念

HDFS,它是一個文件系統,全稱:Hadoop Distributed File System,用於存儲文件通過目錄樹來定位文件;其次,它是分布式的,由很多服務器聯合起來實現其功能,集群中的服務器有各自的角色。

1.2 組成

1HDFS集群包括,NameNodeDataNode以及Secondary Namenode

2NameNode負責管理整個文件系統的元數據,以及每一個路徑(文件)所對應的數據塊信息。

3DataNode 負責管理用戶的文件數據塊,每一個數據塊都可以在多個datanode上存儲多個副本。

4Secondary NameNode用來監控HDFS狀態的輔助后台程序,每隔一段時間獲取HDFS元數據的快照。

1.3 HDFS 文件塊大小

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

HDFS的塊比磁盤的塊大,其目的是為了最小化尋址開銷。如果設置得足夠大,從磁盤傳輸數據的時間會明顯大於定位這個開始位置所需的時間。因而傳輸一個由多個塊組成的文件的時間取決於磁盤傳輸速率

如果尋址時間約為10ms,而傳輸速率為100MB/s,為了使尋址時間僅占傳輸時間的1%,我們要將塊大小設置約為100MB。默認塊大小128MB

的大小:10ms*100*100M/s = 100M

 

HFDS命令行操作

1)基本語法

bin/hadoop fs 具體命令

2)參數大全

bin/hadoop fs

[-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常用命令實操

1-help:輸出這個命令參數

bin/hdfs dfs -help rm

2-ls: 顯示目錄信息

hadoop fs -ls /

3-mkdir:在hdfs上創建目錄

hadoop fs  -mkdir  -p  /hdfs路徑

(4-moveFromLocal從本地剪切粘貼到hdfs

hadoop  fs  - moveFromLocal  本地路徑  /hdfs路徑

5--appendToFile  追加一個文件到已經存在的文件末尾

hadoop  fs  -appendToFile  本地路徑  /hdfs路徑

6-cat :顯示文件內容

hadoop fs -cat /hdfs路徑

7-tail -f:監控文件

hadoop  fs  -tail -f /hdfs路徑

8-chmod-chownlinux文件系統中的用法一樣,修改文件所屬權限

hadoop  fs  -chmod  777  /hdfs路徑

hadoop  fs  -chown  someuser:somegrp   /hdfs路徑

9-cp :從hdfs的一個路徑拷貝到hdfs的另一個路徑

hadoop  fs  -cp  /hdfs路徑1  / hdfs路徑2

10-mv:在hdfs目錄中移動/重命名 文件

hadoop  fs  -mv  /hdfs路徑  / hdfs路徑

11-get:等同於copyToLocal,就是從hdfs下載文件到本地

hadoop fs -get / hdfs路徑 ./本地路徑

12-getmerge  :合並下載多個文到linux本地,比如hdfs的目錄 /aaa/下有多個文件:log.1, log.2,log.3,...(注:是合成到Linux本地)

hadoop fs -getmerge /aaa/log.* ./log.sum

合成到不同的目錄:hadoop fs -getmerge /hdfs1路徑 /hdfs2路徑 /

13-put:等同於copyFromLocal

hadoop  fs  -put  /本地路徑  /hdfs路徑

14-rm:刪除文件或文件夾

hadoop fs -rm -r /hdfs路徑

(15-df :統計文件系統的可用空間信息

hadoop  fs  -df  -h  / hdfs路徑

(16-du統計文件夾的大小信息

[itstar@bigdata111 hadoop-2.7.2]$ hadoop fs -du -s -h / hdfs路徑

188.5 M  /user/itstar/wcinput

 

[itstar@bigdata111 hadoop-2.7.2]$ hadoop fs -du  -h / hdfs路徑

188.5 M  / hdfs路徑

97       / hdfs路徑

17-count:統計一個指定目錄下的文件節點數量

hadoop fs -count /aaa/

[itstar@bigdata111 hadoop-2.7.2]$ hadoop fs -count / hdfs路徑

       1             2          197657784 / hdfs路徑

嵌套文件層級;  包含文件的總數

(18-setrep:設置hdfs中文件的副本數量:3是副本數,可改

hadoop fs -setrep 3 / hdfs路徑

 

這里設置的副本數只是記錄在namenode的元數據中,是否真的會有這么多副本,還得看datanode的數量。因為目前只有3設備,最多也就3副本,只有節點數的增加10台時副本數才能達到10

HDFS客戶端操作

3.1 IDEA環境准備

{$MAVEN_HOME/conf/settings}

  <!--本地倉庫所在位置-->

<localRepository>F:\m2\repository</localRepository>

 

<!--使用阿里雲鏡像去下載Jar包,速度更快-->

  <mirrors>

    <mirror>

      <id>alimaven</id>

      <name>aliyun maven</name>

      <url>http://maven.aliyun.com/nexus/content/groups/public/</url>

      <mirrorOf>central</mirrorOf>        

    </mirror>

  </mirrors>

 

<!--本地配置JDK8版本-->

<profiles>

<profile>  

  <id>jdk-1.8</id>  

   <activation>  

     <activeByDefault>true</activeByDefault>  

     <jdk>1.8</jdk>  

   </activation>  

<properties>  

<maven.compiler.source>1.8</maven.compiler.source>  

<maven.compiler.target>1.8</maven.compiler.target>  

<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>

</properties>

</profile>

</profiles>

 

3.1.0 Maven配置

3.1.1 Maven准備

<dependency>

            <groupId>org.apache.hadoop</groupId>

            <artifactId>hadoop-common</artifactId>

            <version>2.8.4</version>

        </dependency>

 

        <dependency>

            <groupId>org.apache.hadoop</groupId>

            <artifactId>hadoop-common</artifactId>

            <version>2.8.4</version>

        </dependency>

        <dependency>

            <groupId>org.apache.hadoop</groupId>

            <artifactId>hadoop-hdfs</artifactId>

            <version>2.8.4</version>

        </dependency>

        <dependency>

            <groupId>org.apache.hadoop</groupId>

            <artifactId>hadoop-client</artifactId>

            <version>2.8.4</version>

        </dependency>

 

        <dependency>

            <groupId>org.projectlombok</groupId>

            <artifactId>lombok</artifactId>

            <version>1.16.10</version>

        </dependency>

 

        <dependency>

            <groupId>log4j</groupId>

            <artifactId>log4j</artifactId>

            <version>1.2.17</version>

        </dependency>

        <dependency>

            <groupId>org.slf4j</groupId>

            <artifactId>slf4j-api</artifactId>

            <version>1.7.7</version>

        </dependency>

 

        <!-- https://mvnrepository.com/artifact/junit/junit -->

        <dependency>

            <groupId>junit</groupId>

            <artifactId>junit</artifactId>

            <version>4.12</version>

            <scope>test</scope>

        </dependency>

 

3.1.2 IDEA准備

1配置HADOOP_HOME環境變量

2)采用hadoop編譯后的bin 、lib兩個文件夾(如果不生效,重新啟動IDEA

3)創建第一個java工程

public class HdfsClientDemo1 {

public static void main(String[] args) throws Exception {

// 1 獲取文件系統

Configuration configuration = new Configuration();

// 配置在集群上運行

configuration.set("fs.defaultFS", "hdfs://bigdata111:9000");

FileSystem fileSystem = FileSystem.get(configuration);

 

// 直接配置訪問集群的路徑和訪問集群的用戶名稱

// FileSystem fileSystem = FileSystem.get(new URI("hdfs://bigdata111:9000"),configuration, "itstar");

 

// 2 把本地文件上傳到文件系統中

fileSystem.copyFromLocalFile(new Path("f:/hello.txt"), new Path("/hello1.copy.txt"));

 

// 3 關閉資源

fileSystem.close();

System.out.println("over");

}

}

4)執行程序

注:eclipse運行可能需要配置用戶名稱

客戶端去操作hdfs時,是有一個用戶身份的。默認情況下,hdfs客戶端api會從jvm中獲取一個參數來作為自己的用戶身份:-DHADOOP_USER_NAME=itstar,itstar為用戶名稱。

3.2 通過API操作HDFS

3.2.1 HDFS獲取文件系統

1)詳細代碼

@Test

public void initHDFS() throws Exception{

// 1 創建配置信息對象

Configuration configuration = new Configuration();

 

// 2 獲取文件系統

FileSystem fs = FileSystem.get(configuration);

 

// 3 打印文件系統

System.out.println(fs.toString());

}

3.2.2 HDFS文件上傳

@Test

public void putFileToHDFS() throws Exception{

// 1 創建配置信息對象

// new Configuration();的時候,它就會去加載jar包中的hdfs-default.xml

// 然后再加載classpath下的hdfs-site.xml

Configuration configuration = new Configuration();

 

// 2 設置參數

// 參數優先級: 1、客戶端代碼中設置的值  2classpath下的用戶自定義配置文件 3、然后是服務器的默認配置

configuration.set("dfs.replication", "2");

 

FileSystem fs = FileSystem.get(new URI("hdfs://bigdata111:9000"),configuration, "itstar");

 

// 3 創建要上傳文件所在的本地路徑

Path src = new Path("e:/hello.txt");

 

// 4 創建要上傳到hdfs的目標路徑

Path dst = new Path("hdfs://bigdata111:9000/user/itstar/hello.txt");

 

// 5 拷貝文件

fs.copyFromLocalFile(src, dst);

fs.close();

}

2)測試參數優先級

參數優先級: 1、客戶端代碼中設置的值  2、然后是服務器的默認配置

3.2.3 HDFS文件下載

@Test

public void getFileFromHDFS() throws Exception{

 

// 1 創建配置信息對象

Configuration configuration = new Configuration();

 

FileSystem fs = FileSystem.get(new URI("hdfs://bigdata111:9000"),configuration, "itstar");

 

// fs.copyToLocalFile(new Path("hdfs://bigdata111:9000/user/itstar/hello.txt"), new Path("d:/hello.txt"));

// boolean delSrc 指是否將原文件刪除

// Path src 指要下載的文件路徑

// Path dst 指將文件下載到的路徑

// boolean useRawLocalFileSystem 是否開啟文件效驗

    // 2 下載文件

fs.copyToLocalFile(false, new Path("hdfs://bigdata111:9000/user/itstar/hello.txt"), new Path("e:/hellocopy.txt"), true);

fs.close();

}

3.2.4 HDFS目錄創建

@Test

public void mkdirAtHDFS() throws Exception{

// 1 創建配置信息對象

Configuration configuration = new Configuration();

 

FileSystem fs = FileSystem.get(new URI("hdfs://bigdata111:9000"),configuration, "itstar");

 

//2 創建目錄

fs.mkdirs(new Path("hdfs://bigdata111:9000/user/itstar/output"));

fs.close();

}

3.2.5 HDFS文件夾刪除

@Test

public void deleteAtHDFS() throws Exception{

// 1 創建配置信息對象

Configuration configuration = new Configuration();

 

FileSystem fs = FileSystem.get(new URI("hdfs://bigdata111:9000"),configuration, "itstar");

 

//2 刪除文件夾 ,如果是非空文件夾,參數2是否遞歸刪除,true遞歸

fs.delete(new Path("hdfs://bigdata111:9000/user/itstar/output"), true);

fs.close();

}

3.2.6 HDFS文件名更改

@Test

public void renameAtHDFS() throws Exception{

// 1 創建配置信息對象

Configuration configuration = new Configuration();

 

FileSystem fs = FileSystem.get(new URI("hdfs://bigdata111:9000"),configuration, "itstar");

 

//2 重命名文件或文件夾

fs.rename(new Path("hdfs://bigdata111:9000/user/itstar/hello.txt"), new Path("hdfs://bigdata111:9000/user/itstar/hellonihao.txt"));

fs.close();

}

3.2.7 HDFS文件詳情查看

查看文件名稱、權限、長度信息

@Test

public void readListFiles() throws Exception {

// 1 創建配置信息對象

Configuration configuration = new Configuration();

 

FileSystem fs = FileSystem.get(new URI("hdfs://bigdata111:9000"),configuration, "itstar");

 

// 思考:為什么返回迭代器,而不是List之類的容器

RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/"), true);

 

while (listFiles.hasNext()) {

LocatedFileStatus fileStatus = listFiles.next();

 

System.out.println(fileStatus.getPath().getName());

System.out.println(fileStatus.getBlockSize());

System.out.println(fileStatus.getPermission());

System.out.println(fileStatus.getLen());

 

BlockLocation[] blockLocations = fileStatus.getBlockLocations();

 

for (BlockLocation bl : blockLocations) {

 

System.out.println("block-offset:" + bl.getOffset());

 

String[] hosts = bl.getHosts();

 

for (String host : hosts) {

System.out.println(host);

}

}

 

System.out.println("--------------Andy的分割線--------------");

}

}

3.2.8 HDFS文件和文件夾判斷

@Test

public void findAtHDFS() throws Exception, IllegalArgumentException, IOException{

 

// 1 創建配置信息對象

Configuration configuration = new Configuration();

 

FileSystem fs = FileSystem.get(new URI("hdfs://bigdata111:9000"),configuration, "itstar");

 

// 2 獲取查詢路徑下的文件狀態信息

FileStatus[] listStatus = fs.listStatus(new Path("/"));

 

// 3 遍歷所有文件狀態

for (FileStatus status : listStatus) {

if (status.isFile()) {

System.out.println("f--" + status.getPath().getName());

} else {

System.out.println("d--" + status.getPath().getName());

}

}

}

3.3 通過IO流操作HDFS

3.3.1 HDFS文件上傳

@Test

public void putFileToHDFS() throws Exception{

// 1 創建配置信息對象

Configuration configuration = new Configuration();

 

FileSystem fs = FileSystem.get(new URI("hdfs://bigdata111:9000"),configuration, "itstar");

 

// 2 創建輸入流

FileInputStream inStream = new FileInputStream(new File("e:/hello.txt"));

 

// 3 獲取輸出路徑

String putFileName = "hdfs://bigdata111:9000/user/itstar/hello1.txt";

Path writePath = new Path(putFileName);

 

// 4 創建輸出流

FSDataOutputStream outStream = fs.create(writePath);

 

// 5 流對接

try{

IOUtils.copyBytes(inStream, outStream, 4096, false);

}catch(Exception e){

e.printStackTrace();

}finally{

IOUtils.closeStream(inStream);

IOUtils.closeStream(outStream);

}

}

3.3.2 HDFS文件下載

@Test

public void getFileToHDFS() throws Exception{

// 1 創建配置信息對象

Configuration configuration = new Configuration();

 

FileSystem fs = FileSystem.get(new URI("hdfs://bigdata111:9000"),configuration, "itstar");

 

// 2 獲取讀取文件路徑

String filename = "hdfs://bigdata111:9000/user/itstar/hello1.txt";

 

// 3 創建讀取path

Path readPath = new Path(filename);

 

// 4 創建輸入流

FSDataInputStream inStream = fs.open(readPath);

 

// 5 流對接輸出到控制台

try{

IOUtils.copyBytes(inStream, System.out, 4096, false);

}catch(Exception e){

e.printStackTrace();

}finally{

IOUtils.closeStream(inStream);

}

}

3.3.3 定位文件讀取

1下載第一塊

@Test

// 定位下載第一塊內容

public void readFileSeek1() throws Exception {

 

// 1 創建配置信息對象

Configuration configuration = new Configuration();

 

FileSystem fs = FileSystem.get(new URI("hdfs://bigdata111:9000"), configuration, "itstar");

 

// 2 獲取輸入流路徑

Path path = new Path("hdfs://bigdata111:9000/user/itstar/tmp/hadoop-2.7.2.tar.gz");

 

// 3 打開輸入流

FSDataInputStream fis = fs.open(path);

 

// 4 創建輸出流

FileOutputStream fos = new FileOutputStream("e:/hadoop-2.7.2.tar.gz.part1");

 

// 5 流對接

byte[] buf = new byte[1024];

for (int i = 0; i < 128 * 1024; i++) {

fis.read(buf);

fos.write(buf);

}

 

// 6 關閉流

IOUtils.closeStream(fis);

IOUtils.closeStream(fos);

}

2下載第二塊

@Test

// 定位下載第二塊內容

public void readFileSeek2() throws Exception{

 

// 1 創建配置信息對象

Configuration configuration = new Configuration();

 

FileSystem fs = FileSystem.get(new URI("hdfs://bigdata111:9000"), configuration, "itstar");

 

// 2 獲取輸入流路徑

Path path = new Path("hdfs://bigdata111:9000/user/itstar/tmp/hadoop-2.7.2.tar.gz");

 

// 3 打開輸入流

FSDataInputStream fis = fs.open(path);

 

// 4 創建輸出流

FileOutputStream fos = new FileOutputStream("e:/hadoop-2.7.2.tar.gz.part2");

 

// 5 定位偏移量(第二塊的首位)

fis.seek(1024 * 1024 * 128);

 

// 6 流對接

IOUtils.copyBytes(fis, fos, 1024);

 

// 7 關閉流

IOUtils.closeStream(fis);

IOUtils.closeStream(fos);

}

3)合並文件

在window命令窗口中執行

type hadoop-2.7.2.tar.gz.part2 >> hadoop-2.7.2.tar.gz.part1

HDFS的數據

4.1 HDFS寫數據流程

4.1.1 剖析文件寫入

 

1)客戶端namenode請求上傳文件,namenode檢查目標文件是否已存在,父目錄是否存在。

2namenode返回是否可以上傳。

3)客戶端請求第一個 block上傳到哪幾個datanode服務器上。

4namenode返回3datanode節點,分別為dn1、dn2、dn3。

5)客戶端請求dn1上傳數據,dn1收到請求會繼續調用dn2,然后dn2調用dn3,將這個通信管道建立完成

6dn1、dn2、dn3逐級應答客戶端

7)客戶端開始往dn1上傳第一個block(先從磁盤讀取數據放到一個本地內存緩存),以packet為單位,dn1收到一個packet就會傳給dn2,dn2傳給dn3;dn1每傳一個packet會放入一個應答隊列等待應答

8)當一個block傳輸完成之后,客戶端再次請求namenode上傳第二個block的服務器。(重復執行3-7步)

4.1.2 網絡拓撲概念

本地網絡中,兩個節點被稱為“彼此近鄰”是什么意思?海量數據處理中,其主要限制因素是節點之間數據的傳輸速率——帶寬很稀缺。這里想法是將兩個節點間的帶寬作為距離的衡量標准。

節點距離:兩個節點到達最近的共同祖先的距離總和。

例如,假設有數據中心d1機架r1中的節點n1節點可以表示為/d1/r1/n1利用這種標記,這里給出四種距離描述。

Distance(/d1/r1/n1, /d1/r1/n1)=0(同一節點上的進程

Distance(/d1/r1/n1, /d1/r1/n2)=2(同一機架上的不同節點

Distance(/d1/r1/n1, /d1/r3/n2)=4(同一數據中心不同機架上的節點

Distance(/d1/r1/n1, /d2/r4/n2)=6(不同數據中心的節點

 

大家算一算每兩個節點之間距離

 

4.1.3 機架感知(副本節點選擇)

1)官方ip地址

http://hadoop.apache.org/docs/r2.7.2/hadoop-project-dist/hadoop-common/RackAwareness.html

http://hadoop.apache.org/docs/r2.7.2/hadoop-project-dist/hadoop-hdfs/HdfsDesign.html#Data_Replication

2)低版本Hadoop副本節點選擇

第一個副本client所處的節點上如果客戶端在集群外,隨機選一個。

二個副本和第一個副本位於不相同機架隨機節點上。

三個副本和第二個副本位於相同機架節點隨機。

 

3)Hadoop2.7.2副本節點選擇

第一個副本在client所處的節點上如果客戶端在集群外,隨機選一個。

二個本和第一個副本位於相同機架隨機節點。

三個本位於不同機架,隨機節點。

 

4.2 HDFS讀數據流程

 

1)客戶端向namenode請求下載文件,namenode通過查詢元數據,找到文件塊所在的datanode地址。

2)挑選一台datanode(就近原則,然后隨機)服務器,請求讀取數據

3datanode開始傳輸數據給客戶端(從磁盤里面讀取數據放入流,以packet為單位來做校驗)。

4)客戶端以packet為單位接收,先在本地緩存,然后寫入目標文件。

4.3 一致性模型

1debug調試如下代碼

@Test

public void writeFile() throws Exception{

// 1 創建配置信息對象

Configuration configuration = new Configuration();

fs = FileSystem.get(configuration);

 

// 2 創建文件輸出流

Path path = new Path("hdfs://bigdata111:9000/user/itstar/hello.txt");

FSDataOutputStream fos = fs.create(path);

 

// 3 寫數據

fos.write("hello".getBytes());

        // 4 一致性刷新

fos.hflush();

 

fos.close();

}

2)總結

寫入數據時,如果希望數據被其他client立即可見,調用如下方法

FsDataOutputStream. hflush (); //清理客戶端緩沖區數據,被其他client立即可見

NameNode工作機制

5.1 NameNode&Secondary NameNode工作機制

 

 

1)第一階段:namenode啟動

1)第一次啟動namenode格式化后創建fsimage和edits文件。如果不是第一次啟動,直接加載編輯日志和鏡像文件到內存。

2客戶端對元數據進行增刪改的請求

3namenode記錄操作日志,更新滾動日志

4namenode在內存中對數據進行增刪改查

2)第二階段:Secondary NameNode工作

1Secondary NameNode詢問namenode是否需要checkpoint直接帶回namenode是否檢查結果。

2Secondary NameNode請求執行checkpoint。

3namenode滾動正在寫的edits日志

4)將滾動前的編輯日志和鏡像文件拷貝到Secondary NameNode

5Secondary NameNode加載編輯日志和鏡像文件到內存,並合並。

6生成新的鏡像文件fsimage.chkpoint

7拷貝fsimage.chkpoint到namenode

8namenodefsimage.chkpoint重新命名成fsimage

3)web端訪問SecondaryNameNode

1)啟動集群

2)瀏覽器中輸入:http://bigdata111:50090/status.html

3)查看SecondaryNameNode信息

4chkpoint檢查時間參數設置

1)通常情況下,SecondaryNameNode每隔一小時執行一次

[hdfs-default.xml]

<property>

  <name>dfs.namenode.checkpoint.period</name>

  <value>3600</value>

</property>

2)一分鍾檢查一次操作次數,當操作次數達到1百萬時,SecondaryNameNode執行一次。

<property>

  <name>dfs.namenode.checkpoint.txns</name>

  <value>1000000</value>

<description>操作動作次數</description>

</property>

 

<property>

  <name>dfs.namenode.checkpoint.check.period</name>

  <value>60</value>

<description> 1分鍾檢查一次操作次數</description>

</property>

5.2 鏡像文件和編輯日志文件

1概念

namenode被格式化之后,將在/opt/module/hadoop-2.7.2/data/tmp/dfs/name/current目錄中產生如下文件

edits_0000000000000000000

fsimage_0000000000000000000.md5

seen_txid

VERSION

1Fsimage文件:HDFS文件系統元數據的一個永久性的檢查點,其中包含HDFS文件系統的所有目錄和文件idnode的序列化信息。 

2Edits文件:存放HDFS文件系統的所有更新操作的路徑,文件系統客戶端執行的所有寫操作首先會被記錄到edits文件中。 

3seen_txid文件保存的是一個數字,就是最后一個edits_的數字

4每次Namenode啟動的時候都會將fsimage文件讀入內存,並從00001開始到seen_txid中記錄的數字依次執行每個edits里面的更新操作,保證內存中的元數據信息是最新的、同步的,可以看成Namenode啟動的時候就將fsimageedits文件進行了合並

2oiv查看fsimage文件

1查看oiv和oev命令

[itstar@bigdata111 current]$ hdfs

oiv                  apply the offline fsimage viewer to an fsimage

oev                  apply the offline edits viewer to an edits file

2)基本語法

hdfs oiv -p 文件類型 -i鏡像文件 -o 轉換后文件輸出路徑

3)案例實操

[itstar@bigdata111 current]$ pwd

/opt/module/hadoop-2.7.2/data/tmp/dfs/name/current

 

[itstar@bigdata111 current]$ hdfs oiv -p XML -i fsimage_0000000000000000025 -o /opt/module/hadoop-2.7.2/fsimage.xml

 

[itstar@bigdata111 current]$ cat /opt/module/hadoop-2.7.2/fsimage.xml

將顯示xml文件內容拷貝到IDEA中創建的xml文件中,並格式化

3)oev查看edits文件

(1)基本語法

hdfs oev -p 文件類型 -i編輯日志 -o 轉換后文件輸出路徑

(2)案例實操

[itstar@bigdata111 current]$ hdfs oev -p XML -i edits_0000000000000000012-0000000000000000013 -o /opt/module/hadoop-2.7.2/edits.xml

[itstar@bigdata111 current]$ cat /opt/module/hadoop-2.7.2/edits.xml

將顯示xml文件內容拷貝到IDEA中創建的xml文件中,並格式化

5.3 滾動編輯日志

正常情況HDFS文件系統有更新操作,就會滾動編輯日志可以用命令強制滾動編輯日志。

1)滾動編輯日志(前提必須啟動集群)

[itstar@bigdata111 current]$ hdfs dfsadmin -rollEdits

2)鏡像文件什么時候產生

Namenode啟動時加載鏡像文件和編輯日志

5.4 namenode版本

1查看namenode版本號

在/opt/module/hadoop-2.7.2/data/tmp/dfs/name/current這個目錄下查看VERSION

namespaceID=1933630176

clusterID=CID-1f2bf8d1-5ad2-4202-af1c-6713ab381175

cTime=0

storageType=NAME_NODE

blockpoolID=BP-97847618-192.168.10.102-1493726072779

layoutVersion=-63

2)namenode版本號具體解釋

1namespaceIDHDFS,會有多個Namenode,所以不同NamenodenamespaceID是不同的,分別管理一組blockpoolID

2clusterID集群id,全局唯一

3cTime屬性標記了namenode存儲系統的創建時間,對於剛剛格式化的存儲系統,這個屬性為0但是在文件系統升級之后,該值會更新到新的時間戳。

4storageType屬性說明該存儲目錄包含的是namenode的數據結構。

5blockpoolID一個block pool id標識一個block pool,並且是跨集群的全局唯一。當一個新的Namespace被創建的時候(format過程的一部分)會創建並持久化一個唯一ID。在創建過程構建全局唯一的BlockPoolID比人為的配置更可靠一些。NNBlockPoolID持久化到磁盤中,在后續的啟動過程中,會再次load並使用。

6layoutVersion一個負整數。通常只有HDFS增加新特性時才會更新這個版本號。

5.5 SecondaryNameNode目錄結構

Secondary NameNode用來監控HDFS狀態的輔助后台程序,每隔一段時間獲取HDFS元數據的快照。

在/opt/module/hadoop-2.7.2/data/tmp/dfs/namesecondary/current這個目錄中查看SecondaryNameNode目錄結構。

edits_0000000000000000001-0000000000000000002

fsimage_0000000000000000002

fsimage_0000000000000000002.md5

VERSION

SecondaryNameNode的namesecondary/current目錄和主namenodecurrent目錄的布局相同。

好處:在主namenode發生故障時(假設沒有及時備份數據),可以SecondaryNameNode恢復數據

方法一:將SecondaryNameNode中數據拷貝到namenode存儲數據的目錄;

方法二:使用-importCheckpoint選項啟動namenode守護進程,從而將SecondaryNameNode中數據拷貝到namenode目錄

1)案例實操(一)

模擬namenode故障,並采用方法一,恢復namenode數據

1kill -9 namenode進程

2刪除namenode存儲的數據(/opt/module/hadoop-2.7.2/data/tmp/dfs/name)

rm -rf /opt/module/hadoop-2.7.2/data/tmp/dfs/name/*

3拷貝SecondaryNameNode中數據到原namenode存儲數據目錄

cp -R /opt/module/hadoop-2.7.2/data/tmp/dfs/namesecondary/* /opt/module/hadoop-2.7.2/data/tmp/dfs/name/

4重新啟動namenode

sbin/hadoop-daemon.sh start namenode

2)案例實操(二)

模擬namenode故障,並采用方法,恢復namenode數據

0)修改hdfs-site.xml中

<property>

  <name>dfs.namenode.checkpoint.period</name>

  <value>120</value>

</property>

 

<property>

  <name>dfs.namenode.name.dir</name>

  <value>/opt/module/hadoop-2.7.2/data/tmp/dfs/name</value>

</property>

1kill -9 namenode進程

2刪除namenode存儲的數據(/opt/module/hadoop-2.7.2/data/tmp/dfs/name)

rm -rf /opt/module/hadoop-2.7.2/data/tmp/dfs/name/*

3)如果SecondaryNameNode不和Namenode在一個主機節點上,需要將SecondaryNameNode存儲數據的目錄拷貝到Namenode存儲數據的平級目錄。

[itstar@bigdata111 dfs]$ pwd

/opt/module/hadoop-2.7.2/data/tmp/dfs

[itstar@bigdata111 dfs]$ ls

data  name  namesecondary

(4)導入檢查點數據(等待一會ctrl+c結束掉)

bin/hdfs namenode -importCheckpoint

(5)啟動namenode

sbin/hadoop-daemon.sh start namenode

(6)如果提示文件鎖了,可以刪除in_use.lock

rm -rf /opt/module/hadoop-2.7.2/data/tmp/dfs/namesecondary/in_use.lock

5.6 集群安全模式操作

1)概述

Namenode啟動時,首先將映像文件(fsimage載入內存,並執行編輯日志(edits的各項操作。一旦內存中成功建立文件系統元數據的映像,則創建一個新的fsimage文件和一個空的編輯日志。此時,namenode開始監聽datanode請求。但是此刻,namenode運行在安全模式,即namenode文件系統對於客戶端來說是只讀的。

系統中的數據塊的位置並不是由namenode維護的,而是以塊列表的形式存儲在datanode中。系統的正常操作期間,namenode會在內存中保留所有塊位置的映射信息。在安全模式下,各個datanode向namenode發送最新的塊列表信息namenode了解到足夠的塊位置信息之后,即可高效運行文件系統。

如果滿足“最小副本條件”,namenode會在30鍾之后就退出安全模式。所謂最小副本條件指的是在整個文件系統中99.9%的塊滿足最小副本級別(默認值:dfs.replication.min=1啟動一個剛剛格式化的HDFS集群時,因為系統中還沒有任何塊,所以namenode不會進入安全模式。

2)基本語法

集群處於安全模式,不能執行重要操作(操作)集群啟動完成后,自動退出安全模式。

(1)bin/hdfs dfsadmin -safemode get (功能描述:查看安全模式狀態

2bin/hdfs dfsadmin -safemode enter   (功能描述:進入安全模式狀態

3bin/hdfs dfsadmin -safemode leave (功能描述:離開安全模式狀態

4bin/hdfs dfsadmin -safemode wait (功能描述:等待安全模式狀態

3)案例

模擬等待安全模式

1)先進入安全模式

bin/hdfs dfsadmin -safemode enter

2)執行下面的腳本

編輯一個腳本

#!/bin/bash

bin/hdfs dfsadmin -safemode wait

bin/hdfs dfs -put ~/hello.txt /root/hello.txt

3)再打開一個窗口,執行

bin/hdfs dfsadmin -safemode leave

5.7 Namenode目錄配置

1namenode的本地目錄可以配置成多個,每個目錄存放內容相同,增加了可靠性。

2具體配置如下:

hdfs-site.xml

<property>

    <name>dfs.namenode.name.dir</name>

<value>file:///${hadoop.tmp.dir}/dfs/name1,file:///${hadoop.tmp.dir}/dfs/name2</value>

</property>

DataNode工作機制

6.1 DataNode工作機制

 

1一個數據塊在datanode上以文件形式存儲在磁盤上,包括兩個文件,一個是數據本身,一個是元數據包括數據塊的長度,塊數據校驗和,以及時間戳

2DataNode啟動后向namenode注冊,通過后,周期性(1小時namenode上報所有的塊信息。

3心跳是每3一次,心跳返回結果帶有namenode給該datanode的命令如復制塊數據到另一台機器,或刪除某個數據塊如果超過10分鍾沒有收到某個datanode的心跳,則認為該節點不可用。

4集群運行中可以安全加入和退出一些機器

6.2 數據完整性

1當DataNode讀取block的時候,它會計算checksum

2如果計算后的checksum,與block創建時值不一樣,說明block已經損壞。

3client讀取其他DataNode上的block.

4datanode在其文件創建后周期驗證checksum

6.3 掉線時限參數設置

datanode進程死亡或者網絡故障造成datanode無法與namenode通信,namenode不會立即把該節點判定為死亡,要經過一段時間,這段時間暫稱作超時時長。HDFS默認的超時時長為10分鍾+30秒。如果定義超時時間為timeout,則超時時長的計算公式為:

timeout  = 2 * dfs.namenode.heartbeat.recheck-interval + 10 * dfs.heartbeat.interval

而默認的dfs.namenode.heartbeat.recheck-interval 大小為5分鍾,dfs.heartbeat.interval默認為3秒。

需要注意的是hdfs-site.xml 配置文件中的heartbeat.recheck.interval的單位為毫秒dfs.heartbeat.interval的單位為秒。

<property>

    <name>dfs.namenode.heartbeat.recheck-interval</name>

    <value>300000</value>

</property>

<property>

    <name> dfs.heartbeat.interval </name>

    <value>3</value>

</property>

6.4 DataNode的目錄結構

和namenode不同的是,datanode的存儲目錄是初始階段自動創建的,不需要額外格式化。

1)在/opt/module/hadoop-2.7.2/data/tmp/dfs/data/current這個目錄下查看版本號

[itstar@bigdata111 current]$ cat VERSION

storageID=DS-1b998a1d-71a3-43d5-82dc-c0ff3294921b

clusterID=CID-1f2bf8d1-5ad2-4202-af1c-6713ab381175

cTime=0

datanodeUuid=970b2daf-63b8-4e17-a514-d81741392165

storageType=DATA_NODE

layoutVersion=-56

2)具體解釋

1storageID:存儲id

2clusterID集群id,全局唯一

3cTime屬性標記了datanode存儲系統的創建時間,對於剛剛格式化的存儲系統,這個屬性為0但是在文件系統升級之后,該值會更新到新的時間戳。

4datanodeUuiddatanode的唯一識別碼

5storageType:存儲類型

6layoutVersion一個負整數。通常只有HDFS增加新特性時才會更新這個版本號。

3)在/opt/module/hadoop-2.7.2/data/tmp/dfs/data/current/BP-97847618-192.168.10.102-1493726072779/current這個目錄下查看該數據的版本號

[itstar@bigdata111 current]$ cat VERSION

#Mon May 08 16:30:19 CST 2017

namespaceID=1933630176

cTime=0

blockpoolID=BP-97847618-192.168.10.102-1493726072779

layoutVersion=-56

4)具體解釋

1namespaceID:datanode首次訪問namenode的時候從namenode處獲取的storageID每個datanode來說是唯一的(但對於單個datanode中所有存儲目錄來說則是相同的),namenode可用這個屬性來區分不同datanode

2cTime屬性標記了datanode存儲系統的創建時間,對於剛剛格式化的存儲系統,這個屬性為0但是在文件系統升級之后,該值會更新到新的時間戳。

3blockpoolID一個block pool id標識一個block pool,並且是跨集群的全局唯一。當一個新的Namespace被創建的時候(format過程的一部分)會創建並持久化一個唯一ID。在創建過程構建全局唯一的BlockPoolID比人為的配置更可靠一些。NNBlockPoolID持久化到磁盤中,在后續的啟動過程中,會再次load並使用。

4layoutVersion一個負整數。通常只有HDFS增加新特性時才會更新這個版本號。

6.5 Datanode目錄配置

1datanode也可以配置成多個目錄,每個目錄存儲的數據不一樣。:數據不是副本。

2)具體配置如下:

hdfs-site.xml

<property>

        <name>dfs.datanode.data.dir</name>

        <value>file:///${hadoop.tmp.dir}/dfs/data1,file:///${hadoop.tmp.dir}/dfs/data2</value>

</property>

 

HDFS其他功能

7.1 集群間數據拷貝

1scp實現兩個遠程主機之間的文件復制

scp -r hello.txt root@bigdata112:/user/itstar/hello.txt // push

scp -r root@bigdata112:/user/itstar/hello.txt  hello.txt // pull

scp -r root@bigdata112:/user/itstar/hello.txt root@bigdata113:/user/itstar   //是通過本地主機中轉實現兩個遠程主機的文件復制;如果在兩個遠程主機之間ssh沒有配置的情況下可以使用該方式。

2采用discp命令實現兩個hadoop集群之間的遞歸數據復制

bin/hadoop distcp hdfs://haoop102:9000/user/itstar/hello.txt hdfs://bigdata112:9000/user/itstar/hello.txt

7.2 Hadoop存檔

1)理論概述

每個文件均按塊存儲,每個塊的元數據存儲在namenode的內存中,因此hadoop存儲小文件會非常低效。因為大量的小文件會耗盡namenode中的大部分內存。但注意,存儲小文件所需要的磁盤容量和存儲這些文件原始內容所需要的磁盤空間相比也不會增多。例如一個1MB的文件以大小為128MB的塊存儲,使用的是1MB磁盤空間,而不是128MB

Hadoop存檔文件或HAR文件,是一個更高效的文件存檔工具,它將文件存入HDFS塊,在減少namenode內存使用的同時,允許對文件進行透明的訪問。具體來,Hadoop存檔文件可以用作MapReduce的輸入。

2)案例實操

1需要啟動yarn進程

start-yarn.sh

2歸檔文件

歸檔成一個叫做xxx.har的文件夾,該文件夾下有相應的數據文件。Xx.har目錄是一個整體,該目錄看成是一個歸檔文件即可。

bin/hadoop archive -archiveName myhar.har -p /user/itstar   /user/my

3)查看歸檔

hadoop fs -lsr /user/my/myhar.har

hadoop fs -lsr har:///myhar.har

4)解歸檔文件

hadoop fs -cp har:/// user/my/myhar.har /* /user/itstar

7.3 快照管理

快照相當於對目錄做一個備份不會立即復制所有文件,而是指向同一個文件。當寫入發生時,才會產生新文件。

1)基本語法

1hdfs dfsadmin -allowSnapshot 路徑   (功能描述:開啟指定目錄的快照功能

(2)hdfs dfsadmin -disallowSnapshot 路徑 (功能描述:禁用定目錄的快照功能,默認是禁用

3hdfs dfs -createSnapshot 路徑        (功能描述:目錄創建快照

(4)hdfs dfs -createSnapshot 路徑 名稱   (功能描述:指定名稱創建快照

5hdfs dfs -renameSnapshot 路徑 舊名稱 名稱 (功能描述:重命名快照

(6)hdfs lsSnapshottableDir         (功能描述:列出當前用戶所有可快照目錄

(7)hdfs snapshotDiff 路徑1 路徑2 (功能描述:比較兩個快照目錄的不同之處

8hdfs dfs -deleteSnapshot <path> <snapshotName>  (功能描述:刪除快照

2案例實操

1)開啟/禁用指定目錄的快照功能

hdfs dfsadmin -allowSnapshot /user/itstar/data

hdfs dfsadmin -disallowSnapshot /user/itstar/data

2)對目錄創建快照

hdfs dfs -createSnapshot /user/itstar/data // 目錄創建快照

通過web訪問hdfs://bigdata111:9000/user/itstar/data/.snapshot/s…..// 快照和源文件使用相同數據塊

hdfs dfs -lsr /user/itstar/data/.snapshot/

3)指定名稱創建快照

hdfs dfs -createSnapshot /user/itstar/data miao170508

4)重命名快照

hdfs dfs -renameSnapshot /user/itstar/data/ miao170508 itstar170508

5)列出當前用戶所有可快照目錄

hdfs lsSnapshottableDir

6)比較兩個快照目錄的不同之處

hdfs snapshotDiff /user/itstar/data/  .  .snapshot/itstar170508

7)恢復快照

hdfs dfs -cp /user/itstar/input/.snapshot/s20170708-134303.027 /user

7.4 回收站

1默認回收站

默認fs.trash.interval=00表示禁用回收站,可以設置刪除文件的存活時間

默認fs.trash.checkpoint.interval=0,檢查回收站的間隔時間

要求fs.trash.checkpoint.interval<=fs.trash.interval。

 

2)啟用回收站

修改core-site.xml,配置垃圾回收時間1分鍾。

<property>

    <name>fs.trash.interval</name>

    <value>1</value>

</property>

3)查看回收站

回收集群中的;路徑:/user/itstar/.Trash/….

4)修改訪問垃圾回收站用戶名稱

進入垃圾回收站用戶名稱,默認是dr.who,修改為itstar用戶

[core-site.xml]

<property>

  <name>hadoop.http.staticuser.user</name>

  <value>itstar</value>

</property>

5)通過程序刪除的文件不會經過回收站,需要調用moveToTrash()進入回收站

Trash trash = New Trash(conf);

trash.moveToTrash(path);

6)恢復回收站數據

hadoop fs -mv /user/itstar/.Trash/Current/user/itstar/input    /user/itstar/input

7)清空回收站

hdfs dfs -expunge

HDFS HA高可用

8.1 HA概述

1)所謂HA(high available),即高可用(7*24小時不中斷服務)

2)實現高可用最關鍵策略是消除單點故障。HA嚴格來說應該分成各個組件的HA機制HDFSHAYARNHA

3Hadoop2.0之前,在HDFS集群中NameNode存在單點故障(SPOF

4)NameNode主要在以下兩個方面影響HDFS集群

NameNode機器發生意外,如宕機,集群將無法使用,直到管理員重啟

NameNode機器需要升級,包括軟件、硬件升級,此時集群也將無法使用

HDFS HA功能通過配置Active/Standby兩個nameNodes實現在集群中對NameNode的熱備來解決上述問題。如果出現故障,如機器崩潰或機器需要升級維護,這時可通過此種方式將NameNode很快的切換到另外一台機器。

8.2 HDFS-HA工作機制

1)通過雙namenode消除單點故障

8.2.1 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對外提供服務

8.2.2 HDFS-HA自動故障轉移工作機制

面學習了使用命令hdfs haadmin -failover手動進行故障轉移,在該模式下,即使現役NameNode已經失效,系統也不會自動從現役NameNode轉移到待機NameNode,下面學習如何配置部署HA自動進行故障轉移。自動故障轉移為HDFS部署增加了兩個新組件:ZooKeeperZKFailoverControllerZKFC)進程。ZooKeeper是維護少量協調數據,通知客戶端這些數據的改變和監視客戶端故障的高可用服務。HA的自動故障轉移依賴於ZooKeeper的以下功能:

1故障檢測:集群中的每個NameNodeZooKeeper中維護了一個持久會話,如果機器崩潰,ZooKeeper中的會話將終止,ZooKeeper通知另一個NameNode需要觸發故障轉移。

2現役NameNode選擇:ZooKeeper提供了一個簡單的機制用於唯一的選擇一個節點為active狀態。如果目前現役NameNode崩潰,另一個節點可能從ZooKeeper獲得特殊的排外鎖以表明它應該成為現役NameNode

ZKFC是自動故障轉移中的另一個新組件,是ZooKeeper的客戶端,也監視和管理NameNode的狀態。每個運行NameNode的主機也運行了一個ZKFC進程,ZKFC負責:

1健康監測:ZKFC使用一個健康檢查命令定期地ping與之在相同主機的NameNode,只要該NameNode及時地回復健康狀態,ZKFC認為該節點是健康的。如果該節點崩潰,凍結或進入不健康狀態,健康監測器標識該節點為非健康的。

2ZooKeeper會話管理:當本地NameNode是健康的,ZKFC保持一個在ZooKeeper中打開的會話。如果本地NameNode處於active狀態,ZKFC也保持一個特殊的znode鎖,該鎖使用了ZooKeeper對短暫節點的支持,如果會話終止,鎖節點將自動刪除。

3基於ZooKeeper的選擇:如果本地NameNode是健康的,且ZKFC發現沒有其它的節點當前持有znode鎖,它將為自己獲取該鎖。如果成功,則它已經贏得了選擇,並負責運行故障轉移進程以使它的本地NameNodeactive。故障轉移進程與前面描述的手動故障轉移相似,首先如果必要保護之前的現役NameNode,然后本地NameNode轉換為active狀態。

 

8.4 HDFS-HA集群配置

8.4.1 環境准備

1)修改IP

2)修改主機名及主機名和IP地址的映射

3)關閉防火牆

4ssh免密登錄

5)安裝JDK,配置環境變量等

8.4.2 規划集群

bigdata111   bigdata112    bigdata113

NameNode NameNode

JournalNode JournalNode JournalNode

DataNode DataNode DataNode

ZK ZK ZK

ResourceManager

NodeManager NodeManager NodeManager

8.4.3 配置Zookeeper集群

0)集群規划

在bigdata111、bigdata112和bigdata113三個節點上部署Zookeeper。

1解壓安裝

1)解壓zookeeper安裝包到/opt/module/目錄下

[itstar@bigdata111 software]$ tar -zxvf zookeeper-3.4.10.tar.gz -C /opt/module/

2)在/opt/module/zookeeper-3.4.10/這個目錄下創建zkData

mkdir -p zkData

3)重命名/opt/module/zookeeper-3.4.10/conf這個目錄下的zoo_sample.cfg為zoo.cfg

mv zoo_sample.cfg zoo.cfg

2)配置zoo.cfg文件

1)具體配置

dataDir=/opt/module/zookeeper-3.4.10/zkData

增加如下配置

#######################cluster##########################

server.2=bigdata111:2888:3888

server.3=bigdata112:2888:3888

server.4=bigdata113:2888:3888

2)配置參數解讀

Server.A=B:C:D。

A是一個數字,表示這個是第幾號服務器;

B是這個服務器的ip地址;

C是這個服務器與集群中的Leader服務器交換信息的端口;

D是萬一集群中的Leader服務器掛了,需要一個端口來重新進行選舉,選出一個新的Leader,而這個端口就是用來執行選舉時服務器相互通信的端口。

集群模式下配置一個文件myid,這個文件在dataDir目錄下,這個文件里面有一個數據就是A的值,Zookeeper啟動時讀取此文件,拿到里面數據與zoo.cfg里面的配置信息比較從而判斷到底是哪個server

3)集群操作

1/opt/module/zookeeper-3.4.10/zkData目錄下創建一個myid的文件

touch myid

添加myid文件,注意一定要在linux里面創建notepad++里面很可能亂碼

2編輯myid文件

vi myid

文件中添加與server的編號:如2

3)拷貝配置好的zookeeper到其他機器上

scp -r zookeeper-3.4.10/ root@bigdata112.itstar.com:/opt/app/

scp -r zookeeper-3.4.10/ root@bigdata113.itstar.com:/opt/app/

分別修改myid文件中內容為34

4分別啟動zookeeper

[root@bigdata111 zookeeper-3.4.10]# bin/zkServer.sh start

[root@bigdata112 zookeeper-3.4.10]# bin/zkServer.sh start

[root@bigdata113 zookeeper-3.4.10]# bin/zkServer.sh start

5查看狀態

[root@bigdata111 zookeeper-3.4.10]# bin/zkServer.sh status

JMX enabled by default

Using config: /opt/module/zookeeper-3.4.10/bin/../conf/zoo.cfg

Mode: follower

[root@bigdata112 zookeeper-3.4.10]# bin/zkServer.sh status

JMX enabled by default

Using config: /opt/module/zookeeper-3.4.10/bin/../conf/zoo.cfg

Mode: leader

[root@bigdata113 zookeeper-3.4.5]# bin/zkServer.sh status

JMX enabled by default

Using config: /opt/module/zookeeper-3.4.10/bin/../conf/zoo.cfg

Mode: follower

8.4.4 配置HDFS-HA集群

1官方地址:http://hadoop.apache.org/

2在opt目錄下創建一個ha文件夾

mkdir ha

3將/opt/app/下 hadoop-2.7.2拷貝/opt/ha目錄

cp -r hadoop-2.7.2/ /opt/ha/

4配置hadoop-env.sh

export JAVA_HOME=/opt/module/jdk1.7.0_79

5配置core-site.xml

<configuration>

<!-- 把兩個NameNode)的地址組裝成一個集群mycluster -->

<property>

<name>fs.defaultFS</name>

         <value>hdfs://mycluster</value>

</property>

 

<!-- 指定hadoop運行時產生文件的存儲目錄 -->

<property>

<name>hadoop.tmp.dir</name>

<value>/opt/ha/hadoop-2.7.2/data/tmp</value>

</property>

</configuration>

6配置hdfs-site.xml

<configuration>

<!-- 完全分布式集群名稱 -->

<property>

<name>dfs.nameservices</name>

<value>mycluster</value>

</property>

 

<!-- 集群中NameNode節點都有哪些 -->

<property>

<name>dfs.ha.namenodes.mycluster</name>

<value>nn1,nn2</value>

</property>

 

<!-- nn1RPC通信地址 -->

<property>

<name>dfs.namenode.rpc-address.mycluster.nn1</name>

<value>bigdata111:9000</value>

</property>

 

<!-- nn2RPC通信地址 -->

<property>

<name>dfs.namenode.rpc-address.mycluster.nn2</name>

<value>bigdata112:9000</value>

</property>

 

<!-- nn1http通信地址 -->

<property>

<name>dfs.namenode.http-address.mycluster.nn1</name>

<value>bigdata111:50070</value>

</property>

 

<!-- nn2http通信地址 -->

<property>

<name>dfs.namenode.http-address.mycluster.nn2</name>

<value>bigdata112:50070</value>

</property>

 

<!-- 指定NameNode元數據在JournalNode上的存放位置 -->

<property>

<name>dfs.namenode.shared.edits.dir</name>

<value>qjournal://bigdata111:8485;bigdata112:8485;bigdata113:8485/mycluster</value>

</property>

 

<!-- 配置隔離機制,即同一時刻只能有一台服務器對外響應 -->

<property>

<name>dfs.ha.fencing.methods</name>

<value>sshfence</value>

</property>

 

<!-- 使用隔離機制時需要ssh無秘鑰登錄-->

<property>

<name>dfs.ha.fencing.ssh.private-key-files</name>

<value>/home/itstar/.ssh/id_rsa</value>

</property>

 

<!-- 聲明journalnode服務器存儲目錄-->

<property>

<name>dfs.journalnode.edits.dir</name>

<value>/opt/ha/hadoop-2.7.2/data/jn</value>

</property>

 

<!-- 關閉權限檢查-->

<property>

<name>dfs.permissions.enable</name>

<value>false</value>

</property>

 

<!-- 訪問代理類:clientmyclusteractive配置失敗自動切換實現方式-->

<property>

   <name>dfs.client.failover.proxy.provider.mycluster</name>

<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>

</property>

</configuration>

7拷貝配置好的hadoop環境到其他節點

8.4.5 啟動HDFS-HA集群

1在各個JournalNode節點上,輸入以下命令啟動journalnode服務:

sbin/hadoop-daemon.sh start journalnode

2)在[nn1],對其進行格式化,並啟動:

bin/hdfs namenode -format

sbin/hadoop-daemon.sh start namenode

3)在[nn2],同步nn1的元數據信息:

bin/hdfs namenode -bootstrapStandby

4)啟動[nn2]

sbin/hadoop-daemon.sh start namenode

5查看web頁面顯示

 

 

6)[nn1],啟動所有datanode

sbin/hadoop-daemons.sh start datanode

7)將[nn1]切換Active

bin/hdfs haadmin -transitionToActive nn1

8查看是否Active

bin/hdfs haadmin -getServiceState nn1

8.4.6 配置HDFS-HA自動故障轉移

1)具體配置

1)在hdfs-site.xml中增加

<property>

<name>dfs.ha.automatic-failover.enabled</name>

<value>true</value>

</property>

2)在core-site.xml文件中增加

<property>

<name>ha.zookeeper.quorum</name>

<value>bigdata111:2181,bigdata112:2181,bigdata113:2181</value>

</property>

2)啟動

1)關閉所有HDFS服務:

sbin/stop-dfs.sh

2)啟動Zookeeper集群:

bin/zkServer.sh start

3)初始化HAZookeeper狀態

bin/hdfs zkfc -formatZK

4)啟動HDFS服務:

sbin/start-dfs.sh

5)在各個NameNode節點上啟動DFSZK Failover Controller,先在哪台機器啟動,哪個機器的NameNode就是Active NameNode

sbin/hadoop-daemin.sh start zkfc

3)驗證

1)將Active NameNode進程kill

kill -9 namenode的進程id

2)將Active NameNode機器斷開網絡

service network stop

8.5 YARN-HA配置

8.5.1 YARN-HA工作機制

1)官方文檔:

http://hadoop.apache.org/docs/r2.7.2/hadoop-yarn/hadoop-yarn-site/ResourceManagerHA.html

2YARN-HA工作機制

 

8.5.2 配置YARN-HA集群

0)環境准備

1)修改IP

2)修改主機名及主機名和IP地址的映射

3)關閉防火牆

4ssh免密登錄

5)安裝JDK,配置環境變量等

6)配置Zookeeper集群

1規划集群

bigdata111   bigdata112    bigdata113

NameNode NameNode

JournalNode JournalNode JournalNode

DataNode DataNode DataNode

ZK ZK ZK

ResourceManager ResourceManager

NodeManager NodeManager NodeManager

2)具體配置

1yarn-site.xml

<configuration>

 

    <property>

        <name>yarn.nodemanager.aux-services</name>

        <value>mapreduce_shuffle</value>

    </property>

 

    <!--啟用resourcemanager ha-->

    <property>

        <name>yarn.resourcemanager.ha.enabled</name>

        <value>true</value>

    </property>

 

    <!--聲明兩台resourcemanager的地址-->

    <property>

        <name>yarn.resourcemanager.cluster-id</name>

        <value>cluster-yarn1</value>

    </property>

 

    <property>

        <name>yarn.resourcemanager.ha.rm-ids</name>

        <value>rm1,rm2</value>

    </property>

 

    <property>

        <name>yarn.resourcemanager.hostname.rm1</name>

        <value>bigdata111</value>

    </property>

 

    <property>

        <name>yarn.resourcemanager.hostname.rm2</name>

        <value>bigdata112</value>

    </property>

 

    <!--指定zookeeper集群的地址-->

    <property>

        <name>yarn.resourcemanager.zk-address</name>

        <value>bigdata111:2181,bigdata112:2181,bigdata113: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>

 

</configuration>

2)同步更新其他節點配置信息

3啟動hdfs 

1在各個JournalNode節點上,輸入以下命令啟動journalnode服務:

sbin/hadoop-daemon.sh start journalnode

2)在[nn1],對其進行格式化,並啟動:

bin/hdfs namenode -format

sbin/hadoop-daemon.sh start namenode

3)在[nn2],同步nn1的元數據信息:

bin/hdfs namenode -bootstrapStandby

4)啟動[nn2]

sbin/hadoop-daemon.sh start namenode

5啟動所有datanode

sbin/hadoop-daemons.sh start datanode

6)將[nn1]切換Active

bin/hdfs haadmin -transitionToActive nn1

4)啟動yarn

1)在bigdata111中執行:

sbin/start-yarn.sh

2)在bigdata112中執行:

sbin/yarn-daemon.sh start resourcemanager

3)查看服務狀態

bin/yarn rmadmin -getServiceState rm1

 

8.6 HDFS Federation架構設計

1) NameNode架構的局限性

1Namespace(命名空間)限制

由於NameNode在內存中存儲所有的元數據(metadata因此單個namenode所能存儲的對象(文件+塊)數目受到namenode所在JVMheap size的限制。50Gheap能夠存儲20200million對象,這20個對象支持4000datanode12PB的存儲(假設文件平均大小為40MB隨着數據的飛速增長,存儲的需求也隨之增長。單個datanode4T增長到36T,集群的尺寸增長到8000datanode。存儲的需求從12PB增長到大於100PB

2隔離問題

由於HDFS僅有一個namenode,無法隔離各個程序因此HDFS上的一個實驗程序就很有可能影響整個HDFS運行的程序。

3性能的瓶頸

由於是單個namenodeHDFS架構,因此整個HDFS文件系統的吞吐量受限於單個namenode的吞吐量。

2HDFS Federation架構設計

不能有多個NameNode

NameNode NameNode NameNode

數據數據數據

Log machine 電商數據/話單數據

 

3HDFS Federation應用思考

不同應用可以使用不同NameNode進行數據管理

圖片業務、爬蟲業務、日志審計業務

Hadoop生態系統中,不的框架使用不同的namenode進行管理namespace。隔離性)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM