大数据之Hadoop(HDFS文件系统)

大数据之Hadoop(HDFS文件系统)

HDFS文件系统概念:

1.1、概念

​ HDFS,它是一个文件系统,全称:Hadoop distributed File System ,用于存储问价通过目录树来定位文件;其次,它是分布式的,由很多服务器联合起来实现其功能,集群中的服务器有各自的角色。注:服务器默认为3台

1.2、组成

​ 1)、HDFS集群包括,NameNode 和 DataNode 以及 SecondaryNameNode。

​ A)、NameNode 负责管理整个文件系统得元数据,以及每个路径(文件)所对应的数据块信息。

​ B)、DateNode 负责管理用户的文件数据块,每一个数据块都可以在多个 datanode 上存储多个副本。

​ C)、Secondary NameNode 用来监控 HDFS 状态的辅助后台程序,每隔一段时间获取 HDFS 元数据的快照。

1.3、HDFS文件块大小

​ HDFS 中的文件在物理上是分块存储(block),块的大小可以通过配置参数(dfs.blocksize)来规定,默认大小为128M。

​ HDFS 的块比磁盘的块大,其目的是为了最小化寻址开销。如果块设置得足够大,从磁盘传输数据的时间会明显大于定位这个块开始位置所需的时间。因而,传输一个由多个快组成的文件的时间取决于磁盘传输速率

HDFS命令行操作:

1、基本语法

​ bin/hadoop fs 具体命令

2、常用命令实操

1)-help:输出这个命令参数

​ bin/hdfs dfs -help rm

2.1、显示

1)-ls:显示 hdfs 上的目录信息

​ hadoop fs -ls /

2)-cat:显示文本文件内容

​ hadoop fs -cat /hdfs文件

3)-tail -f:监控文本文件

​ hadoop fs -tail -f /hdfs目录

4)-df:统计文件系统的可用空间信息

​ hadoop fs -df /hdfs(目录/文件)

5)-du:统计文件夹的大小信息

​ hadoop fs -du -s -h /hdfs(目录/文件)【查看文件总的大小】

​ hadoop fs -du -h /hdfs(目录/文件)【查看所有文件的大小】

6)-count:统计一个指定目录下的文件节点数量

​ hadoop fs -count /hdfs(目录/文件)

​ 结果显示:【嵌套层级】 【文本数量】 大小/路径

2.2、创建

1)-mkdir:在 hdfs 上创建目录

​ hadoop fs -mkdir -p /hdfs目录名

2.3、添加

1)-appendToFile:将本地文本文件的内容添加到 hdfs 文本文件的末尾

​ hadoop fs -appendToFile 本地目录 /hdfs目录

2.4、上传

1)-put:将本地的目录/文件上传到 hdfs

​ hadoop fs -put 本地(目录/文件) /hdfs(目录/文件)

2)-moveFromLocal 从本地剪切粘贴到 hdfs 上

​ hadoop fs -moveFrpmLocal 本地(目录/文件) /hdfs目录名

2.5、下载

1)-get:从 hdfs 下载文件到本地

​ hadoop fs -get /hdfs(目录/文件) 本地(目录/文件)

2)-getmerge:从 hdfs 中合并多个文件下载到 Linux 中

​ hadoop fs -getmerge /hdfs(目录/文件) /hdfs(目录/文件)

2.6、删除

1)-rm:删除文件或文件夹

​ hadoop fs -rm -r /hdfs(目录/文件)

2.7、hdfs 上移动/拷贝

1)-cp:从 hdfs 的一个路径拷贝到 hdfs 的另一个路径

​ hadoop fs -cp /hdfs(目录/文件) /hdfs目录

2)-mv:在 hdfs 目录中移动/重命名 文件

​ hsdoop fs -mv /hdfs(目录/文件) /hdfs(目录/文件)

2.8、修改

1)-chmod、-chown:与 Linux 系统用法相同,修改文件所属权限

​ hadoop fs -chmod 777 /hdfs(目录/文件)

​ hadoop fs -chown root:root /hdfs(目录/文件)

2)-setrep:设置hdfs中文件的副本数量:3是副本数,可改

​ hadoop fs -setrep 3 /hdfs(目录/文件)

​ 这里设置的副本数只是记录在 namenode 的元数据中,是否真的会有这么多副本,还得看 datanode 的数量。因为目前自由 3 台设备,最多也就 3 个副本,只有节点数增(namenode)加到 10 台时,副本数才能达到 10 。**

​ hsdoop fs -mv /hdfs(目录/文件) /hdfs(目录/文件)

HDFS IDEA环境准备:

1、apache-maven配置步骤

//	1、配置	apache-maven-3.3.9	文件下conf文件下的	settings	文件
		//注:网盘下的学习文件下的	apache-maven-3.3.9	包是配置好了的。

//	2、	settings	文件下的仓库路径一定要去建立文件夹

//	3、将	apache-maven-3.3.9	文件放在虚拟机的那个盘中

//	4、打开	IDEA	点击	file	下	Settings	下搜索		maven
	//	找到	Maven	目录
	//	在目录下	directory	中选择  apache-maven-3.3.9 的路径
	//	file 	中选择		apache-maven-3.3.9	下	settings	的路径
	//	选择完路径后	一定要勾选上	file 后的	Override	不然会默认选择C盘下的目录

settings配置:

{$MAVEN_HOME/conf/settings};设置后添加环境变量,测试命令:mvn -v

 <!--本地仓库所在位置-->
<localRepository>D:\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>

Maven依赖配置

​ 将以下的依赖复制到新建的 IDEA 下的 pom.xml 下

		<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>

也可以百度搜索maven依赖添加。

HDFS文件系统操作:

1、HDFS上传文件

/**
 *  上传文件代码
 */

@Test
public void CopyFileTOHDFS() throws Exception {

    //创建配置信息对象
    Configuration conf = new Configuration();

    /**
     * 获取文件系统的路径
     *      final URI uri  :HDFS地址
     *      final Configuration conf  :配置信息
     *      String user :Linux用户名
     */
    FileSystem fs = FileSystem.get(new URI("hdfs://192.168.181.111:9000"), conf, "root");

    /**
     * 以拷贝的方式上传
     *      boolean delSrc:是否删除本地文件
     *      boolean overwrite:是否覆盖
     *      ath src:需要上传文件的地址
     *      Path dst:需要上传到哪儿
     */
    fs.copyFromLocalFile(true,true,new Path("D:\\jds.txt"),
            new Path("hdfs://192.168.181.111:9000/"));

    //关闭
    fs.close();

    //提示
    System.out.println("上传成功!");

}

2、HDFS下载文件

/**
 * 下载文件代码
 */

@Test
public void GetFileToHDFS() throws Exception {

    //创建配置信息
    Configuration conf = new Configuration();

    /**
     * 获取文件系统的路径
     *      final URI uri  :HDFS地址
     *      final Configuration conf  :配置信息
     *      String user :Linux用户名
     */
    FileSystem fs = FileSystem.get(new URI("hdfs://192.168.181.111:9000"), conf, "root");

    /**
     * 下载文件
     *      boolean delSrc:是否将源文件删除
     *      Path src:下载的路径
     *      Path dst:下载文件保存的路径
     *      boolean useRawLocalFileSystem:是否校验文件
     */
    fs.copyToLocalFile(false,new Path("hdfs://192.168.181.111:9000/jds.txt"),
            new Path("D:\\jds.txt"),true);

    //关闭
    fs.close();

    //提示
    System.out.println("下载成功!");

}

3、HDFS-API创建目录

/**
 * 在 HDFS 上创建目录
 */

@Test
public void MkdirHDFS() throws Exception {

    //创建配置信息
    Configuration conf = new Configuration();

    /**
     * 获取文件系统的路径
     *      final URI uri  :HDFS地址
     *      final Configuration conf  :配置信息
     *      String user :Linux用户名
     */
    FileSystem fs = FileSystem.get(new URI("hdfs://192.168.181.111:9000"), conf, "root");

    //创建目录
    fs.mkdirs(new Path("hdfs://192.168.181.111:9000/BigData"));

    //关闭
    fs.close();

    //提示
    System.out.println("创建成功!");
}

4、HDFS-API删除

/**
 * 在 HDFS 上执行删除
 */

@Test
public void DeleteHDFS() throws Exception {

    //创建配置信息
    Configuration conf = new Configuration();

    /**
     * 获取文件系统的路径
     *      final URI uri  :HDFS地址
     *      final Configuration conf  :配置信息
     *      String user :Linux用户名
     */
    FileSystem fs = FileSystem.get(new URI("hdfs://192.168.181.111:9000"), conf, "root");

    /**
     * 执行删除
     *      Path var1 :HDFS 地址
     *      boolean var2  :是否递归删除
     */
    fs.delete(new Path("hdfs://192.168.181.111:9000/BigData"),true);

    //关闭
    fs.close();

    //提示
    System.out.println("删除成功!");

}

5、HDFS文件名的更改

/**
 * 更改文件名字
 * @throws Exception
 */

@Test
public void RenameAtHDFS() throws Exception{

    //获取配置信息
    Configuration conf = new Configuration();

    //获取系统文件路径
    FileSystem fs = FileSystem.get(new URI("hdfs://192.168.181.111:9000"), conf, "root");

    //更改名字
    fs.rename(new Path("hdfs://192.168.181.111:9000/English"),
            new Path("hdfs://192.168.181.111:9000/English.txt"));

    //关闭
    fs.close();

    //提示
    System.out.println("更改成功!!!");

}

6、HDFS查看文件属性

/**
 * 查看【文件】属性
 */

@Test
public void ReadListHDFS() throws Exception {
    //创建配置信息
    Configuration conf = new Configuration();

    /**
     * 获取文件系统的路径
     *      final URI uri  :HDFS地址
     *      final Configuration conf  :配置信息
     *      String user :Linux用户名
     */
    FileSystem fs = FileSystem.get(new URI("hdfs://192.168.181.111:9000"), conf, "root");

    /**
     * 迭代器
     *      final Path f : 迭代那个目录下的文件
     *      final boolean recursive : 是否递归迭代
     */
    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[] 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("===================================");

    }
}

7、文件判断

/**
 * 文件判断(判断是文件还是目录并输出)
 */

@Test
public void JudgeHDFS() throws Exception {
    //创建配置文件
    Configuration conf = new Configuration();

    /**
     * 获取文件系统的路径
     *      final URI uri  :HDFS地址
     *      final Configuration conf  :配置信息
     *      String user :Linux用户名
     */
    FileSystem fs = FileSystem.get(new URI("hdfs://192.168.181.111:9000"), conf, "root");

    //遍历所有的文件
    FileStatus[] listStatus = fs.listStatus(new Path("/"));
    for (FileStatus status: listStatus
         ) {

        //判断是否是文件
        if(status.isFile()){
            System.out.println("文件:" + status.getPath().getName());
        }else {
            System.out.println("目录:" + status.getPath().getName());
        }
    }
}

8、IO 上传到 HDFS

/**
 * IO 上传到 HDFS
 * @throws Exception
 */

@Test
public void copyIOFromHDFS() throws Exception{

    //获取配置信息
    Configuration conf = new Configuration();

    //获取文件系统路径
    FileSystem fs = FileSystem.get(new URI("hdfs://192.168.181.111:9000"), conf, "root");

    //创建输入流
    FileInputStream fis = new FileInputStream(new File("C:\\Users\\Jds\\Desktop\\HDFS\\English.txt"));

    //输出路径
    //注意:上传 IO 流必须在目录下给名字
    FSDataOutputStream fos = fs.create(new Path("hdfs://192.168.181.111:9000/AAA/English"));

    /**
     * 流对接
     *      nputStream in : 输入
     *      OutputStream out : 输出
     *      int buffSize : 缓冲区
     *      boolean close : 是否关闭流
     */
    IOUtils.copyBytes(fis,fos,4 * 1024,true);

    //提示
    System.out.println("上传成功!!!");

}

9、IO 读取 HDFS 到控制台

/**
 * IO 读取 HDFS 文件到控制台
 * @throws URISyntaxException
 * @throws IOException
 * @throws InterruptedException
 */
@Test
public void GetFileToHDFSIO() throws URISyntaxException, IOException, InterruptedException {

    //获取配置信息
    Configuration conf = new Configuration();

    //获取文件系统位置
    FileSystem fs = FileSystem.get(new URI("hdfs://192.168.181.111:9000"), conf, "root");

    //读取路径
    Path readpath = new Path("hdfs://192.168.181.111:9000/English");

    //输入
    FSDataInputStream fis = fs.open(readpath);

    //输出到控制台
    /**
     * 流对接
     *      nputStream in : 输入
     *      OutputStream out : 输出
     *      int buffSize : 缓冲区
     *      boolean close : 是否关闭流
     */
    try {
        IOUtils.copyBytes(fis,System.out,4 * 1024,false);
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        IOUtils.closeStream(fs);
        fis.close();
    }

}

10、分块读取 HDFS 上大于 128M 的文件

/**
 * IO 读取第一块内容
 * @throws Exception
 */

@Test
public void ReadFileSeek1() throws Exception{

    //获取配置信息
    Configuration conf = new Configuration();

    //获取系统文件路径
    FileSystem fs = FileSystem.get(new URI("hdfs://192.168.181.111:9000"), conf, "root");

    //输入
    Path path = new Path("hdfs://192.168.181.111:9000/hadoop-2.7.2.rar");
    FSDataInputStream fis = fs.open(path);

    //输出
    FileOutputStream fos = new FileOutputStream("C:\\Users\\Jds\\Desktop\\Seek\\A1");

    //流对接
    byte[] buf = new byte[1024];
    for (int i = 0; i < 128 * 1024; i++) {

        fis.read(buf);
        fos.write(buf);

    }

    //关闭流
    IOUtils.closeStream(fos);
    IOUtils.closeStream(fis);

    //提示
    System.out.println("读取成功!!!");
}


/**
 * IO 读取第二块
 * @throws Exception
 */

@Test
public void ReadFileSeek2() throws Exception{

    //获取配置信息
    Configuration conf = new Configuration();

    //获取系统文件路径
    FileSystem fs = FileSystem.get(new URI("hdfs://192.168.181.111:9000"), conf, "root");

    //输入
    Path path = new Path("hdfs://192.168.181.111:9000/hadoop-2.7.2.rar");
    FSDataInputStream fis = fs.open(path);

    //输出
    FileOutputStream fos = new FileOutputStream("C:\\Users\\Jds\\Desktop\\Seek\\A2");

    //定位偏移量/offset/游标/读取进度(目的:找到第一块的尾巴,第二块的开头)
    fis.seek(128 * 1024 * 1024);

    //流对接
    IOUtils.copyBytes(fis,fos,1024);

    //关闭流
    IOUtils.closeStream(fos);
    IOUtils.closeStream(fis);

    //提示
    System.out.println("读取成功!!!");

}

/**
 * 注:读取下来的文件是分开的,所以需要合并起来
 *    在存放文件的文件夹下打开  cmd 输入 type A2 >> A1 将 A2 追加到 A1后
 *    在更改 A1 的后缀
 */

HDFS 写数据流程:

简易版

在这里插入图片描述

1、客户端向 namenode 请求上传文件,namenode 检查目标文件是否已存在,父目录是否存在。

2、namenode 返回是否可以上传。

3、客户端请求第一个 block 上传到哪几个 datanode 服务器上。

4、namenode 返回 3 个 datanode 节点,分别为 dn1、dn2、d3。

5、客户端请求 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步)

复杂版

1、客户端 通过调用 DistributedFileSystemcreate 方法创建新文件。

2、DistributedFileSystem 通过 RPC协议 调用 namenode 去创建一个没有 block(块) 关联的新文件,创建前,namenode 会做各种校验,比如文件是否存在,客户端有无权限去创建等。如果检验通过, namenode 就会记录下新文件,否则就会抛出 IO 异常。

3、前两步结束后,会返回 FSDataOutputStream 的对象,与读文件的时候相似,FSDataOutputStream 被封装成 DFSOutputStreamDFSOutputStream 可以协调 namenodedatanode 。客户端开始写数据到 DFSOutputStreamDFSOutputStream 会把数据切成一个个小的 packet ,然后排成队列 data quene(数据队列)

4、DataStreamer 会去处理接受 data quene , 它先询问 namenode 这个新的 block(块) 最适合存储的在那几个 datanode 里(比如重复数是 3,那么就找到 3 个最适合 datanode ),把他们排成一个 pipeline(管道)DataStreamerpacket(包) 按队列输出到管道的第一个 datanode 中,第一个 datanode 又把 packet(包) 输出到第二个 datanode 中,以此类推。

5、DFSOutputStream 还有一个队列叫 ack quene ,也是由 packet(包) 组成,等待 datanode 收到的响应,当 pipeline(管道) 中的所有 datanode 都表示已经收到的时候,这时 ack quene 才会把对应的 packet(包) 移除掉。

​ 如果在写的过程中某个 datanode 发生错误,会采取以下几步:

​ 1)pipeline(管道) 被关闭掉;

​ 2)为了防止丢包 ack quene 里的 packet(包) 会同步到 data quene 里;

​ 3)把产生错误的 datanode 上当前在写但未完成的 block(块) 删掉;

​ 4)block(包) 剩下的部分被 写到剩下 的两个正常的 datanode 中;

​ 5)namenode 找到另外的 datanode 去创建这个块的复制。当然,这些操作对客户端来说是无感知的。

6、客户端完成写数据后调用 close 方法关闭写入流。

7、DataStreamer 把剩余的包都刷到 pipeline(管道) 里,然后等待 ack 信息,收到最后一个 ack 后,通知 datanode 把文件标视为已完成。

​ 注意:客户端执行 write 操作后,写完的 block 才是可见的 (注:和下面的一致性所对应),正在写的block对客户端是不可见的,只有 调用sync方法,客户端才确保该文件的写操作已经全部完成,当客户端调用close方法时,会默认调用sync方法。是否需要手动调用取决你根据程序需 要在数据健壮性和吞吐率之间的权衡

HDFS 读数据流程:

简易版

在这里插入图片描述

1)客户端向 namenode 请求下载文件, namenode 通过查询元数据,找到文件块所在的 datanode 地址。

2)namenode 挑选一个 datanode (就近原则,然后随机) 服务器,请求读取数据。

3)datanode 开始传输数据给客户端(从磁盘里面读取数据放入流,以 packet(包) 为单位来做校验)。

4)客户端以 packet(包) 为单位接受,先在本地缓存,然后写入目标文件。

复杂版

在这里插入图片描述

1、首先调用 FileSystem 对象的 open 方法,其实是一个 DistributedFileSystem 的实例。

2、DistributedFileSystem 通过 rpc(协议) 获得文件的第一批 block(块)locations(地址) ,同一个 block 按照重复数会返回多个locations(地点) ,这些 locations(地点) 按照 hadoop 拓扑结构排序,距离客户端近的排在前面。

3、前两步会返回一个 FSDataInputStream 对象,该对象会被封装 DFSInputStream 对象, DFSInputStream 可 以方便的管理 datanodenamenode 数据流。客户端调用 read 方法,DFSInputStream 最会找出离客户端最近的 datanode 并连接。

4、数据从 datanode 源源不断的流向客户端。

5、如果第一块的数据读完了,就会关闭指向第一块的 datanode 连接,接着读取下一块。这些操作对客户端来说是透明的,客户端的角度看来只是读一个持续不断的流。

7、如果在读数据的时候,DFSInputStreamdatanode 的通讯发生异常,就会尝试正在读的 block(块) 的排序第二近的 datanode,并且会记录哪个 datanode 发生错误,剩余的 blocks(包) 读的时候就会直接跳过该datanodeDFSInputStream 也会检查 block(包) 数据校验和,如果发现一个坏的 block(包),就会先报告到namenode 节点,然后 DFSInputStream 在其他的 datanode 上读该 block(包) 的镜像。

8、该设计就是客户端直接连接 datanode 来检索数据并且 namenode 来负责为每一个 block(包) 提供最优的datanodenamenode 仅仅处理 block location(地址) 的请求,这些信息都加载在 namenode 的内存中,hdfs 通过datanode 集群可以承受大量客户端的并发访问。

HDFS网络拓扑概念:

在本地网络中,两个节点被称为 “彼此近邻” 是什么意思?在海量数据处理中,其主要限制因素是节点之间数据的传输速率——带宽很稀缺。这里的想法是将两个节点间的带宽作为距离的衡量标准。

​ 节点距离:两个节点到达最近的共同祖先的距离总和。

​ 例如,假设有数据中心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(不同数据中心的节点)

在这里插入图片描述

HDFS机架感知:

低版本Hadoop副本节点选择

​ 第一个副本在client所处的节点上。如果客户端在集群外,随机选一个。

​ 第二个副本和第一个副本位于不相同机架的随机节点上。

​ 第三个副本和第二个副本位于相同机架,节点随机。

在这里插入图片描述

高版本副本节点选择

​ 第一个副本在client所处的节点上。如果客户端在集群外,随机选一个。

​ 第二个副本和第一个副本位于相同机架,随机节点。

​ 第三个副本位于不同机架,随机节点。

在这里插入图片描述

HDFS一致性模型:

代码调试:

/**
 * 想本地文件写入数据
 * @throws Exception
 */
@Test
public void WriteHDFS() throws Exception{

    //获取配置信息
    Configuration conf = new Configuration();

    //获取系统文件路径
    FileSystem fs = FileSystem.get(conf);

    //创建文件输出流
    FSDataOutputStream fos = fs.create(new Path("C:\\Users\\Jds\\Desktop\\HDFS\\jds.txt"));

    //写数据
    fos.write("hello world".getBytes());

    //一致性刷新
    fos.hflush();

    //关闭
    IOUtils.closeStream(fos);

    //提示
    System.out.println("写入成功!!!");
}

总结

​ 写入数据时,如果希望数据被其它 client(客户端) 立即可见,调用如下方法:

FSDataOutputStream. hflush (); //清理客户端缓冲区数据,被其他client立即可见

NameNode工作机制:

1、NameNode&Secondary NameNode 工作机制

在这里插入图片描述

​ 1)第一次启动 namenode 格式化后,会自动创建 fsimageedits 文件。如果不是第一次启动,直接加载 编辑日志(edits)镜像文件(fsimage) 到内存;

​ 2)客户端元数据 进行增删改查的请求;

​ 3)namenode 记录操作日志,更新滚动日志;

​ 4)namenode 在内存中对数据进行增删改查。

第二阶段:Secondary NameNode 工作

​ 1)Secondary NameNode 询问 namenode 是否需要 checkpoint(触发检查站) 。直接返回 namenode 是否检查的结果 ;

​ 2)Secondary NameNode 请求执行 checkpoint(触发检查站)

​ 3)namenode 滚动正在写的 edits 日志 ;

​ 4)将滚动前的 编辑日志镜像文件 拷贝到 Secondary NameNode

​ 5)Sencondary NameNode 加载 编辑日志镜像文件 到内存,并合并 ;

​ 6)生成新的 镜像文件 fsimage.checkpoint ;

​ 7)拷贝 fsimage.checkpoint ;

​ 8)namenodefsimage.checkpoint 重新命名成 fsimage

checkpoint 检查时间参数设置

​ 1)通常情况下,Secondary NameNode 每隔一小时执行一次。

​ [ hdfs-site.xml ]

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

​ 2)一分钟检查一次操作次数,当操作次数达到1百万时,Secondary NameNode 执行一次。

<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>

2、镜像文件和编辑日志文件

概念

namenode 被格式化之后,将在 /opt/module/hadoop-2.8.4/data/dfs/name/current 目录中产生如下文件,注只能在 NameNode 所在的节点才能找到此文件。

可以执行 find . -name edits* 来查找文件

<!--
edits_0000000000000000000
fsimage_0000000000000000000.md5
seen_txid
VERSION
-->

​ 1)fsimage 文件:HDFS 文件系统元数据的一个永久性的检查点,其中包含 HDFS 文件系统的所有目录和文件idnode的序列化信息。

​ 2)edits 文件:存放 HDFS 文件系统的所有更新操作的路径,文件系统客户端执行的所有写操作首先会被记录到 edits 文件中。

​ 3)seen_txid 文件保存的是一个数字,就是最后一个 edits_ 的数字

​ 4)每次 namenode 启动的时候都会将 fsimage 文件读入内存,并从 00001 开始到 seen_txid 中记录的数字依次执行每个 edits 里面的更新操作,保证内存中的元数据信息是最新的、同步的,可以看成 namenode 启动的时候就将 fsimageedits 文件进行了合并。

oiv 查看 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.8.4/data/dfs/name/current

[itstar@bigdata111 current]$ hdfs oiv -p XML -i fsimage_0000000000000000316 -o 
/opt/fsimage.xml

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

oev查看edits文件

​ 1)基本语法

<!--
hdfs oev -p(文件类型) -i(编辑日志) -o (转换后文件输出路径)

	-p	–processor <arg>	指定转换类型: binary (二进制格式), xml (默认,XML格式),stats
	-i	–inputFile <arg>	输入edits文件,如果是xml后缀,表示XML格式,其他表示二进制
	-o 	–outputFile <arg> 	输出文件,如果存在,则会覆盖
-->

​ 2)案例实操

<!--
[itstar@bigdata111 current]$ hdfs oev -p XML -i edits_0000000000000000135-0000000000000000135 -o /opt/module/hadoop-2.8.4/edits.xml -p stats

[itstar@bigdata111 current]$ cat /opt/module/hadoop-2.8.4/edits.xml
-->
<?xml version="1.0" encoding="UTF-8"?>
<EDITS>
  <EDITS_VERSION>-63</EDITS_VERSION>
  <RECORD>
    <OPCODE>OP_START_LOG_SEGMENT</OPCODE>
    <DATA>
      <TXID>29</TXID>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_END_LOG_SEGMENT</OPCODE>
    <DATA>
      <TXID>30</TXID>
    </DATA>
  </RECORD>
</EDITS>

<!--
每个RECORD记录了一次操作,比如图中的

OP_ADD代表添加文件操作、OP_MKDIR代表创建目录操作。里面还记录了

文件路径(PATH)

修改时间(MTIME)

添加时间(ATIME)

客户端名称(CLIENT_NAME)

客户端地址(CLIENT_MACHINE)

权限(PERMISSION_STATUS)等非常有用的信息 
-->

3、滚动编辑日志

​ 正常情况 HDFS 文件系统有更新操作时,就会滚动编辑日志。也可以用命令强制滚动编辑日志。

滚动编辑日志(前提必须启动集群)

<!--
[itstar@bigdata111 current]$ hdfs dfsadmin -rollEdits

举例:原文件名 edits_inprogress_0000000000000000321 执行以下命令后

[root@bigdata111 current]# hdfs dfsadmin -rollEdits

	Successfully rolled edit logs.
	New segment starts at txid 323
	edits_inprogress_0000000000000000321 => edits_inprogress_0000000000000000323
-->

镜像文件什么时候产生?

Namenode 启动时加载镜像文件和编辑日志 。

4、namenode版本号

查看namenode版本号

<!--
在/opt/module/hadoop-2.8.4/data/dfs/name/current这个目录下查看VERSION

[root@bigdata111 current]# cat 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
-->

namenode版本号具体解释

​ 1) namespaceIDHDFS 上,会有多个 namenode ,所以不同 namenodenamespaceID 是不同的,分别管理一组 blockpoolID

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

​ 3)cTime 属性标记了 namenode 存储系统的创建时间,对于刚刚格式化的存储系统,这个属性为 0 ;但是在文件系统升级之后,该值会更新到新的时间戳 。

​ 4)storageType 属性说明该存储目录包含的是 namenode 的数据结构 。

​ 5)blockpoolID :一个 block pool id 标识一个 block pool ,并且是跨集群的全局唯一。当一个新的Namespace 被创建的时候 (format过程的一部分) 会创建并持久化一个唯一 ID 。在创建过程构建全局唯一的 BlockPoolID 比人为的配置更可靠一些。NNBlockPoolID 持久化到磁盘中,在后续的启动过程中,会再次 load 并使用。

​ 6)layoutVersion 是一个负整数。通常只有 HDFS 增加新特性时才会更新这个版本号。

​ 7)storageID (存储ID):是 DataNodeID ,不唯一

5、SecondaryNameNode目录结构

Secondary NameNode 用来监控 HDFS 状态的辅助后台程序,每隔一段时间获取 HDFS 元数据的快照。

​ 在 /opt/module/hadoop-2.8.4/data/dfs/namesecondary/current 这个目录中查看 SecondaryNameNode 目录结构。

<!--

edits_0000000000000000001-0000000000000000002

fsimage_0000000000000000002

fsimage_0000000000000000002.md5

VERSION

-->

SecondaryNameNodenamesecondary/current 目录和主 namenodecurrent 目录的布局相同。

​ 好处:在主 namenode 发生故障时(假设没有及时备份数据),可以从 SecondaryNameNode 恢复数据。

​ 方法一:将 SecondaryNameNode 中数据拷贝到 namenode 存储数据的目录;

​ 方法二:使用 -importCheckpoint 选项启动 namenode 守护进程,从而将 SecondaryNameNode 中数据拷贝到 namenode 目录中。

案例实操:

<!--

模拟namenode故障,并采用方法一,恢复namenode数据

(1)kill -9 namenode进程

(2)删除namenode存储的数据(/opt/module/hadoop-2.8.4/data/dfs/name)
	rm -rf /opt/module/hadoop-2.8.4/data/dfs/name/*
		
		注:此时hadoop-daemon.sh stop namenode关闭NN,
		然后hadoop-daemon.sh start namenode重启NN,发现50070页面启动不了

(3)拷贝SecondaryNameNode中数据到原namenode存储数据目录
	cp -r /opt/module/hadoop-2.8.4/data/dfs/namesecondary/* /opt/module/hadoop-2.8.4/data/dfs/name/

(4)重新启动namenode
	sbin/hadoop-daemon.sh start namenode

-->

6、集群安全模式操作

概述

​ Namenode 启动时,首先将映像文件(fsimage)载入内存,并执行编辑日志(edits)中的各项操作。一旦在内存中成功建立文件系统元数据的映像,则创建一个新的fsimage文件和一个空的编辑日志。此时,namenode开始监听datanode请求。但是此刻,namenode运行在安全模式,即namenode的文件系统对于客户端来说是只读的。

​ 系统中的数据块的位置并不是由namenode维护的,而是以块列表的形式存储在datanode中。在系统的正常操作期间,namenode会在内存中保留所有块位置的映射信息。在安全模式下,各个datanode会向namenode发送最新的块列表信息,namenode了解到足够多的块位置信息之后,即可高效运行文件系统。

​ 如果满足“最小副本条件”,namenode会在30秒钟之后就退出安全模式。所谓的最小副本条件指的是在整个文件系统中99.9%的块满足最小副本级别(默认值:dfs.replication.min=1)。在启动一个刚刚格式化的HDFS集群时,因为系统中还没有任何块,所以namenode不会进入安全模式。

基本语法

​ 集群处于安全模式,不能执行重要操作(写操作)。集群启动完成后,自动退出安全模式。

<!--
(1)bin/hdfs dfsadmin -safemode get		(功能描述:查看安全模式状态)

(2)bin/hdfs dfsadmin -safemode enter  	(功能描述:进入安全模式状态)

(3)bin/hdfs dfsadmin -safemode leave	(功能描述:离开安全模式状态)

(4)bin/hdfs dfsadmin -safemode wait		(功能描述:等待安全模式状态)
-->

案例

​ 模拟等待安全模式

<!--
	1)先进入安全模式
		bin/hdfs dfsadmin -safemode enter
	
	2)执行下面的脚本
		编辑一个脚本(注:必须已设置环境变量,要不就写绝对路径)
		#!bin/bash
		hdfs dfsadmin -safemode wait
		hadoop fs -put /opt/BBB /

	3)再打开一个窗口,执行
		bin/hdfs dfsadmin -safemode leave
-->

7、Namenode多目录配置

​ namenode的本地目录可以配置成多个,且每个目录存放内容相同,增加了可靠性

具体部署如下:

​ 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.	停止集群 删除data 和 logs  rm -rf data/* logs/*
2.	hdfs namenode -format
3.	start-dfs.sh
4.	去展示
https://blog.csdn.net/qq_39657909/article/details/85553525

实验总结:
	思考1:如果在非Namenode节点、进行格式化(hdfs namenode -format)是否和在NN节点上同样会生成name1和name2目录呢?
    答:只要配置了以上得配置,在该节点下同样会生成name1和name2

具体解释:
	格式化做了哪些事情?
	在NameNode节点上,有两个最重要的路径,分别被用来存储元数据信息和操作日志,而这两个路径来自于配置文件,它们对应的属性分别是dfs.name.dir和dfs.name.edits.dir,同时,它们默认的路径均是/tmp/hadoop/dfs/name。格式化时,NameNode会清空两个目录下的所有文件,之后,格式化会在目录dfs.name.dir下创建文件
	hadoop.tmp.dir 这个配置,会让dfs.name.dir和dfs.name.edits.dir会让两个目录的文件生成在一个目录里

	思考2:非NN上如果生成了name1和name2,那么他和NN上生成得有没有差别?
	答:有区别、NN节点上会产生新得edits_XXX,非NN不会fsimage会更新,而非NN不会,只会产生一个仅初始化得到得fsimage,不会生成edits,更不会发生日志滚动。
-->

DataNode工作机制:

1、NameNode& DataNode工作机制

在这里插入图片描述

​ 1)一个数据块在datanode上以文件形式存储在磁盘上,包括两个文件,一个是数据本身,一个是元数据包括数据块的长度,块数据的校验和,以及时间戳。

​ 2)DataNode启动后向namenode注册,通过后,周期性(1小时)的向namenode上报所有的块信息。

​ 3)心跳是每3秒一次,心跳返回结果带有namenode给该datanode的命令如复制块数据到另一台机器,或删除某个数据块。如果超过10分钟没有收到某个datanode的心跳,则认为该节点不可用。

​ 4)集群运行中可以安全加入和退出一些机器

2 、数据完整性

​ 1)当DataNode读取block的时候,它会计算checksum校验和

​ 2)如果计算后的checksum,与block创建时值不一样,说明block已经损坏。

​ 3)client读取其他DataNode上的block.

​ 4)datanode在其文件创建后周期验证checksum校验和

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>	<!--  5分钟  !>
</property>
<property>
    <name> dfs.heartbeat.interval </name>
    <value>3</value>		<!--  3秒  !>
</property>

4、 DataNode的目录结构

​ 和namenode不同的是,datanode的存储目录是初始阶段自动创建的,不需要额外格式化。

​ 1)在/opt/module/hadoop-2.8.4/data/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)具体解释

​ (1)storageID:存储id号

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

​ (3)cTime属性标记了datanode存储系统的创建时间,对于刚刚格式化的存储系统,这个属性为0;但是在文件系统升级之后,该值会更新到新的时间戳。

​ (4)datanodeUuid:datanode的唯一识别码

​ (5)storageType:存储类型

​ (6)layoutVersion是一个负整数。通常只有HDFS增加新特性时才会更新这个版本号。

3)在/opt/module/hadoop-2.8.4/data/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)具体解释

​ (1)namespaceID:是datanode首次访问namenode的时候从namenode处获取的storageID对每个datanode来说是唯一的(但对于单个datanode中所有存储目录来说则是相同的),namenode可用这个属性来区分不同datanode。

​ (2)cTime属性标记了datanode存储系统的创建时间,对于刚刚格式化的存储系统,这个属性为0;但是在文件系统升级之后,该值会更新到新的时间戳。

​ (3)blockpoolID:一个block pool id标识一个block pool,并且是跨集群的全局唯一。当一个新的Namespace被创建的时候(format过程的一部分)会创建并持久化一个唯一ID。在创建过程构建全局唯一的BlockPoolID比人为的配置更可靠一些。NN将BlockPoolID持久化到磁盘中,在后续的启动过程中,会再次load并使用。

​ (4)layoutVersion是一个负整数。通常只有HDFS增加新特性时才会更新这个版本号。

5、 Datanode多目录配置

1)datanode也可以配置成多个目录,每个目录存储的数据不一样。即:数据不是副本。

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的保护机制:

1、集群间数据拷贝

​ 1)scp实现两个远程主机之间的文件复制

​ scp -r hello.txt root@bigdata111:/user/itstar/hello.txt // 推 push

​ scp -r [root@bigdata112:/user/itstar/hello.txt hello.txt](mailto:root@hadoop103:/user/atguigu/hello.txt hello.txt) // 拉 pull

​ 2)采用discp命令实现两个hadoop集群之间的递归数据复制(注:不用设置其他,直接写IP)

​ bin/hadoop distcp hdfs://192.168.1.51:9000/LICENSE.txt hdfs://192.168.1.111:9000/HAHA

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目录是一个整体,该目录看成是一个归档文件即可。

在这里插入图片描述

用法:hadoop archive -archiveName 归档名称 -p 父目录 [-r <复制因子>] 原路径(可以多个) 目的路径

bin/ hadoop archive -archiveName foo.har -p /Andy -r 3 a b c /

​ (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

​ 并行解压缩:hadoop distcp har:/foo.har /001

3、 快照管理

​ 快照相当于对目录做一个备份。并不会立即复制所有文件,而是指向同一个文件。当写入发生时,才会产生新文件。

​ 1)基本语法

​ (1)hdfs dfsadmin -allowSnapshot 路径 (功能描述:开启指定目录的快照功能)

​ (2)hdfs dfsadmin -disallowSnapshot 路径 (功能描述:禁用指定目录的快照功能,默认是禁用)

​ (3)hdfs dfs -createSnapshot 路径 (功能描述:对目录创建快照)

​ (4)hdfs dfs -createSnapshot 路径 名称 (功能描述:指定名称创建快照)

​ (5)hdfs dfs -renameSnapshot 路径 旧名称 新名称 (功能描述:重命名快照)

​ (6)hdfs lsSnapshottableDir (功能描述:列出当前用户所有已快照目录)

​ (7)hdfs snapshotDiff 路径1 路径2 (功能描述:比较两个快照目录的不同之处)

​ (8)hdfs dfs -deleteSnapshot (功能描述:删除快照)

​ 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)重命名快照(注:快照是只读的,无法修改名)

​ (√) dfs -renameSnapshot /Andy/ andy bndy

​ 注:路径只是你创建得名字/Andy,不要带后边得/Andy/.snapshot/,不然会出现

​ renameSnapshot: Modification on a read-only snapshot is disallowed

​ (5)列出当前用户所有可快照目录

​ hdfs lsSnapshottableDir

​ (6)比较两个快照目录的不同之处

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

​ (7)恢复快照

​ 1. 自定义创建一个快照名:hdfs dfs -createSnapshot /HAHA1 miaomiao

​ 2. 展示原文件包含内容:Hadoop fs -ls /HAHA1

​ 3. 里面有五个文件、删除其中1~2个

​ /HAHA1/.snapshot/miaomiao1

​ 4. 回复快照:hdfs dfs -cp /HAHA1/.snapshot/miaomiao1 /miaomiao

​ (8)删除快照

​ hdfs dfs -deleteSnaphost /001名字

4、 回收站

​ 1)默认回收站

​ 默认值fs.trash.interval=0,0表示禁用回收站,可以设置删除文件的存活时间。

​ 默认值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

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Hadoop分布式文件系统HDFS)是Hadoop的核心组件之一,它是一个分布式文件系统,旨在存储大量数据,并提供高吞吐量数据访问。HDFS采用管理者-工作者模式运行,其中一个NameNode(管理者)和多个DataNode(工作者)组成集群。NameNode负责管理文件系统命名空间,以及控制客户端对文件的访问。DataNode负责存储实际的数据块,并响应客户端读写请求。 HDFS的主要特点包括: - 高容错性:HDFS采用数据复制的方式来实现容错性,即将数据块复制到多个DataNode上,以保证即使某个节点出现故障,数据仍然可用。 - 适合大数据存储:HDFS适合存储大量数据,因为它可以将数据划分为多个数据块,并将这些数据块分布在不同的DataNode上,以实现并行处理。 - 流式数据访问:HDFS支持流式数据访问,即一次性读取或写入大量数据,而不是随机访问。 - 可扩展性:HDFS可以通过添加更多的DataNode来扩展存储容量和吞吐量。 下面是HDFS的一些常用命令: - hdfs dfs -ls /:列出根目录下的所有文件和目录。 - hdfs dfs -mkdir /test:在根目录下创建一个名为test的目录。 - hdfs dfs -put localfile /test:将本地文件localfile上传到HDFS的/test目录下。 - hdfs dfs -get /test/remotefile localfile:将HDFS上的/test/remotefile文件下载到本地文件localfile中。 - hdfs dfs -rm /test/remotefile:删除HDFS上的/test/remotefile文件

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值