大數據技術之_04_Hadoop學習_01_HDFS_HDFS概述+HDFS的Shell操作(開發重點)+HDFS客戶端操作(開發重點)+HDFS的數據流(面試重點)+NameNode和SecondaryNameNode(面試開發重點)


第1章 HDFS概述1.1 HDFS產出背景及定義1.2 HDFS優缺點1.3 HDFS組成架構1.4 HDFS文件塊大小(面試重點)第2章 HDFS的Shell操作(開發重點)第3章 HDFS客戶端操作(開發重點)3.1 HDFS客戶端環境准備3.2 HDFS的API操作3.2.1 HDFS文件上傳(測試參數優先級)3.2.2 HDFS文件下載3.2.3 HDFS文件夾刪除3.2.4 HDFS文件名更改3.2.5 HDFS文件詳情查看3.2.6 HDFS文件和文件夾判斷3.3 HDFS的I/O流操作(自定義框架使用)3.3.1 HDFS文件上傳3.3.2 HDFS文件下載3.3.3 定位文件讀取第4章 HDFS的數據流(面試重點)4.1 HDFS寫數據流程4.1.1 剖析文件寫入4.1.2 網絡拓撲-節點距離計算4.1.3 機架感知(副本存儲節點選擇)4.2 HDFS讀數據流程第5章 NameNode和SecondaryNameNode(面試開發重點)5.1 NN和2NN工作機制5.2 Fsimage和Edits解析5.3 CheckPoint時間設置5.4 NameNode故障處理(開發重點:偏運維)5.5 集群安全模式5.6 NameNode多目錄配置


第1章 HDFS概述

1.1 HDFS產出背景及定義


其他文件管理系統:

1.2 HDFS優缺點

優點


缺點

1.3 HDFS組成架構

1)NameNode(nn)和DataNode(dn)


2)Client和Secondary NameNode(2nn)

1.4 HDFS文件塊大小(面試重點)


思考:為什么塊的大小不能設置太小,也不能設置太大?

傳統硬盤HDD(Hard Disk Drive)傳輸速率:100MB/s
固態硬盤SSD(Solid State Drive)傳輸速率:500MB/s
混合硬盤HHD(Hybrid Harddrive)傳輸速率:300MB/s
PCIe固態硬盤SSD(Solid State Drive)傳輸速率:1500MB/s

第2章 HDFS的Shell操作(開發重點)

1、基本語法
  bin/hadoop fs 具體命令 OR bin/hdfs dfs 具體命令
  dfs是fs的實現類。
2、命令大全

[[atguigu@hadoop102 hadoop-2.7.2]$ bin/hadoop fs
Usage: hadoop fs [generic options]
    [-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] [-l] <localsrc> ... <dst>]
    [-copyToLocal [-p] [-ignoreCrc] [-crc] <src> ... <localdst>]
    [-count [-q] [-h] <path> ...]
    [-cp [-f] [-p | -p[topax]] <src> ... <dst>]
    [-createSnapshot <snapshotDir> [<snapshotName>]]
    [-deleteSnapshot <snapshotDir> <snapshotName>]
    [-df [-h] [<path> ...]]
    [-du [-s] [-h] <path> ...]
    [-expunge]
    [-find <path> ... <expression> ...]
    [-get [-p] [-ignoreCrc] [-crc] <src> ... <localdst>]
    [-getfacl [-R] <path>]
    [-getfattr [-R] {-n name | -d} [-e en] <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] [-l] <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>]]
    [-setfattr {-n name [-v value] | -x name} <path>]
    [-setrep [-R] [-w] <rep> <path> ...]
    [-stat [format] <path> ...]
    [-tail [-f] <file>]
    [-test -[defsz] <path>]
    [-text [-ignoreCrc] <src> ...]
    [-touchz <path> ...]
    [-truncate [-w] <length> <path> ...]
    [-usage [cmd ...]]

Generic options supported are
-conf <configuration file>     specify an application configuration file
-D <property=value>            use value for given property
-fs <local|namenode:port>      specify a namenode
-jt <local|resourcemanager:port>    specify a ResourceManager
-files <comma separated list of files>    specify comma separated files to be copied to the map reduce cluster
-libjars <comma separated list of jars>    specify comma separated jar files to include in the classpath.
-archives <comma separated list of archives>    specify comma separated archives to be unarchived on the compute machines.

The general command line syntax is
bin/hadoop command [genericOptions] [commandOptions]

[atguigu@hadoop102 hadoop-2.7.2]$ 

3.常用命令實操
(0)啟動Hadoop集群(方便后續的測試)

[atguigu@hadoop102 hadoop-2.7.2]$ sbin/start-dfs.sh
[atguigu@hadoop103 hadoop-2.7.2]$ sbin/start-yarn.sh

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

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -help rm

(2)-ls: 顯示目錄信息

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -ls /

(3)-mkdir:在HDFS上創建目錄

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -mkdir -p /sanguo/shuguo/

(4)-moveFromLocal:從本地系統中剪切粘貼文件到HDFS上(本地系統中不存在該文件)

[atguigu@hadoop102 hadoop-2.7.2]$ touch kongming.txt
[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -moveFromLocal ./kongming.txt /sanguo/shuguo/

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

[atguigu@hadoop102 hadoop-2.7.2]$ touch liubei.txt
[atguigu@hadoop102 hadoop-2.7.2]$ vim liubei.txt
輸入
san gu mao lu

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -appendToFile liubei.txt /sanguo/shuguo/kongming.txt

(6)-cat:顯示文件內容

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -cat /sanguo/shuguo/kongming.txt

(7)-chgrp 、-chmod、-chown:跟Linux文件系統中的用法一樣,修改文件所屬權限

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -chmod 666 /sanguo/shuguo/kongming.txt
[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -chown atguigu:atguigu /sanguo/shuguo/kongming.txt

(8)-copyFromLocal:從本地文件系統中拷貝文件到HDFS路徑中去(本地系統中還存在該文件)

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -copyFromLocal README.txt /

(9)-copyToLocal:從HDFS拷貝到本地系統中

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -copyToLocal /sanguo/shuguo/kongming.txt ./

(10)-cp:從HDFS的一個路徑拷貝到HDFS的另一個路徑(文件還在舊的HDFS中)

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -cp /sanguo/shuguo/kongming.txt /zhuge.txt

(11)-mv:在HDFS目錄中移動文件(文件不在舊的HDFS中,在新的HDFS中)

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -mv /zhuge.txt /sanguo/shuguo/

(12)-get:等同於copyToLocal,就是從HDFS下載文件到本地系統中

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -get /sanguo/shuguo/kongming.txt ./

(13)-getmerge:合並下載多個文件,比如HDFS的目錄 /user/atguigu/test/ 下有多個文件:log.1,log.2,log.3,……

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -getmerge /sanguo/shuguo/* ./zaiyiqi.txt

(14)-put:等同於copyFromLocal,就是從本地文件系統中拷貝文件到HDFS路徑中去

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -put ./zaiyiqi.txt /sanguo/shuguo/

(15)-tail:顯示一個文件的末尾幾行(因為日志文件一般是在文件的末尾不斷地追加,即監控新產生的數據變化)

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -tail /sanguo/shuguo/kongming.txt

(16)-rm:刪除文件或文件夾

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -rm /sanguo/shuguo/zaiyiqi.txt

(17)-rmdir:刪除空目錄

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -mkdir /test
[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -rmdir /test

(18)-du:統計文件夾的大小信息

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -du -s -h /user/atguigu/test/
2.7 K  /user/atguigu/test

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -du -h /user/atguigu/test/
1.3 K  /user/atguigu/test/README.txt
1.4 K  /user/atguigu/test/zaiyiqi.txt

(19)-setrep:設置HDFS中文件的副本數量

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -setrep 10 /kongming.txt

HDFS副本數量


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

第3章 HDFS客戶端操作(開發重點)

3.1 HDFS客戶端環境准備

1、根據自己電腦的操作系統拷貝對應的編譯后的hadoop jar包到非中文路徑(例如:D:\Develop\hadoop-2.7.2),如下圖所示。


2、配置HADOOP_HOME環境變量,如下圖所示:

3、配置Path環境變量,如下圖所示:

4、創建一個Maven工程HdfsClientDemo
5、導入相應的依賴坐標+日志添加
<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>RELEASE</version>
    </dependency>
        <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.8.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-common</artifactId>
        <version>2.7.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-client</artifactId>
        <version>2.7.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-hdfs</artifactId>
        <version>2.7.2</version>
    </dependency>
    <dependency>
        <groupId>jdk.tools</groupId>
        <artifactId>jdk.tools</artifactId>
        <version>1.8</version>
        <scope>system</scope>
        <systemPath>${JAVA_HOME}/lib/tools.jar</systemPath>
    </dependency>
</dependencies>

注意:如果Eclipse/Idea打印不出日志,在控制台上只顯示

1.log4j:WARN No appenders could be found for logger (org.apache.hadoop.util.Shell).  
2.log4j:WARN Please initialize the log4j system properly.  
3.log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.

需要在項目的src/main/resources目錄下,新建一個文件,命名為“log4j.properties”,在文件中填入以下內容:

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

6、創建包名:com.atguigu.hdfs
7、創建HdfsClient類

public class HdfsClient {
    /**
     * 測試創建多級文件夾:在hdfs系統上創建多級文件夾
     */

    @Test
    public void testMkdirs() throws IOException, InterruptedException, URISyntaxException {

        // 1、獲取hdfs文件系統對象
        Configuration configuration = new Configuration();
        // 配置在集群上運行
        configuration.set("fs.defaultFS""hdfs://hadoop102:9000");
        FileSystem fs = FileSystem.get(configuration);

        // 2 、創建目錄
        fs.mkdirs(new Path("/0529/dashen"));

        // 3 、關閉資源
        fs.close();
    }
}

8、執行程序
運行時需要配置用戶名稱,右鍵 -> Run Configurations,如下圖所示:


客戶端去操作HDFS時,是有一個用戶身份的。默認情況下,HDFS客戶端API會從JVM中獲取一個參數來作為自己的用戶身份:-DHADOOP_USER_NAME=atguigu,atguigu為用戶名稱。
9、另一種【配置在集群上運行】的方式,可以不用手動配置用戶名稱
public class HdfsClient {
    /**
     * 測試創建多級文件夾:在hdfs系統上創建多級文件夾
     */

    @Test
    public void testMkdirs() throws IOException, InterruptedException, URISyntaxException {

        // 1、 獲取hdfs文件系統對象
        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, "atguigu");

        // 2 、創建目錄
        fs.mkdirs(new Path("/0529/dashen"));

        // 3 、關閉資源
        fs.close();
    }
}

3.2 HDFS的API操作

3.2.1 HDFS文件上傳(測試參數優先級)

1、編寫源代碼

    /**
     * 測試文件上傳:從本地系統上傳文件至hdfs文件系統上
     */

    @Test
    public void testCopyFromLocalFile() throws IOException, InterruptedException, URISyntaxException {
        Configuration configuration = new Configuration();
        // 1、獲取hdfs文件系統
        FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "atguigu");
        configuration.set("dfs.replication""2");
        // 2、本地系統執行上傳文件操作
        fs.copyFromLocalFile(new Path("D:/temp/atguigu/0529/banzhang.txt"), new Path("/banzhang.txt"));
        // 3、關閉資源
        fs.close();
    }

2、在/HdfsClientDemo/src/main/resources/目錄下新建hdfs-site.xml文件,文件內容如下,然后再次執行上傳文件操作

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<configuration>
    <property>
        <name>dfs.replication</name>
        <!-- 設置副本的個數 -->
        <value>1</value>
    </property>
</configuration>

3.參數優先級
參數優先級排序:(1)客戶端代碼中設置的值 >(2)ClassPath下的用戶自定義配置文件設置的值 >(3)hdfs服務器的默認配置的值


效果如下圖所示:

3.2.2 HDFS文件下載

示例代碼如下:

    /**
     * 測試文件下載:將hdfs文件系統上的文件下載到本地系統上
     */

    @Test
    public void testCopyToLocalFile() throws IOException, InterruptedException, URISyntaxException {
        Configuration configuration = new Configuration();
        // 1、獲取hdfs文件系統對象
        FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "atguigu");
        // 2、執行下載文件操作
        // fs.copyToLocalFile(new Path("/banhua.txt"), new Path("D:/temp/atguigu/0529/banhua.txt"));
        // boolean delSrc 指是否將源文件刪除,默認值是false,表示不刪除源文件
        // Path src 指要下載的文件路徑
        // Path dst 指將文件下載到的路徑
        // boolean useRawLocalFileSystem 是否開啟文件校驗,即是否生成 .xxx.crc 檢驗文件,默認值是false,表示生成檢驗文件
        fs.copyToLocalFile(falsenew Path("/bancao.txt"), new Path("D:/temp/atguigu/0529/bancao.txt"), true);
        // 3、關閉資源
        fs.close();
    }

3.2.3 HDFS文件夾刪除

示例代碼如下:

    /**
     * 測試[文件夾/文件]刪除:將hdfs文件系統上的[文件夾/文件]刪除
     */

    @Test
    public void testDelete() throws IOException, InterruptedException, URISyntaxException {
        Configuration configuration = new Configuration();
        // 1、獲取hdfs文件系統對象
        FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "atguigu");
        // 2、執行刪除文件操作
        // boolean recursive 指的是遞歸的意思,設置成true,表示遞歸刪除文件夾
        fs.delete(new Path("/0529/"), true);
        // 3、關閉資源
        fs.close();
    }

3.2.4 HDFS文件名更改

示例代碼如下:

    /**
     * 文件名更改:將hdfs文件系統上的文件更改名稱
     */

    @Test
    public void testRename() throws IOException, InterruptedException, URISyntaxException {
        Configuration configuration = new Configuration();
        // 1、獲取hdfs文件系統對象
        FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "atguigu");
        // 2、執行文件名更改操作
        fs.rename(new Path("/banzhang.txt"), new Path("/yanjing.txt"));
        // 3、關閉資源
        fs.close();
    }

3.2.5 HDFS文件詳情查看

查看文件名稱、權限、長度、塊信息
示例代碼如下:

    /**
     * 查看文件詳情
     */

    @Test
    public void testListFiles() throws IOException, InterruptedException, URISyntaxException {
        Configuration configuration = new Configuration();
        // 1、獲取hdfs文件系統對象
        FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "atguigu");
        // 2、獲取文件詳情
        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.getPermission()); // 權限
            System.out.println(fileStatus.getLen()); // 長度
            System.out.println(fileStatus.getGroup()); // 分組

            // 獲取存儲的塊信息
            BlockLocation[] blockLocations = fileStatus.getBlockLocations();
            for (BlockLocation blockLocation : blockLocations) {
                // 獲取塊存儲的主機節點
                String[] hosts = blockLocation.getHosts();
                for (String host : hosts) {
                    System.out.println(host);
                }
            }
            System.out.println("---------------------");
        }
        // 3、關閉資源
        fs.close();
    }

3.2.6 HDFS文件和文件夾判斷

示例代碼如下:

    /**
     * 判斷是文件還是文件夾
     */

    @Test
    public void testListStatus() throws IOException, InterruptedException, URISyntaxException {
        Configuration configuration = new Configuration();
        // 1、獲取hdfs文件系統對象
        FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "atguigu");
        // 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();
    }

3.3 HDFS的I/O流操作(自定義框架使用)

  上面我們學的API操作HDFS系統都是框架封裝好的。那么如果我們想自己實現上述API的操作該怎么實現呢?
  我們可以采用IO流的方式實現數據的上傳和下載。

3.3.1 HDFS文件上傳

1、需求:把本地D:\temp\atguigu\0529\上的banhua.txt文件上傳到HDFS根目錄
2、編寫代碼

    /**
     * 把本地 D:\temp\atguigu\0529\ 上的banhua.txt文件上傳到HDFS根目錄
     */

    @Test
    public void putFileToHDFS() throws IOException, InterruptedException, URISyntaxException {
        // 1、獲取hdfs文件系統對象
        Configuration configuration = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "atguigu");

        // 2、創建輸入流
        FileInputStream fis = new FileInputStream(new File("D:/temp/atguigu/0529/banhua.txt"));

        // 3、創建輸出流
        FSDataOutputStream fos = fs.create(new Path("/banzhang.txt"));

        // 4、流對拷
        IOUtils.copyBytes(fis, fos, configuration);

        // 5、關閉資源
        IOUtils.closeStream(fos);
        IOUtils.closeStream(fis);
        fs.close();
    }

3.3.2 HDFS文件下載

1、需求:從HDFS上下載banhua.txt文件到本地D:\temp\atguigu\0529\
2、編寫代碼

     * 從HDFS上下載banhua.txt文件到本地 D:\temp\atguigu\0529\ 上
     */
    @Test
    public void getFileFromHDFS() throws IOException, InterruptedException, URISyntaxException {
        // 1、獲取hdfs文件系統對象
        Configuration configuration = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "atguigu");

        // 2、創建輸入流
        FSDataInputStream fis = fs.open(new Path("/banhua.txt"));

        // 3、創建輸出流
        FileOutputStream fos = new FileOutputStream(new File("D:/temp/atguigu/0529/banhua.txt"));

        // 4、流對拷
        IOUtils.copyBytes(fis, fos, configuration);

        // 5、關閉資源
        IOUtils.closeStream(fos);
        IOUtils.closeStream(fis);
        fs.close();
    }

3.3.3 定位文件讀取

1、需求:分塊讀取HDFS上的大文件,比如根目錄下的/hadoop-2.7.2.tar.gz
2、編寫代碼
(1)下載第一塊

    /**
     * 分塊讀取HDFS上的大文件,比如根目錄下的/hadoop-2.7.2.tar.gz,下載第一塊
     */

    @Test
    public void readFileSeek1() throws IOException, InterruptedException, URISyntaxException {
        // 1、獲取hdfs文件系統對象
        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、創建輸出流
        FileOutputStream fos = new FileOutputStream(new File("D:/temp/atguigu/0529/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();
    }

(2)下載第二塊

    /**
     * 分塊讀取HDFS上的大文件,比如根目錄下的/hadoop-2.7.2.tar.gz,下載第二塊
     */

    @Test
    public void readFileSeek2() throws IOException, InterruptedException, URISyntaxException {
        // 1、獲取hdfs文件系統對象
        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("D:/temp/atguigu/0529/hadoop-2.7.2.tar.gz.part2"));

        // 5、流的對拷
        IOUtils.copyBytes(fis, fos, configuration);

        // 6、關閉資源
        IOUtils.closeStream(fis);
        IOUtils.closeStream(fos);
        fs.close();
    }

(3)合並文件
在Window命令窗口中進入到目錄 D:\temp\atguigu\0529\,然后執行如下命令,對數據進行合並

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包非常完整。

第4章 HDFS的數據流(面試重點)

4.1 HDFS寫數據流程

4.1.1 剖析文件寫入

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步)。

4.1.2 網絡拓撲-節點距離計算

  在HDFS寫數據的過程中,NameNode會選擇距離待上傳數據最近距離的DataNode接收數據。那么這個最近距離怎么計算呢?
  節點距離:兩個節點到達最近的共同祖先的距離總和。
網絡拓撲概念:


例如,假設有數據中心d1機架r1中的節點n1。該節點可以表示為/d1/r1/n1。利用這種標記,這里給出四種距離描述,如上圖所示。
大家算一算每兩個節點之間的距離,如下圖所示。

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

1、官方ip地址
機架感知說明:http://hadoop.apache.org/docs/r2.7.2/hadoop-project-dist/hadoop-hdfs/HdfsDesign.html#Data_Replication

For the common case, when the replication factor is three, HDFS’s placement policy is to put one replica on one node in the local rack, another on a different node in the local rack, and the last on a different node in a different rack. This policy cuts the inter-rack write traffic which generally improves write performance. The chance of rack failure is far less than that of node failure; this policy does not impact data reliability and availability guarantees. However, it does reduce the aggregate network bandwidth used when reading data since a block is placed in only two unique racks rather than three. With this policy, the replicas of a file do not evenly distribute across the racks. One third of replicas are on one node, two thirds of replicas are on one rack, and the other third are evenly distributed across the remaining racks. This policy improves write performance without compromising data reliability or read performance.

翻譯如下:

對於常見情況,當復制因子為3時,HDFS的放置策略是將一個副本放在本地機架中的一個節點上,另一個放在本地機架中的另一個節點上,將最后一個放在另一個機架中的另一個節點上。此策略可以減少機架間寫入流量,從而提高寫入性能。機架故障的可能性遠小於節點故障的可能性; 此策略不會影響數據可靠性和可用性保證。但是,它確實減少了讀取數據時使用的聚合網絡帶寬,因為塊只放在兩個唯一的機架而不是三個。使用此策略時,文件的副本不會均勻分布在機架上。三分之一的副本位於一個節點上,三分之二的副本位於一個機架上,另外三個副本均勻分布在剩余的機架上。

2、Hadoop2.7.2副本節點選擇

4.2 HDFS讀數據流程

HDFS的讀數據流程,如下圖所示。


詳解如下:
  • 1)客戶端通過Distributed FileSystem向NameNode請求下載文件,NameNode通過查詢元數據,找到文件塊所在的DataNode地址。
  • 2)挑選一台DataNode(就近原則,然后隨機)服務器,請求讀取數據。
  • 3)DataNode開始傳輸數據給客戶端(從磁盤里面讀取數據輸入流,以Packet為單位來做校驗)。
  • 4)客戶端以Packet為單位接收,先在本地緩存,然后寫入目標文件。

第5章 NameNode和SecondaryNameNode(面試開發重點)

5.1 NN和2NN工作機制

思考:NameNode中的元數據是存儲在哪里的?
  首先,我們做個假設,如果存儲在NameNode節點的磁盤中,因為經常需要進行隨機訪問,還有響應客戶請求,必然是效率過低。因此,元數據需要存放在內存中。但如果只存在內存中,一旦斷電,元數據丟失,整個集群就無法工作了。因此產生在磁盤中備份元數據的FsImage。
  這樣又會帶來新的問題,當在內存中的元數據更新時,如果同時更新FsImage,就會導致效率過低,但如果不更新,就會發生一致性問題,一旦NameNode節點斷電,就會產生數據丟失。因此,引入Edits文件(只進行追加操作,效率很高)。每當元數據有更新或者添加元數據時,修改內存中的元數據並追加到Edits中。這樣,一旦NameNode節點斷電,可以通過FsImage和Edits的合並,合成元數據。
  但是,如果長時間添加數據到Edits中,會導致該文件數據過大,效率降低,而且一旦斷電,恢復元數據需要的時間過長。因此,需要定期進行FsImage和Edits的合並,如果這個操作由NameNode節點完成,又會效率過低。因此,引入一個新的節點SecondaryNamenode,專門用於FsImage和Edits的合並。
  NN和2NN工作機制,如下圖所示。


詳解如下:
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中。

 

5.2 Fsimage和Edits解析

1、概念

2、oiv查看Fsimage文件
(1)查看oiv和oev命令

[atguigu@hadoop102 current]$ hdfs
Usage: hdfs [--config confdir] [--loglevel loglevel] COMMAND
       where COMMAND is one of:
  dfs                  run a filesystem command on the file systems supported in Hadoop.
  classpath            prints the classpath
  namenode -format     format the DFS filesystem
  secondarynamenode    run the DFS secondary namenode
  namenode             run the DFS namenode
  journalnode          run the DFS journalnode
  zkfc                 run the ZK Failover Controller daemon
  datanode             run a DFS datanode
  dfsadmin             run a DFS admin client
  haadmin              run a DFS HA admin client
  fsck                 run a DFS filesystem checking utility
  balancer             run a cluster balancing utility
  jmxget               get JMX exported values from NameNode or DataNode.
  mover                run a utility to move block replicas across
                       storage types
  oiv                  apply the offline fsimage viewer to an fsimage
  oiv_legacy           apply the offline fsimage viewer to an legacy fsimage
  oev                  apply the offline edits viewer to an edits file
  fetchdt              fetch a delegation token from the NameNode
  getconf              get config values from configuration
  groups               get the groups which users belong to
  snapshotDiff         diff two snapshots of a directory or diff the
                       current directory contents with a snapshot
  lsSnapshottableDir   list all snapshottable dirs owned by the current user
                        Use -help to see options
  portmap              run a portmap service
  nfs3                 run an NFS version 3 gateway
  cacheadmin           configure the HDFS cache
  crypto               configure HDFS encryption zones
  storagepolicies      list/get/set block storage policies
  version              print the version

Most commands print help when invoked w/o parameters.
[atguigu@hadoop102 current]$ 

(2)基本語法
  hdfs oiv -p 文件類型 -i 鏡像文件 -o 轉換后文件輸出路徑
(3)案例實操

[atguigu@hadoop102 current]$ pwd
/opt/module/hadoop-2.7.2/data/tmp/dfs/name/current
[atguigu@hadoop102 current]$ hdfs oiv -p XML -i fsimage_0000000000000000124 -o fsimage.xml
[atguigu@hadoop102 current]$ cat fsimage.xml 

將顯示的xml文件內容拷貝到Eclipse中創建的xml文件中,並格式化。部分顯示結果如下。

<inode>
    <id>16385</id>
    <type>DIRECTORY</type>
    <name></name>
    <mtime>1549193480818</mtime>
    <permission>atguigu:supergroup:rwxr-xr-x</permission>
    <nsquota>9223372036854775807</nsquota>
    <dsquota>-1</dsquota>
</inode>
<inode>
    <id>16386</id>
    <type>FILE</type>
    <name>wc.input</name>
    <replication>3</replication>
    <mtime>1549109263472</mtime>
    <atime>1549191451377</atime>
    <perferredBlockSize>134217728</perferredBlockSize>
    <permission>atguigu:supergroup:rw-r--r--</permission>
    <blocks>
        <block>
            <id>1073741825</id>
            <genstamp>1001</genstamp>
            <numBytes>43</numBytes>
        </block>
    </blocks>
</inode>
<inode>
    <id>16394</id>
    <type>FILE</type>
    <name>kongming.txt</name>
    <replication>10</replication>
    <mtime>1549172409335</mtime>
    <atime>1549172409063</atime>
    <perferredBlockSize>134217728</perferredBlockSize>
    <permission>atguigu:supergroup:rw-r--r--</permission>
    <blocks>
        <block>
            <id>1073741832</id>
            <genstamp>1009</genstamp>
            <numBytes>28</numBytes>
        </block>
    </blocks>
</inode>
<inode>
    <id>16398</id>
    <type>FILE</type>
    <name>yanjing.txt</name>
    <replication>3</replication>
    <mtime>1549182842815</mtime>
    <atime>1549191453687</atime>
    <perferredBlockSize>134217728</perferredBlockSize>
    <permission>atguigu:supergroup:rw-r--r--</permission>
    <blocks>
        <block>
            <id>1073741833</id>
            <genstamp>1010</genstamp>
            <numBytes>29</numBytes>
        </block>
    </blocks>
</inode>
<inode>
    <id>16399</id>
    <type>FILE</type>
    <name>banhua.txt</name>
    <replication>1</replication>
    <mtime>1549183347279</mtime>
    <atime>1549191440485</atime>
    <perferredBlockSize>134217728</perferredBlockSize>
    <permission>atguigu:supergroup:rw-r--r--</permission>
    <blocks>
        <block>
            <id>1073741834</id>
            <genstamp>1011</genstamp>
            <numBytes>29</numBytes>
        </block>
    </blocks>
</inode>
<inode>
    <id>16400</id>
    <type>FILE</type>
    <name>bancao.txt</name>
    <replication>2</replication>
    <mtime>1549183571406</mtime>
    <atime>1549191438143</atime>
    <perferredBlockSize>134217728</perferredBlockSize>
    <permission>atguigu:supergroup:rw-r--r--</permission>
    <blocks>
        <block>
            <id>1073741835</id>
            <genstamp>1012</genstamp>
            <numBytes>29</numBytes>
        </block>
    </blocks>
</inode>
<inode>
    <id>16401</id>
    <type>FILE</type>
    <name>banzhang.txt</name>
    <replication>1</replication>
    <mtime>1549192955364</mtime>
    <atime>1549192955243</atime>
    <perferredBlockSize>134217728</perferredBlockSize>
    <permission>atguigu:supergroup:rw-r--r--</permission>
    <blocks>
        <block>
            <id>1073741836</id>
            <genstamp>1013</genstamp>
            <numBytes>12</numBytes>
        </block>
    </blocks>
</inode>
<inode>
    <id>16402</id>
    <type>FILE</type>
    <name>hadoop-2.7.2.tar.gz</name>
    <replication>3</replication>
    <mtime>1549193480811</mtime>
    <atime>1549193471067</atime>
    <perferredBlockSize>134217728</perferredBlockSize>
    <permission>atguigu:supergroup:rw-r--r--</permission>
    <blocks>
        <block>
            <id>1073741837</id>
            <genstamp>1014</genstamp>
            <numBytes>134217728</numBytes>
        </block>
        <block>
            <id>1073741838</id>
            <genstamp>1015</genstamp>
            <numBytes>63439959</numBytes>
        </block>
    </blocks>
</inode>

思考:可以看出,Fsimage中沒有記錄塊所對應DataNode,為什么?
答:是因為在集群啟動后,要求DataNode上報數據塊信息,並間隔一段時間后再次上報。所以我們要先啟動集群。

3、oev查看Edits文件
(1)基本語法
  hdfs oev -p 文件類型 -i 編輯日志 -o 轉換后文件輸出路徑
(2)案例實操

[atguigu@hadoop102 current]$ hdfs oev -p XML -i edits_0000000000000000103-0000000000000000108 -o edits.xml
[atguigu@hadoop102 current]$ cat edits.xml

將顯示的xml文件內容拷貝到Eclipse中創建的xml文件中,並格式化。顯示結果如下。

<?xml version="1.0" encoding="UTF-8"?>
<EDITS>
    <EDITS_VERSION>-63</EDITS_VERSION>
    <RECORD>
        <OPCODE>OP_START_LOG_SEGMENT</OPCODE>
        <DATA>
            <TXID>103</TXID>
        </DATA>
    </RECORD>
    <RECORD>
        <OPCODE>OP_TIMES</OPCODE>
        <DATA>
            <TXID>104</TXID>
            <LENGTH>0</LENGTH>
            <PATH>/bancao.txt</PATH>
            <MTIME>-1</MTIME>
            <ATIME>1549191438143</ATIME>
        </DATA>
    </RECORD>
    <RECORD>
        <OPCODE>OP_TIMES</OPCODE>
        <DATA>
            <TXID>105</TXID>
            <LENGTH>0</LENGTH>
            <PATH>/banhua.txt</PATH>
            <MTIME>-1</MTIME>
            <ATIME>1549191440485</ATIME>
        </DATA>
    </RECORD>
    <RECORD>
        <OPCODE>OP_TIMES</OPCODE>
        <DATA>
            <TXID>106</TXID>
            <LENGTH>0</LENGTH>
            <PATH>/wc.input</PATH>
            <MTIME>-1</MTIME>
            <ATIME>1549191451377</ATIME>
        </DATA>
    </RECORD>
    <RECORD>
        <OPCODE>OP_TIMES</OPCODE>
        <DATA>
            <TXID>107</TXID>
            <LENGTH>0</LENGTH>
            <PATH>/yanjing.txt</PATH>
            <MTIME>-1</MTIME>
            <ATIME>1549191453687</ATIME>
        </DATA>
    </RECORD>
    <RECORD>
        <OPCODE>OP_END_LOG_SEGMENT</OPCODE>
        <DATA>
            <TXID>108</TXID>
        </DATA>
    </RECORD>
</EDITS>

思考:NameNode如何確定下次開機啟動的時候合並哪些Edits?
答:根據seen_txid里面記錄最新的Fsimage(鏡像文件)的值去合並Edits(編輯日志)

5.3 CheckPoint時間設置

(1)通常情況下,SecondaryNameNode每隔一小時執行一次。
[hdfs-default.xml]

<property>
    <name>dfs.namenode.checkpoint.period</name>
    <value>3600</value>
    <description>SecondaryNameNode每隔一小時執行一次</description>
</property>

(2)當操作次數達到1百萬時,SecondaryNameNode執行一次。

<property>
    <name>dfs.namenode.checkpoint.txns</name>
    <value>1000000</value>
    <description>操作動作次數</description>
</property>

(3)一分鍾檢查一次操作次數。

<property>
    <name>dfs.namenode.checkpoint.check.period</name>
    <value>60</value>
    <description>1分鍾檢查一次操作次數</description>
</property >

該文件截圖如下:

5.4 NameNode故障處理(開發重點:偏運維)

  NameNode故障后,可以采用如下兩種方法恢復數據。

方法一:將SecondaryNameNode中數據拷貝到NameNode存儲數據的目錄。
1、kill -9 NameNode進程
2、刪除NameNode存儲的數據目錄中的數據(目錄位置:/opt/module/hadoop-2.7.2/data/tmp/dfs/name/)

[atguigu@hadoop102 hadoop-2.7.2]$ rm -rf /opt/module/hadoop-2.7.2/data/tmp/dfs/name/*

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

[atguigu@hadoop102 name]$ pwd
/opt/module/hadoop-2.7.2/data/tmp/dfs/name
[atguigu@hadoop102 name]$ scp -r atguigu@hadoop104:/opt/module/hadoop-2.7.2/data/tmp/dfs/namesecondary/* ./

4、重新啟動NameNode

[atguigu@hadoop102 hadoop-2.7.2]$ sbin/hadoop-daemon.sh start namenode

方法二:使用-importCheckpoint選項啟動NameNode守護進程,從而將SecondaryNameNode中數據拷貝到NameNode目錄中。
1、修改hdfs-site.xml中的內容,新增如下,然后分發到其他節點

[atguigu@hadoop102 hadoop-2.7.2]$ vim etc/hadoop/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>

[atguigu@hadoop102 hadoop-2.7.2]$ xsync etc/hadoop/

2、kill -9 NameNode進程
3、刪除NameNode存儲的數據目錄中的數據(目錄位置:/opt/module/hadoop-2.7.2/data/tmp/dfs/name/)

[atguigu@hadoop102 hadoop-2.7.2]$ rm -rf /opt/module/hadoop-2.7.2/data/tmp/dfs/name/*

4、如果SecondaryNameNode不和NameNode在一個主機節點上,需要將SecondaryNameNode存儲數據的目錄namesecondary拷貝到NameNode存儲數據的平級目錄name,並刪除in_use.lock文件

[atguigu@hadoop102 dfs]$ pwd
/opt/module/hadoop-2.7.2/data/tmp/dfs
[atguigu@hadoop102 dfs]$ ll
總用量 8
drwx------. 3 atguigu atguigu 4096 2月   4 10:37 data
drwxrwxr-x. 2 atguigu atguigu 4096 2月   4 10:59 name
[atguigu@hadoop102 dfs]$ scp -r atguigu@hadoop104:/opt/module/hadoop-2.7.2/data/tmp/dfs/namesecondary/ ./
[atguigu@hadoop102 dfs]$ ll
總用量 12
drwx------. 3 atguigu atguigu 4096 2月   4 10:37 data
drwxrwxr-x. 2 atguigu atguigu 4096 2月   4 10:59 name
drwxrwxr-x. 3 atguigu atguigu 4096 2月   4 11:04 namesecondary
[atguigu@hadoop102 dfs]$
[atguigu@hadoop102 dfs]$ rm -rf namesecondary/in_use.lock 

5、導入檢查點數據(設置的是2分鍾,等待一會ctrl+c結束掉)

[atguigu@hadoop102 hadoop-2.7.2]$ bin/hdfs namenode -importCheckpoint

6、啟動NameNode

[atguigu@hadoop102 hadoop-2.7.2]$ sbin/hadoop-daemon.sh start namenode

方式二比方式一要檢查的東西多一些,方式一比較直接。

5.5 集群安全模式

1、概述

2、基本語法
集群處於安全模式,不能執行重要操作(寫操作)。集群啟動完成后,自動退出安全模式。
(1)bin/hdfs dfsadmin -safemode get (功能描述:[查看/獲取]安全模式狀態)
(2)bin/hdfs dfsadmin -safemode enter (功能描述:[進入/開啟]安全模式狀態)
(3)bin/hdfs dfsadmin -safemode leave (功能描述:[離開]安全模式狀態)
(4)bin/hdfs dfsadmin -safemode wait (功能描述:[等待]安全模式狀態)
演示如下圖所示:

3、案例
模擬等待安全模式
(1)查看當前模式
(2)先進入安全模式
(3)創建並執行下面的腳本
在/opt/module/hadoop-2.7.2路徑上,編輯一個腳本safemode.sh

[atguigu@hadoop102 hadoop-2.7.2]$ bin/hdfs dfsadmin -safemode get
Safe mode is OFF
[atguigu@hadoop102 hadoop-2.7.2]$ bin/hdfs dfsadmin -safemode enter
Safe mode is ON
[atguigu@hadoop102 hadoop-2.7.2]$ touch safemode.sh
[atguigu@hadoop102 hadoop-2.7.2]$ vim safemode.sh 
[atguigu@hadoop102 hadoop-2.7.2]$ cat safemode.sh 
#!/bin/bash
hdfs dfsadmin -safemode wait
hdfs dfs -put /opt/module/hadoop-2.7.2/README.txt /
[atguigu@hadoop102 hadoop-2.7.2]$ bash ./safemode.sh 

(4)再打開一個窗口,執行該腳本

[atguigu@hadoop102 hadoop-2.7.2]$ bin/hdfs dfsadmin -safemode leave

(5)觀察
  (a)再觀察上一個窗口
    Safe mode is OFF
  (b)HDFS集群上已經有上傳的數據了。

5.6 NameNode多目錄配置

1、NameNode的本地目錄可以配置成多個,且每個目錄存放內容相同,增加了可靠性。
2、具體配置如下:
(1)在hdfs-site.xml文件中增加如下內容,保存退出后,然后進行分發操作

[atguigu@hadoop102 hadoop-2.7.2]$ vim etc/hadoop/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>

[atguigu@hadoop102 hadoop-2.7.2]$ xsync etc/hadoop/

(2)停止集群,刪除data和logs中所有數據。

[atguigu@hadoop102 hadoop-2.7.2]$ sbin/stop-dfs.sh         關閉全部 NameNode 和 DataNode 
[atguigu@hadoop103 hadoop-2.7.2]$ sbin/stop-yarn.sh        關閉全部 ResourceManager 和 NodeManager 

[atguigu@hadoop102 hadoop-2.7.2]$ rm -rf data/ logs/
[atguigu@hadoop103 hadoop-2.7.2]$ rm -rf data/ logs/
[atguigu@hadoop104 hadoop-2.7.2]$ rm -rf data/ logs/

(3)格式化集群並啟動。

[atguigu@hadoop102 hadoop-2.7.2]$ bin/hdfs namenode –format
[atguigu@hadoop102 hadoop-2.7.2]$ sbin/start-dfs.sh      開啟全部 NameNode 和 DataNode 

(4)查看結果

[atguigu@hadoop102 dfs]$ ll
總用量 8
drwxrwxr-x. 3 atguigu atguigu 4096 2月   4 12:50 name1
drwxrwxr-x. 3 atguigu atguigu 4096 2月   4 12:50 name2
[atguigu@hadoop102 dfs]$ cd name1/
[atguigu@hadoop102 name1]$ cd current/
[atguigu@hadoop102 current]$ ll
總用量 16
-rw-rw-r--. 1 atguigu atguigu 354 2月   4 12:50 fsimage_0000000000000000000
-rw-rw-r--. 1 atguigu atguigu  62 2月   4 12:50 fsimage_0000000000000000000.md5
-rw-rw-r--. 1 atguigu atguigu   2 2月   4 12:50 seen_txid
-rw-rw-r--. 1 atguigu atguigu 205 2月   4 12:50 VERSION
[atguigu@hadoop102 current]$ cd ..
[atguigu@hadoop102 name1]$ cd ..
[atguigu@hadoop102 dfs]$ cd name2/
[atguigu@hadoop102 name2]$ cd current/
[atguigu@hadoop102 current]$ ll
總用量 16
-rw-rw-r--. 1 atguigu atguigu 354 2月   4 12:50 fsimage_0000000000000000000
-rw-rw-r--. 1 atguigu atguigu  62 2月   4 12:50 fsimage_0000000000000000000.md5
-rw-rw-r--. 1 atguigu atguigu   2 2月   4 12:50 seen_txid
-rw-rw-r--. 1 atguigu atguigu 205 2月   4 12:50 VERSION
[atguigu@hadoop102 current]$ cd ..
[atguigu@hadoop102 name2]$ cd ..
[atguigu@hadoop102 dfs]$ ll
總用量 12
drwx------. 3 atguigu atguigu 4096 2月   4 12:53 data
drwxrwxr-x. 3 atguigu atguigu 4096 2月   4 12:53 name1
drwxrwxr-x. 3 atguigu atguigu 4096 2月   4 12:53 name2
[atguigu@hadoop102 dfs]$ ll name1/current/
總用量 1052
-rw-rw-r--. 1 atguigu atguigu      42 2月   4 12:54 edits_0000000000000000001-0000000000000000002
-rw-rw-r--. 1 atguigu atguigu 1048576 2月   4 12:55 edits_inprogress_0000000000000000003
-rw-rw-r--. 1 atguigu atguigu     354 2月   4 12:50 fsimage_0000000000000000000
-rw-rw-r--. 1 atguigu atguigu      62 2月   4 12:50 fsimage_0000000000000000000.md5
-rw-rw-r--. 1 atguigu atguigu     354 2月   4 12:54 fsimage_0000000000000000002
-rw-rw-r--. 1 atguigu atguigu      62 2月   4 12:54 fsimage_0000000000000000002.md5
-rw-rw-r--. 1 atguigu atguigu       2 2月   4 12:54 seen_txid
-rw-rw-r--. 1 atguigu atguigu     205 2月   4 12:50 VERSION
[atguigu@hadoop102 dfs]$ ll name2/current/
總用量 1052
-rw-rw-r--. 1 atguigu atguigu      42 2月   4 12:54 edits_0000000000000000001-0000000000000000002
-rw-rw-r--. 1 atguigu atguigu 1048576 2月   4 12:55 edits_inprogress_0000000000000000003
-rw-rw-r--. 1 atguigu atguigu     354 2月   4 12:50 fsimage_0000000000000000000
-rw-rw-r--. 1 atguigu atguigu      62 2月   4 12:50 fsimage_0000000000000000000.md5
-rw-rw-r--. 1 atguigu atguigu     354 2月   4 12:54 fsimage_0000000000000000002
-rw-rw-r--. 1 atguigu atguigu      62 2月   4 12:54 fsimage_0000000000000000002.md5
-rw-rw-r--. 1 atguigu atguigu       2 2月   4 12:54 seen_txid
-rw-rw-r--. 1 atguigu atguigu     205 2月   4 12:50 VERSION
[atguigu@hadoop102 dfs]$ 


免責聲明!

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



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