Hadoop之HDFS

目錄
一 HDFS概念
????1.概念
????2.組成
????3 HDFS 文件塊大小
二.HDFS命令行操作
????1.基本語法
????2.參數(shù)大全
????3.常用命令
三.HDFS客戶端操作
????3.1 IDEA環(huán)境準(zhǔn)備
????3.2 通過API操作HDFS
??????3.2.1 HDFS獲取文件系統(tǒng)
??????3.2.2 HDFS文件上傳
??????3.2.3 HDFS文件下載
??????3.2.4 HDFS目錄創(chuàng)建
??????3.2.5 HDFS文件夾刪除
??????3.2.6 HDFS文件名更改
??????3.2.7 HDFS文件詳情查看
??????3.2.8 HDFS文件和文件夾判斷
????3.3 通過IO流操作HDFS
??????3.3.1 HDFS文件上傳
??????3.3.2 HDFS文件下載
??????3.3.3 定位文件讀取
四 HDFS的數(shù)據(jù)流
????4.1 HDFS寫數(shù)據(jù)流程
????4.2 HDFS讀數(shù)據(jù)流程
????4.3 一致性模型
五. NameNode工作機(jī)制
????5.1 NameNode&Secondary NameNode工作機(jī)制
????5.2 鏡像文件和編輯日志文件
????5.3 滾動(dòng)編輯日志
????5.4 namenode版本號(hào)
????5.5 SecondaryNameNode目錄結(jié)構(gòu)
????5.6 集群安全模式操作
????5.7 Namenode多目錄配置
六.DataNode工作機(jī)制
????6.1 NameNode & DataNode工作機(jī)制
????6.2 數(shù)據(jù)完整性
????6.3 掉線時(shí)限參數(shù)設(shè)置
????6.4 DataNode的目錄結(jié)構(gòu)
????6.5 Datanode多目錄配置
七 HDFS其他功能
????7.1 集群間數(shù)據(jù)拷貝
????7.2 Hadoop存檔
????7.3 快照管理
????7.4 回收站

一 HDFS概念

1.概念

HDFS,它是一個(gè)文件系統(tǒng),全稱:Hadoop Distributed File System,用于存儲(chǔ)文件通過目錄樹來定位文件;其次,它是分布式的,由很多服務(wù)器聯(lián)合起來實(shí)現(xiàn)其功能,集群中的服務(wù)器有各自的角色。

2.組成

(1)HDFS集群包括,NameNode和DataNode以及Secondary Namenode。

(2)NameNode負(fù)責(zé)管理整個(gè)文件系統(tǒng)的元數(shù)據(jù),以及每一個(gè)路徑(文件)所對(duì)應(yīng)的數(shù)據(jù)塊信息。

(3)DataNode 負(fù)責(zé)管理用戶的文件數(shù)據(jù)塊,每一個(gè)數(shù)據(jù)塊都可以在多個(gè)datanode上存儲(chǔ)多個(gè)副本。

(4)Secondary NameNode用來監(jiān)控HDFS狀態(tài)的輔助后臺(tái)程序,每隔一段時(shí)間獲取HDFS元數(shù)據(jù)的快照。

3 HDFS 文件塊大小

????HDFS中的文件在物理上是分塊存儲(chǔ)(block),塊的大小可以通過配置參數(shù)(dfs.blocksize)來規(guī)定,默認(rèn)大小在hadoop2.x版本中是128M,老版本中是64M
????HDFS的塊比磁盤的塊大,其目的是為了最小化尋址開銷。如果塊設(shè)置得足夠大,從磁盤傳輸數(shù)據(jù)的時(shí)間會(huì)明顯大于定位這個(gè)塊開始位置所需的時(shí)間。因而,傳輸一個(gè)由多個(gè)塊組成的文件的時(shí)間取決于磁盤傳輸速率。
????如果尋址時(shí)間約為10ms,而傳輸速率為100MB/s,為了使尋址時(shí)間僅占傳輸時(shí)間的1%,我們要將塊大小設(shè)置約為100MB。默認(rèn)的塊大小128MB。
????塊的大小:10ms100100M/s = 100M

HDFS文件快的大小

二.HDFS命令行操作:

1.基本語法
bin/hadoop fs 具體命令
2.參數(shù)大全
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:輸出這個(gè)命令參數(shù)

bin/hdfs dfs -help rm

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

hadoop fs -ls /

(3)-mkdir:在hdfs上創(chuàng)建目錄

hadoop fs  -mkdir  -p  /hdfs路徑

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

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

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

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

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

hadoop fs -cat /hdfs路徑

(7)-tail -f:監(jiān)控文件

hadoop  fs  -tail -f /hdfs路徑

(8)-chmod、-chown:linux文件系統(tǒng)中的用法一樣,修改文件所屬權(quán)限

hadoop  fs  -chmod  777  /hdfs路徑
hadoop  fs  -chown  someuser:somegrp   /hdfs路徑

(9)-cp :從hdfs的一個(gè)路徑拷貝到hdfs的另一個(gè)路徑

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

(10)-mv:在hdfs目錄中移動(dòng)/重命名 文件

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

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

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

(12)-getmerge :合并下載多個(gè)文到linux本地,比如hdfs的目錄 /aaa/下有多個(gè)文件: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 :統(tǒng)計(jì)文件系統(tǒng)的可用空間信息

hadoop  fs  -df  -h  /hdfs路徑

(16)-du統(tǒng)計(jì)文件夾的大小信息

hadoop fs -du -s -h /hdfs路徑

(17)-count:統(tǒng)計(jì)一個(gè)指定目錄下的文件節(jié)點(diǎn)數(shù)量

hadoop fs -count /aaa/
hadoop fs -count /hdfs路徑

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

hadoop fs -setrep 3 / hdfs路徑

這里設(shè)置的副本數(shù)只是記錄在namenode的元數(shù)據(jù)中,是否真的會(huì)有這么多副本,還得看datanode的數(shù)量。因?yàn)槟壳爸挥?臺(tái)設(shè)備,最多也就3個(gè)副本,只有節(jié)點(diǎn)數(shù)的增加到10臺(tái)時(shí),副本數(shù)才能達(dá)到10。

三.HDFS客戶端操作

3.1 IDEA環(huán)境準(zhǔn)備

1.修改$MAVEN_HOME/conf/settings.xml
  <!--本地倉庫所在位置-->
<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>
2.Maven準(zhǔn)備,在在項(xiàng)目文件pom.xml文件中添加
<dependencies>
        <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>
   </dependencies>

3.2 通過API操作HDFS

3.2.1 HDFS獲取文件系統(tǒng)
(1)詳細(xì)代碼:

     /**
     * 打印本地hadoop地址值
     * IO的方式寫代碼
     */
    @Test
    public void intiHDFS() throws IOException {
        //F2 可以快速的定位錯(cuò)誤
        // alt + enter自動(dòng)找錯(cuò)誤
        //1.創(chuàng)建配信信息對(duì)象 ctrl + alt + v  后推前  ctrl + shitl + enter 補(bǔ)全
        Configuration conf = new Configuration();

        //2.獲取文件系統(tǒng)
        FileSystem fs = FileSystem.get(conf);

        //3.打印文件系統(tǒng)
        System.out.println(fs.toString());
    }

3.2.2 HDFS文件上傳
(1)詳細(xì)代碼

    /**
     * 上傳代碼
     * 注意:如果上傳的內(nèi)容大于128MB,則是2塊
     */
    @Test
    public void putFileToHDFS() throws Exception {
        //注:import org.apache.hadoop.conf.Configuration;
        //ctrl + alt + v 推動(dòng)出對(duì)象
        //1.創(chuàng)建配置信息對(duì)象
        Configuration conf = new Configuration();

        //2.設(shè)置部分參數(shù)
        conf.set("dfs.replication","2");

        //3.找到HDFS的地址
        FileSystem fs = FileSystem.get(new URI("hdfs://bigdata111:9000"), conf, "root");

        //4.上傳本地Windows文件的路徑
        Path src = new Path("D:\\hadoop-2.7.2.rar");

        //5.要上傳到HDFS的路徑
        Path dst = new Path("hdfs://bigdata111:9000/Andy");

        //6.以拷貝的方式上傳,從src -> dst
        fs.copyFromLocalFile(src,dst);

        //7.關(guān)閉
        fs.close();

        System.out.println("上傳成功");
}

3.2.3 HDFS文件下載
(1)詳細(xì)代碼:

     /**
     * hadoop fs -get /HDFS文件系統(tǒng)
     * @throws Exception
     */
    @Test
    public void getFileFromHDFS() throws Exception {
        //1.創(chuàng)建配置信息對(duì)象  Configuration:配置
        Configuration conf = new Configuration();

        //2.找到文件系統(tǒng)
        //final URI uri     :HDFS地址
        //final Configuration conf:配置信息
        // String user :Linux用戶名
        FileSystem fs = FileSystem.get(new URI("hdfs://bigdata111:9000"), conf, "root");

        //3.下載文件
        //boolean delSrc:是否將原文件刪除
        //Path src :要下載的路徑
        //Path dst :要下載到哪
        //boolean useRawLocalFileSystem :是否校驗(yàn)文件
        fs.copyToLocalFile(false,new Path("hdfs://bigdata111:9000/README.txt"),
                new Path("F:\\date\\README.txt"),true);

        //4.關(guān)閉fs
        //alt + enter 找錯(cuò)誤
        //ctrl + alt + o  可以快速的去除沒有用的導(dǎo)包
        fs.close();
        System.out.println("下載成功");
    }

3.2.4 HDFS目錄創(chuàng)建
(1)詳細(xì)代碼

     /**
     * hadoop fs -mkdir /xinshou
     */
    @Test
    public void mkmdirHDFS() throws Exception {
        //1.創(chuàng)新配置信息對(duì)象
        Configuration configuration = new Configuration();

        //2.鏈接文件系統(tǒng)
        //final URI uri  地址
        //final Configuration conf  配置
        //String user   Linux用戶
        FileSystem fs = FileSystem.get(new URI("hdfs://bigdata111:9000"), configuration, "root");

        //3.創(chuàng)建目錄
        fs.mkdirs(new Path("hdfs://bigdata111:9000/Good/Goog/Study"));

        //4.關(guān)閉
        fs.close();
        System.out.println("創(chuàng)建文件夾成功");
    }

3.2.5 HDFS文件夾刪除
(1)詳細(xì)代碼

    /**
     * hadoop fs -rm -r /文件
     */
    @Test
    public void deleteHDFS() throws Exception {
        //1.創(chuàng)建配置對(duì)象
        Configuration conf = new Configuration();

        //2.鏈接文件系統(tǒng)
        //final URI uri, final Configuration conf, String user
        //final URI uri  地址
        //final Configuration conf  配置
        //String user   Linux用戶
        FileSystem fs = FileSystem.get(new URI("hdfs://bigdata111:9000"), conf, "root");

        //3.刪除文件
        //Path var1   : HDFS地址
        //boolean var2 : 是否遞歸刪除
        fs.delete(new Path("hdfs://bigdata111:9000/a"),false);

        //4.關(guān)閉
        fs.close();
        System.out.println("刪除成功啦");
    }

3.2.6 HDFS文件名更改
(1)詳細(xì)代碼:

    @Test
    public void renameAtHDFS() throws Exception{
    // 1 創(chuàng)建配置信息對(duì)象
    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文件詳情查看
查看文件名稱、權(quán)限、長度、塊信息

    /**
     * 查看【文件】名稱、權(quán)限等
     */
    @Test
    public void readListFiles() throws Exception {
        //1.創(chuàng)建配置對(duì)象
        Configuration conf = new Configuration();

        //2.鏈接文件系統(tǒng)
        FileSystem fs = FileSystem.get(new URI("hdfs://bigdata111:9000"), conf, "root");

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

        //4.遍歷迭代器
        while (listFiles.hasNext()){
            //一個(gè)一個(gè)出
            LocatedFileStatus fileStatus = listFiles.next();

            //名字
            System.out.println("文件名:" + fileStatus.getPath().getName());
            //塊大小
            System.out.println("大?。? + fileStatus.getBlockSize());
            //權(quán)限
            System.out.println("權(quán)限:" + fileStatus.getPermission());
            System.out.println(fileStatus.getLen());


            BlockLocation[] locations = fileStatus.getBlockLocations();

            for (BlockLocation bl:locations){
                System.out.println("block-offset:" + bl.getOffset());
                String[] hosts = bl.getHosts();
                for (String host:hosts){
                    System.out.println(host);
                }
            }

            System.out.println("------------------華麗的分割線----------------");
        }

3.2.8 HDFS文件和文件夾判斷

    /**
     * 判斷是否是個(gè)文件還是目錄,然后打印
     * @throws Exception
     */
    @Test
    public void judge() throws Exception {
        //1.創(chuàng)建配置文件信息
        Configuration conf = new Configuration();

        //2.獲取文件系統(tǒng)
        FileSystem fs = FileSystem.get(new URI("hdfs://bigdata111:9000"), conf, "root");

        //3.遍歷所有的文件
        FileStatus[] liststatus = fs.listStatus(new Path("/Andy"));
        for(FileStatus status :liststatus)
        {
            //判斷是否是文件
            if (status.isFile()){
                //ctrl + d:復(fù)制一行
                //ctrl + x 是剪切一行,可以用來當(dāng)作是刪除一行
                System.out.println("文件:" + status.getPath().getName());
            } else {
                System.out.println("目錄:" + status.getPath().getName());
            }
        }
    }

3.3 通過IO流操作HDFS

3.3.1 HDFS文件上傳

    /**
     * IO流方式上傳
     *
     * @throws URISyntaxException
     * @throws FileNotFoundException
     * @throws InterruptedException
     */
    @Test
    public void putFileToHDFSIO() throws URISyntaxException, IOException, InterruptedException {
        //1.創(chuàng)建配置文件信息
        Configuration conf = new Configuration();

        //2.獲取文件系統(tǒng)
        FileSystem fs = FileSystem.get(new URI("hdfs://bigdata111:9000"), conf, "root");

        //3.創(chuàng)建輸入流
        FileInputStream fis = new FileInputStream(new File("F:\\date\\Sogou.txt"));

        //4.輸出路徑
        //注意:不能/Andy  記得后邊寫個(gè)名 比如:/Andy/Sogou.txt
        Path writePath = new Path("hdfs://bigdata111:9000/Andy/Sogou.txt");
        FSDataOutputStream fos = fs.create(writePath);

        //5.流對(duì)接
        //InputStream in    輸入
        //OutputStream out  輸出
        //int buffSize      緩沖區(qū)
        //boolean close     是否關(guān)閉流
        try {
            IOUtils.copyBytes(fis,fos,4 * 1024,false);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            IOUtils.closeStream(fos);
            IOUtils.closeStream(fis);
            System.out.println("上傳成功啦");
        }
    }

3.3.2 HDFS文件下載

     /**
     * IO讀取HDFS到本地
     *
     * @throws URISyntaxException
     * @throws IOException
     * @throws InterruptedException
     */
    @Test
    public void getFileToHDFSIO() throws URISyntaxException, IOException, InterruptedException {
        Configuration configuration = new Configuration();

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


        FileOutputStream fos = new FileOutputStream(new File("/Users/macbook/TestInfo/downloadFileFromHdfsIO.txt"));

        Path readPath = new Path("hdfs://bigdata111:9000/aa.txt");

        FSDataInputStream fis = fileSystem.open(readPath);

        try {
            IOUtils.copyBytes(fis,fos,4*1024,false);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            IOUtils.closeStream(fis);
            IOUtils.closeStream(fos);
            System.out.println("下載成功!");
        }
    }

3.3.3 定位文件讀取
(1)下載第一塊

     /**
     * IO讀取第一塊的內(nèi)容
     *
     * @throws Exception
     */
    @Test
    public void  readFlieSeek1() throws Exception {
        //1.創(chuàng)建配置文件信息
        Configuration conf = new Configuration();

        //2.獲取文件系統(tǒng)
        FileSystem fs = FileSystem.get(new URI("hdfs://bigdata111:9000"), conf, "root");

        //3.輸入
        Path path = new Path("hdfs://bigdata111:9000/Andy/hadoop-2.7.2.rar");
        FSDataInputStream fis = fs.open(path);

        //4.輸出
        FileOutputStream fos = new FileOutputStream("F:\\date\\readFileSeek\\A1");

        //5.流對(duì)接
        byte[] buf = new byte[1024];
        for (int i = 0; i < 128 * 1024; i++) {
            fis.read(buf);
            fos.write(buf);
        }

        //6.關(guān)閉流
        IOUtils.closeStream(fos);
        IOUtils.closeStream(fis);
    }

(2)下載第二塊

    /**
     * IO讀取第二塊的內(nèi)容
     *
     * @throws Exception
     */
    @Test
    public void readFlieSeek2() throws Exception {
        //1.創(chuàng)建配置文件信息
        Configuration conf = new Configuration();

        //2.獲取文件系統(tǒng)
        FileSystem fs = FileSystem.get(new URI("hdfs://bigdata111:9000"), conf, "root");

        //3.輸入
        Path path = new Path("hdfs://bigdata111:9000/Andy/hadoop-2.7.2.rar");
        FSDataInputStream fis = fs.open(path);

        //4.輸出
        FileOutputStream fos = new FileOutputStream("F:\\date\\readFileSeek\\A2");

        //5.定位偏移量/offset/游標(biāo)/讀取進(jìn)度 (目的:找到第一塊的尾巴,第二塊的開頭)
        fis.seek(128 * 1024 * 1024);

        //6.流對(duì)接
        IOUtils.copyBytes(fis, fos, 1024);

        //7.關(guān)閉流
        IOUtils.closeStream(fos);
        IOUtils.closeStream(fis);
    }

(3)合并文件
在window命令窗口中執(zhí)行
type A2 >> A1 然后更改后綴為rar即可

四 HDFS的數(shù)據(jù)流

4.1 HDFS寫數(shù)據(jù)流程

1.剖析文件寫入
HDFS的寫數(shù)據(jù)流程

(1)客戶端向namenode請(qǐng)求上傳文件,namenode檢查目標(biāo)文件是否已存在,父目錄是否存在。

(2)namenode返回是否可以上傳。

(3)客戶端請(qǐng)求第一個(gè) block上傳到哪幾個(gè)datanode服務(wù)器上。

(4)namenode返回3個(gè)datanode節(jié)點(diǎn),分別為dn1、dn2、dn3。

(5)客戶端請(qǐng)求dn1上傳數(shù)據(jù),dn1收到請(qǐng)求會(huì)繼續(xù)調(diào)用dn2,然后dn2調(diào)用dn3,將這個(gè)通信管道建立完成

(6)dn1、dn2、dn3逐級(jí)應(yīng)答客戶端

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

(8)當(dāng)一個(gè)block傳輸完成之后,客戶端再次請(qǐng)求namenode上傳第二個(gè)block的服務(wù)器。(重復(fù)執(zhí)行3-7步)

文件的寫入
1.  客戶端通過調(diào)用DistributedFileSystem的create方法創(chuàng)建新文件。

2.  DistributedFileSystem通過RPC調(diào)用namenode去創(chuàng)建一個(gè)沒有blocks關(guān)聯(lián)的新文件,創(chuàng)建前, namenode會(huì)做各種校驗(yàn),比如文件是否存在,客戶端有無權(quán)限去創(chuàng)建等。如果校驗(yàn)通過, namenode就會(huì)記錄下新文件,否則就會(huì)拋出IO異常。

3.  前兩步結(jié)束后,會(huì)返回FSDataOutputStream的對(duì)象,與讀文件的時(shí)候相似, FSDataOutputStream被封裝成DFSOutputStream。DFSOutputStream可以協(xié)調(diào)namenode和 datanode。客戶端開始寫數(shù)據(jù)到DFSOutputStream,DFSOutputStream會(huì)把數(shù)據(jù)切成一個(gè)個(gè)小的packet,然后排成隊(duì) 列data quene(數(shù)據(jù)隊(duì)列)。

4.  DataStreamer會(huì)去處理接受data quene,它先詢問namenode這個(gè)新的block最適合存儲(chǔ)的在哪幾個(gè)datanode里(比如重復(fù)數(shù)是3,那么就找到3個(gè)最適合的 datanode),把他們排成一個(gè)pipeline。DataStreamer把packet按隊(duì)列輸出到管道的第一個(gè)datanode中,第一個(gè) datanode又把packet輸出到第二個(gè)datanode中,以此類推。

5.  DFSOutputStream還有一個(gè)對(duì)列叫ack quene,也是由packet組成,等待datanode的收到響應(yīng),當(dāng)pipeline中的所有datanode都表示已經(jīng)收到的時(shí)候,這時(shí)ack quene才會(huì)把對(duì)應(yīng)的packet包移除掉。 
如果在寫的過程中某個(gè)datanode發(fā)生錯(cuò)誤,會(huì)采取以下幾步: 
  (1)pipeline被關(guān)閉掉; 
  (2)   為了防止防止丟包ack quene里的packet會(huì)同步到data quene里; 
  (3)把產(chǎn)生錯(cuò)誤的datanode上當(dāng)前在寫但未完成的block刪掉; 
  (4)block剩下的部分被寫到剩下的兩個(gè)正常的datanode中; 
  (5)namenode找到另外的datanode去創(chuàng)建這個(gè)塊的復(fù)制。當(dāng)然,這些操作對(duì)客戶端來說是無感知的。

6.客戶端完成寫數(shù)據(jù)后調(diào)用close方法關(guān)閉寫入流。

7.DataStreamer把剩余得包都刷到pipeline里,然后等待ack信息,收到最后一個(gè)ack后,通知datanode把文件標(biāo)視為已完成。

    注意:客戶端執(zhí)行write操作后,寫完的block才是可見的(注:和下面的一致性所對(duì)應(yīng)),正在寫的block對(duì)客戶端是不可見的,只有 調(diào)用sync方法,客戶端才確保該文件的寫操作已經(jīng)全部完成,當(dāng)客戶端調(diào)用close方法時(shí),會(huì)默認(rèn)調(diào)用sync方法。是否需要手動(dòng)調(diào)用取決你根據(jù)程序需 要在數(shù)據(jù)健壯性和吞吐率之間的權(quán)衡

4.2 HDFS讀數(shù)據(jù)流程

HDFS讀數(shù)據(jù)流程

(1)客戶端向namenode請(qǐng)求下載文件,namenode通過查詢?cè)獢?shù)據(jù),找到文件塊所在的datanode地址。

(2)挑選一臺(tái)datanode(就近原則,然后隨機(jī))服務(wù)器,請(qǐng)求讀取數(shù)據(jù)。

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

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

1.  首先調(diào)用FileSystem對(duì)象的open方法,其實(shí)是一個(gè)DistributedFileSystem的實(shí)例。
2.  DistributedFileSystem通過rpc獲得文件的第一批block的locations,同一個(gè)block按照重復(fù)數(shù)會(huì)返回多個(gè)locations,這些locations按照hadoop拓?fù)浣Y(jié)構(gòu)排序,距離客戶端近的排在前面。
3.  前兩步會(huì)返回一個(gè)FSDataInputStream對(duì)象,該對(duì)象會(huì)被封裝DFSInputStream對(duì)象,DFSInputStream可 以方便的管理datanode和namenode數(shù)據(jù)流??蛻舳苏{(diào)用read方法,DFSInputStream最會(huì)找出離客戶端最近的datanode 并連接。
4.  數(shù)據(jù)從datanode源源不斷的流向客戶端。
5.  如果第一塊的數(shù)據(jù)讀完了,就會(huì)關(guān)閉指向第一塊的datanode連接,接著讀取下一塊。這些操作對(duì)客戶端來說是透明的,客戶端的角度看來只是讀一個(gè)持續(xù)不斷的流。
6.  如果第一批block都讀完了, DFSInputStream就會(huì)去namenode拿下一批block的locations,然后繼續(xù)讀,如果所有的塊都讀完,這時(shí)就會(huì)關(guān)閉掉所有的流。 
7.  如果在讀數(shù)據(jù)的時(shí)候, DFSInputStream和datanode的通訊發(fā)生異常,就會(huì)嘗試正在讀的block的排序第二近的datanode,并且會(huì)記錄哪個(gè) datanode發(fā)生錯(cuò)誤,剩余的blocks讀的時(shí)候就會(huì)直接跳過該datanode。 DFSInputStream也會(huì)檢查block數(shù)據(jù)校驗(yàn)和,如果發(fā)現(xiàn)一個(gè)壞的block,就會(huì)先報(bào)告到namenode節(jié)點(diǎn),然后 DFSInputStream在其他的datanode上讀該block的鏡像。
8.  該設(shè)計(jì)就是客戶端直接連接datanode來檢索數(shù)據(jù)并且namenode來負(fù)責(zé)為每一個(gè)block提供最優(yōu)的datanode, namenode僅僅處理block location的請(qǐng)求,這些信息都加載在namenode的內(nèi)存中,hdfs通過datanode集群可以承受大量客戶端的并發(fā)訪問。

4.3 一致性模型

(1)debug調(diào)試如下代碼

    @Test
    public void writeFile() throws Exception{
        // 1 創(chuàng)建配置信息對(duì)象
        Configuration configuration = new Configuration();
        fs = FileSystem.get(configuration);
        
        // 2 創(chuàng)建文件輸出流
        Path path = new Path("F:\\date\\H.txt");
        FSDataOutputStream fos = fs.create(path);
        
        // 3 寫數(shù)據(jù)
        fos.write("hello Andy".getBytes());
        // 4 一致性刷新
        fos.hflush();
        
        fos.close();
    }

(2)總結(jié)
寫入數(shù)據(jù)時(shí),如果希望數(shù)據(jù)被其他client立即可見,調(diào)用如下方法

FSDataOutputStream. hflush ();      //清理客戶端緩沖區(qū)數(shù)據(jù),被其他client立即可見

五. NameNode工作機(jī)制

5.1 NameNode&Secondary NameNode工作機(jī)制

1.第一階段:namenode啟動(dòng)

(a)第一次啟動(dòng)namenode格式化后,創(chuàng)建fsimage和edits文件。如果不是第一次啟動(dòng),直接加載編輯日志(edits)和鏡像文件(fsimage)到內(nèi)存

(b)客戶端對(duì)元數(shù)據(jù)進(jìn)行增刪改的請(qǐng)求

(c)namenode記錄操作日志,更新滾動(dòng)日志

(d)namenode在內(nèi)存中對(duì)數(shù)據(jù)進(jìn)行增刪改查

2.第二階段:Secondary NameNode工作

(a)Secondary NameNode詢問namenode是否需要checkpoint。直接帶回namenode是否檢查結(jié)果。

(b)Secondary NameNode請(qǐng)求執(zhí)行checkpoint。

(c)namenode滾動(dòng)正在寫的edits日志

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

(e)Secondary NameNode加載編輯日志和鏡像文件到內(nèi)存,并合并。

(f)生成新的鏡像文件fsimage.chkpoint

(g)拷貝fsimage.chkpoint到namenode

(h)namenode將fsimage.chkpoint重新命名成fsimage

3.chkpoint檢查時(shí)間參數(shù)設(shè)置

(1)通常情況下,SecondaryNameNode每隔一小時(shí)執(zhí)行一次。

[hdfs-default.xml]

<property>
  <name>dfs.namenode.checkpoint.period</name>
  <value>3600</value>
</property>

(2)一分鐘檢查一次操作次數(shù),當(dāng)操作次數(shù)達(dá)到1百萬時(shí),SecondaryNameNode執(zhí)行一次。

<property>
  <name>dfs.namenode.checkpoint.txns</name>
  <value>1000000</value>
  <description>操作動(dòng)作次數(shù)</description>
</property>

<property>
  <name>dfs.namenode.checkpoint.check.period</name>
  <value>60</value>
  <description> 1分鐘檢查一次操作次數(shù)</description>
</property>

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

1.概念

????namenode被格式化之后,將在/opt/module/hadoop-2.8.4/data/dfs/name/current目錄中產(chǎn)生如下文件,注只能在NameNode所在的節(jié)點(diǎn)才能找到此文件
????可以執(zhí)行find . -name edits* 來查找文件

edits_0000000000000000000
fsimage_0000000000000000000.md5
seen_txid
VERSION

(1)Fsimage文件:HDFS文件系統(tǒng)元數(shù)據(jù)的一個(gè)永久性的檢查點(diǎn),其中包含HDFS文件系統(tǒng)的所有目錄和文件idnode的序列化信息。

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

(3)seen_txid文件保存的是一個(gè)數(shù)字,就是最后一個(gè)edits_的數(shù)字

(4)每次Namenode啟動(dòng)的時(shí)候都會(huì)將fsimage文件讀入內(nèi)存,并從00001開始到seen_txid中記錄的數(shù)字依次執(zhí)行每個(gè)edits里面的更新操作,保證內(nèi)存中的元數(shù)據(jù)信息是最新的、同步的,可以看成Namenode啟動(dòng)的時(shí)候就將fsimage和edits文件進(jìn)行了合并。

2.oiv查看fsimage文件

(1)查看oiv和oev命令

hdfs
hdfs

(2)基本語法

hdfs oiv -p 文件類型 -i鏡像文件 -o 轉(zhuǎn)換后文件輸出路徑

(3)案例實(shí)操

pwd
/opt/module/hadoop-2.8.4/data/dfs/name/current

hdfs oiv -p XML -i fsimage_0000000000000000316 -o /opt/fsimage.xml

cat /opt/module/hadoop-2.8.4/fsimage.xml

將顯示的xml文件內(nèi)容拷貝到IDEA中創(chuàng)建的xml文件中,并格式化。

3.oev查看edits文件

(1)基本語法

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

-p  –processor <arg>   指定轉(zhuǎn)換類型: binary (二進(jìn)制格式), xml (默認(rèn),XML格式),stats
-i  –inputFile <arg>     輸入edits文件,如果是xml后綴,表示XML格式,其他表示二進(jìn)制
-o  –outputFile <arg> 輸出文件,如果存在,則會(huì)覆蓋

5.3 滾動(dòng)編輯日志

????正常情況HDFS文件系統(tǒng)有更新操作時(shí),就會(huì)滾動(dòng)編輯日志。也可以用命令強(qiáng)制滾動(dòng)編輯日志。
(1)滾動(dòng)編輯日志(前提必須啟動(dòng)集群)

hdfs dfsadmin -rollEdits

舉例:原文件名edits_inprogress_0000000000000000010
執(zhí)行以下命令后

image.png

(2)鏡像文件什么時(shí)候產(chǎn)生
Namenode啟動(dòng)時(shí)加載鏡像文件和編輯日志

5.4 namenode版本號(hào)

1.查看namenode版本號(hào)

在/opt/module/hadoop-2.8.4/data/dfs/name/current這個(gè)目錄下查看VERSION

namespaceID=1778616660
clusterID=CID-bc165781-d10a-46b2-9b6f-3beb1d988fe0
cTime=1552918200296
storageType=NAME_NODE
blockpoolID=BP-274621862-192.168.1.111-1552918200296
layoutVersion=-63
2.namenode版本號(hào)具體解釋
(1) namespaceID在HDFS上,會(huì)有多個(gè)Namenode,所以不同Namenode的namespaceID是不同的,分別管理一組blockpoolID。

(2)clusterID集群id,全局唯一

(3)cTime屬性標(biāo)記了namenode存儲(chǔ)系統(tǒng)的創(chuàng)建時(shí)間,對(duì)于剛剛格式化的存儲(chǔ)系統(tǒng),這個(gè)屬性為0;但是在文件系統(tǒng)升級(jí)之后,該值會(huì)更新到新的時(shí)間戳。

(4)storageType屬性說明該存儲(chǔ)目錄包含的是namenode的數(shù)據(jù)結(jié)構(gòu)。

(5)blockpoolID:一個(gè)block pool id標(biāo)識(shí)一個(gè)block pool,并且是跨集群的全局唯一。當(dāng)一個(gè)新的Namespace被創(chuàng)建的時(shí)候(format過程的一部分)會(huì)創(chuàng)建并持久化一個(gè)唯一ID。在創(chuàng)建過程構(gòu)建全局唯一的BlockPoolID比人為的配置更可靠一些。NN將BlockPoolID持久化到磁盤中,在后續(xù)的啟動(dòng)過程中,會(huì)再次load并使用。

(6)layoutVersion是一個(gè)負(fù)整數(shù)。通常只有HDFS增加新特性時(shí)才會(huì)更新這個(gè)版本號(hào)。

(7)storageID (存儲(chǔ)ID):是DataNode的ID,不唯一

5.5 SecondaryNameNode目錄結(jié)構(gòu)

????Secondary NameNode用來監(jiān)控HDFS狀態(tài)的輔助后臺(tái)程序,每隔一段時(shí)間獲取HDFS元數(shù)據(jù)的快照。
????在/opt/module/hadoop-2.8.4/data/dfs/namesecondary/current這個(gè)目錄中查看SecondaryNameNode目錄結(jié)構(gòu)

edits_0000000000000000001-0000000000000000002
fsimage_0000000000000000002
fsimage_0000000000000000002.md5
VERSION

????SecondaryNameNode的namesecondary/current目錄和主namenode的current目錄的布局相同。
????好處:在主namenode發(fā)生故障時(shí)(假設(shè)沒有及時(shí)備份數(shù)據(jù)),可以從SecondaryNameNode恢復(fù)數(shù)據(jù)。

方法一:將SecondaryNameNode中數(shù)據(jù)拷貝到namenode存儲(chǔ)數(shù)據(jù)的目錄;
方法二:使用-importCheckpoint選項(xiàng)啟動(dòng)namenode守護(hù)進(jìn)程,從而將SecondaryNameNode中數(shù)據(jù)拷貝到namenode目錄中。

5.6 集群安全模式操作

1.概述

????Namenode啟動(dòng)時(shí),首先將映像文件(fsimage)載入內(nèi)存,并執(zhí)行編輯日志(edits)中的各項(xiàng)操作。一旦在內(nèi)存中成功建立文件系統(tǒng)元數(shù)據(jù)的映像,則創(chuàng)建一個(gè)新的fsimage文件和一個(gè)空的編輯日志。此時(shí),namenode開始監(jiān)聽datanode請(qǐng)求。但是此刻,namenode運(yùn)行在安全模式,即namenode的文件系統(tǒng)對(duì)于客戶端來說是只讀的。
????系統(tǒng)中的數(shù)據(jù)塊的位置并不是由namenode維護(hù)的,而是以塊列表的形式存儲(chǔ)在datanode中。在系統(tǒng)的正常操作期間,namenode會(huì)在內(nèi)存中保留所有塊位置的映射信息。在安全模式下,各個(gè)datanode會(huì)向namenode發(fā)送最新的塊列表信息,namenode了解到足夠多的塊位置信息之后,即可高效運(yùn)行文件系統(tǒng)。
????如果滿足“最小副本條件”,namenode會(huì)在30秒鐘之后就退出安全模式。所謂的最小副本條件指的是在整個(gè)文件系統(tǒng)中99.9%的塊滿足最小副本級(jí)別(默認(rèn)值:dfs.replication.min=1)。在啟動(dòng)一個(gè)剛剛格式化的HDFS集群時(shí),因?yàn)橄到y(tǒng)中還沒有任何塊,所以namenode不會(huì)進(jìn)入安全模式。

2.基本語法

集群處于安全模式,不能執(zhí)行重要操作(寫操作)。集群啟動(dòng)完成后,自動(dòng)退出安全模式。

bin/hdfs dfsadmin -safemode get     (功能描述:查看安全模式狀態(tài))
bin/hdfs dfsadmin -safemode enter   (功能描述:進(jìn)入安全模式狀態(tài))
bin/hdfs dfsadmin -safemode leave   (功能描述:離開安全模式狀態(tài))
bin/hdfs dfsadmin -safemode wait    (功能描述:等待安全模式狀態(tài))

5.7 Namenode多目錄配置

1.namenode的本地目錄可以配置成多個(gè),且每個(gè)目錄存放內(nèi)容相同,增加了可靠性。
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>

(1)步驟:

a.停止集群 刪除data 和 logs  rm -rf data/* logs/*

b.hdfs namenode -format

c.start-dfs.sh

d.去展示

(2)具體解釋:

格式化做了哪些事情?

在NameNode節(jié)點(diǎn)上,有兩個(gè)最重要的路徑,分別被用來存儲(chǔ)元數(shù)據(jù)信息和操作日志,而這兩個(gè)路徑來自于配置文件,它們對(duì)應(yīng)的屬性分別是dfs.name.dir和dfs.name.edits.dir,同時(shí),它們默認(rèn)的路徑均是/tmp/hadoop/dfs/name。格式化時(shí),NameNode會(huì)清空兩個(gè)目錄下的所有文件,之后,格式化會(huì)在目錄dfs.name.dir下創(chuàng)建文件

hadoop.tmp.dir 這個(gè)配置,會(huì)讓dfs.name.dir和dfs.name.edits.dir會(huì)讓兩個(gè)目錄的文件生成在一個(gè)目錄里

(3)思考2****:非NN上如果生成了name1和name2,那么他和NN上生成得有沒有差別?

答:有區(qū)別、NN節(jié)點(diǎn)上會(huì)產(chǎn)生新得edits_XXX,非NN不會(huì)fsimage會(huì)更新,而非NN不會(huì),只會(huì)產(chǎn)生一個(gè)僅初始化得到得fsimage,不會(huì)生成edits,更不會(huì)發(fā)生日志滾動(dòng)。

六.DataNode工作機(jī)制

6.1 NameNode & DataNode工作機(jī)制

Datanode工作機(jī)制

1.一個(gè)數(shù)據(jù)塊在datanode上以文件形式存儲(chǔ)在磁盤上,包括兩個(gè)文件,一個(gè)是數(shù)據(jù)本身,一個(gè)是元數(shù)據(jù)包括數(shù)據(jù)塊的長度,塊數(shù)據(jù)的校驗(yàn)和,以及時(shí)間戳。

2.DataNode啟動(dòng)后向namenode注冊(cè),通過后,周期性(1小時(shí))的向namenode上報(bào)所有的塊信息。

3.心跳是每3秒一次,心跳返回結(jié)果帶有namenode給該datanode的命令如復(fù)制塊數(shù)據(jù)到另一臺(tái)機(jī)器,或刪除某個(gè)數(shù)據(jù)塊。如果超過10分鐘沒有收到某個(gè)datanode的心跳,則認(rèn)為該節(jié)點(diǎn)不可用。

4.集群運(yùn)行中可以安全加入和退出一些機(jī)器

6.2 數(shù)據(jù)完整性

1.當(dāng)DataNode讀取block的時(shí)候,它會(huì)計(jì)算checksum校驗(yàn)和

2.如果計(jì)算后的checksum,與block創(chuàng)建時(shí)值不一樣,說明block已經(jīng)損壞。

3.client讀取其他DataNode上的block.

4.datanode在其文件創(chuàng)建后周期驗(yàn)證checksum校驗(yàn)和

6.3 掉線時(shí)限參數(shù)設(shè)置

????datanode進(jìn)程死亡或者網(wǎng)絡(luò)故障造成datanode無法與namenode通信,namenode不會(huì)立即把該節(jié)點(diǎn)判定為死亡,要經(jīng)過一段時(shí)間,這段時(shí)間暫稱作超時(shí)時(shí)長。HDFS默認(rèn)的超時(shí)時(shí)長為10分鐘+30秒。如果定義超時(shí)時(shí)間為timeout,則超時(shí)時(shí)長的計(jì)算公式為:

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

????而默認(rèn)的dfs.namenode.heartbeat.recheck-interval 大小為5分鐘,dfs.heartbeat.interval默認(rèn)為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的目錄結(jié)構(gòu)

????和namenode不同的是,datanode的存儲(chǔ)目錄是初始階段自動(dòng)創(chuàng)建的,不需要額外格式化。

1.在/opt/module/hadoop-2.8.4/data/dfs/data/current這個(gè)目錄下查看版本號(hào)
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.具體解釋
storageID:存儲(chǔ)id號(hào)
clusterID集群id,全局唯一
cTime屬性標(biāo)記了datanode存儲(chǔ)系統(tǒng)的創(chuàng)建時(shí)間,對(duì)于剛剛格式化的存儲(chǔ)系統(tǒng),這個(gè)屬性為0;但是在文件系統(tǒng)升級(jí)之后,該值會(huì)更新到新的時(shí)間戳。
datanodeUuid:datanode的唯一識(shí)別碼
storageType:存儲(chǔ)類型
layoutVersion是一個(gè)負(fù)整數(shù)。通常只有HDFS增加新特性時(shí)才會(huì)更新這個(gè)版本號(hào)。
3.在/opt/module/hadoop-2.8.4/data/dfs/data/current/BP-97847618-192.168.10.102-1493726072779/current這個(gè)目錄下查看該數(shù)據(jù)塊的版本號(hào)
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.具體解釋
namespaceID:是datanode首次訪問namenode的時(shí)候從namenode處獲取的storageID對(duì)每個(gè)datanode來說是唯一的(但對(duì)于單個(gè)datanode中所有存儲(chǔ)目錄來說則是相同的),namenode可用這個(gè)屬性來區(qū)分不同datanode。

cTime屬性標(biāo)記了datanode存儲(chǔ)系統(tǒng)的創(chuàng)建時(shí)間,對(duì)于剛剛格式化的存儲(chǔ)系統(tǒng),這個(gè)屬性為0;但是在文件系統(tǒng)升級(jí)之后,該值會(huì)更新到新的時(shí)間戳。

blockpoolID:一個(gè)block pool id標(biāo)識(shí)一個(gè)block pool,并且是跨集群的全局唯一。當(dāng)一個(gè)新的Namespace被創(chuàng)建的時(shí)候(format過程的一部分)會(huì)創(chuàng)建并持久化一個(gè)唯一ID。在創(chuàng)建過程構(gòu)建全局唯一的BlockPoolID比人為的配置更可靠一些。NN將BlockPoolID持久化到磁盤中,在后續(xù)的啟動(dòng)過程中,會(huì)再次load并使用。

layoutVersion是一個(gè)負(fù)整數(shù)。通常只有HDFS增加新特性時(shí)才會(huì)更新這個(gè)版本號(hào)。

6.5 Datanode多目錄配置

1.datanode也可以配置成多個(gè)目錄,每個(gè)目錄存儲(chǔ)的數(shù)據(jù)不一樣。即:數(shù)據(jù)不是副本。
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 集群間數(shù)據(jù)拷貝

1.scp實(shí)現(xiàn)兩個(gè)遠(yuǎn)程主機(jī)之間的文件復(fù)制
scp -r hello.txt [root@bigdata111:/user/itstar/hello.txt](mailto:root@bigdata111:/user/itstar/hello.txt)          // 推 push
scp -r [root@bigdata112:/user/itstar/hello.txt  hello.txt](mailto:root@hadoop103:/user/atguigu/hello.txt%20%20hello.txt)        // 拉 pull
scp -r root@bigdata112:/opt/module/hadoop-2.8.4/LICENSE.txt root@bigdata113:/opt/module/hadoop-2.8.4/LICENSE.txt   //是通過本地主機(jī)中轉(zhuǎn)實(shí)現(xiàn)兩個(gè)遠(yuǎn)程主機(jī)的文件復(fù)制;如果在兩個(gè)遠(yuǎn)程主機(jī)之間ssh沒有配置的情況下可以使用該方式。
2.采用discp命令實(shí)現(xiàn)兩個(gè)hadoop集群之間的遞歸數(shù)據(jù)復(fù)制(注:不用設(shè)置其他,直接寫IP)
bin/hadoop distcp hdfs://192.168.1.51:9000/LICENSE.txt hdfs://192.168.1.111:9000/HAHA

7.2 Hadoop存檔

1.理論概述

????每個(gè)文件均按塊存儲(chǔ),每個(gè)塊的元數(shù)據(jù)存儲(chǔ)在namenode的內(nèi)存中,因此hadoop存儲(chǔ)小文件會(huì)非常低效。因?yàn)榇罅康男∥募?huì)耗盡namenode中的大部分內(nèi)存。但注意,存儲(chǔ)小文件所需要的磁盤容量和存儲(chǔ)這些文件原始內(nèi)容所需要的磁盤空間相比也不會(huì)增多。例如,一個(gè)1MB的文件以大小為128MB的塊存儲(chǔ),使用的是1MB的磁盤空間,而不是128MB。
????Hadoop存檔文件或HAR文件,是一個(gè)更高效的文件存檔工具,它將文件存入HDFS塊,在減少namenode內(nèi)存使用的同時(shí),允許對(duì)文件進(jìn)行透明的訪問。具體說來,Hadoop存檔文件可以用作MapReduce的輸入。

7.3 快照管理

快照相當(dāng)于對(duì)目錄做一個(gè)備份。并不會(huì)立即復(fù)制所有文件,而是指向同一個(gè)文件。當(dāng)寫入發(fā)生時(shí),才會(huì)產(chǎn)生新文件。

1.基本語法
hdfs dfsadmin -allowSnapshot 路徑   (功能描述:開啟指定目錄的快照功能)
hdfs dfsadmin -disallowSnapshot 路徑 (功能描述:禁用指定目錄的快照功能,默認(rèn)是禁用)
hdfs dfs -createSnapshot 路徑        (功能描述:對(duì)目錄創(chuàng)建快照)
hdfs dfs -createSnapshot 路徑 名稱   (功能描述:指定名稱創(chuàng)建快照)
hdfs dfs -renameSnapshot 路徑 舊名稱 新名稱 (功能描述:重命名快照)
hdfs lsSnapshottableDir         (功能描述:列出當(dāng)前用戶所有已快照目錄)
hdfs snapshotDiff 路徑1 路徑2 (功能描述:比較兩個(gè)快照目錄的不同之處)
hdfs dfs -deleteSnapshot <path> <snapshotName>  (功能描述:刪除快照)

7.4 回收站

1.默認(rèn)回收站
  • 默認(rèn)值fs.trash.interval=0,0表示禁用回收站,可以設(shè)置刪除文件的存活時(shí)間。
  • 默認(rèn)值fs.trash.checkpoint.interval=0,檢查回收站的間隔時(shí)間。
  • 要求fs.trash.checkpoint.interval<=fs.trash.interval。
image.png
2.啟用回收站

修改core-site.xml,配置垃圾回收時(shí)間為1分鐘。

<property>
    <name>fs.trash.interval</name>
    <value>1</value>
</property>
3.查看回收站

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

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

進(jìn)入垃圾回收站用戶名稱,默認(rèn)是dr.who,修改為itstar用戶
[core-site.xml]

<property>
  <name>hadoop.http.staticuser.user</name>
  <value>itstar</value>
</property>
5.通過程序刪除的文件不會(huì)經(jīng)過回收站,需要調(diào)用moveToTrash()才進(jìn)入回收站

????Trash trash = New Trash(conf);
????trash.moveToTrash(path);

6.恢復(fù)回收站數(shù)據(jù)
hadoop fs -mv /user/itstar/.Trash/Current/user/itstar/input    /user/itstar/input
7.清空回收站
hdfs dfs -expunge
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Hadoop分布式文件系統(tǒng)(HDFS)是一種分布式文件系統(tǒng)。它與現(xiàn)有的分布式文件系統(tǒng)有許多相似之處。但是,與其他分...
    逍遙ii閱讀 1,198評(píng)論 3 20
  • 1 HDFS 概述 1.1 HDFS 產(chǎn)出背景及定義 隨著數(shù)據(jù)量越來越大,在一個(gè)操作系統(tǒng)存不下所有的數(shù)據(jù),那么就分...
    djm猿閱讀 447評(píng)論 0 0
  • 我們依然是先過一遍官方文檔: 引言Hadoop分布式文件系統(tǒng)(HDFS)被設(shè)計(jì)成適合運(yùn)行在通用硬件(commodi...
    e5bda6e7a596閱讀 770評(píng)論 0 0
  • hdfs是什么? 問題: 1. hdfs是基于什么樣的原理將文件分塊存儲(chǔ)到分布式環(huán)境中的各個(gè)設(shè)備上的? 2. h...
    4762d2980c91閱讀 4,859評(píng)論 0 6
  • 第1章 HDFS概述 1.1 HDFS定義 HDFS(Hadoop distributed System),它是一...
    白紙糊閱讀 407評(píng)論 0 0

友情鏈接更多精彩內(nèi)容