【03】HDFS

39_尚硅谷_Hadoop_HDFS_课程介绍

在这里插入图片描述

40_尚硅谷_Hadoop_HDFS_产生背景和定义

在这里插入图片描述
HDFS就是为了解决海量数据的存储问题
分布式存储:就是利用多台服务器来解决同一件事,每个服务器用来存储一部分数据。
在这里插入图片描述

41_尚硅谷_Hadoop_HDFS_优缺点

hdfs擅长的是:快速把数据存进去,然后查询。只适合查询,数据量越大越有优势
适合大文件,不适合小文件低延时数据存储
在这里插入图片描述
在这里插入图片描述

42_尚硅谷_Hadoop_HDFS_组成

hadoop官方文档
https://hadoop.apache.org/docs/r3.1.3/

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2NN也只能起到辅助作用,也只是恢复一部分数据。因为秘书知道的事情跟老板知道的事情还是有一定的差距,那差距的那部分数据就是损失的数据。
对于客户端:NameNode是告诉你允许不允许读,或者说我这机器上有没有,这些都是namenode说的算。那实际来干活和对接的是DataNode。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

43_尚硅谷_Hadoop_HDFS_文件块大小

在公司当中,主流的块大小有两种:128M(中小型企业)、256M(大厂)
在这里插入图片描述
在这里插入图片描述
未来计算的单元是以块来计算的
在这里插入图片描述
在这里插入图片描述

44_尚硅谷_Hadoop_HDFS_Shell命令上传

在这里插入图片描述
一般会选择hadoop fs,因为这个简洁
在这里插入图片描述

在根目录下创建sanguo文件夹
hadoop fs -mkdir /sanguo

在这里插入图片描述
在这里插入图片描述

-moveFromLocal:从本地剪切粘贴到HDFS
 hadoop fs -moveFromLocal shuguo.txt /sanguo

在这里插入图片描述
在这里插入图片描述

-copyFromLocal:从本地文件系统中拷贝文件到HDFS路径去
hadoop fs -copyFromLocal weiguo.txt /sanguo

在这里插入图片描述
在这里插入图片描述

-put:等同于copyFromLocal,生产环境更习惯用put
hadoop fs -put wuguo.txt /sanguo

在这里插入图片描述
在这里插入图片描述

-appendToFile:追加一个文件到已经存在的文件末尾(只能追加,不能后续的修改)
hadoop fs -appendToFile liubei.txt /sanguo/shuguo.txt

在这里插入图片描述

45_尚硅谷_Hadoop_HDFS_Shell命令下载&直接操作

在这里插入图片描述
常用-get,比较简洁
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1)-ls: 显示目录信息
 hadoop fs -ls /
 hadoop fs -ls /sanguo

在这里插入图片描述

2)-cat:显示文件内容
hadoop fs -cat /sanguo/shuguo.txt

在这里插入图片描述

3)-chgrp、-chmod、-chown:Linux文件系统中的用法一样,修改文件所属权限
hadoop fs -chown atguigu:atguigu /sanguo/shuguo.txt

在这里插入图片描述

4)-mkdir:创建路径
hadoop fs -mkdir /jinguo

在这里插入图片描述
在这里插入图片描述

5)-cp:从HDFS的一个路径拷贝到HDFS的另一个路径
 hadoop fs -cp /sanguo/shuguo.txt /jinguo

在这里插入图片描述
在这里插入图片描述

6)-mv:在HDFS目录中移动文件
hadoop fs -mv /sanguo/weiguo.txt /jinguo
hadoop fs -mv /sanguo/wuguo.txt /jinguo

在这里插入图片描述

7)-tail:显示一个文件的末尾1kb的数据
hadoop fs -tail /jingguo/shuguo.txt

在这里插入图片描述
在这里插入图片描述

8)-rm:删除文件或文件夹
hadoop fs -rm /sanguo/shuguo.txt

在这里插入图片描述
在这里插入图片描述

9)-rm -r:递归删除目录及目录里面内容
hadoop fs -rm -r /sanguo

在这里插入图片描述
在这里插入图片描述

10)-du统计文件夹的大小信息
 hadoop fs -du -s -h /jinguo

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

副本里面是每台机器只能存储其中的一块副本,它不会重复的存,因为重复的存没有意义

11)-setrep:设置HDFS中文件的副本数量
hadoop fs -setrep 10 /jinguo/shuguo.txt

46_尚硅谷_Hadoop_HDFS_API环境准备

在这里插入图片描述
要使windows能够连接到远程的Hadoop集群,那么windows这边也得有相关的Hadoop环境变量
在这里插入图片描述

在这里插入图片描述

E:\HadoopEnvironmentData\hadoop-3.1.0

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在IDEA中创建一个Maven工程HdfsClientDemo,并导入相应的依赖坐标+日志添加
在这里插入图片描述

<dependencies>
    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-client</artifactId>
        <version>3.1.3</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.7.30</version>
    </dependency>
</dependencies>

在项目的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

创建包名:com.atguigu.hdfs、创建HdfsClient类
在这里插入图片描述

47_尚硅谷_Hadoop_HDFS_API创建文件夹

客户端是跟namenode打交道

package com.atguigu.hdfs;

import com.sun.org.apache.xml.internal.utils.URI;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.junit.Test;

import java.io.IOException;
import java.net.URISyntaxException;

/*
客户端代码常用套路
1、获取一个客户端对象
2、执行相关的操作命令
3、关闭资源
HDFS zookeeper
*/

public class HdfsClient {
    @Test
    public void testmkdir() throws IOException, URISyntaxException {
        /*
            new URI("hdfs://hadoop102:8020").var
            alt+回车:抛个异常
        */

        // 连接的集群Namenode的地址:8020是内部的地址
        java.net.URI uri = new java.net.URI("hdfs://192.168.10.102:8020");

        //创建一个配置文件
        Configuration configuration = new Configuration();

        /*
            注意FileSystem是在hadoop包下,别导错了(没有的鼠标对着FileSystem按alt+enter导入包)
            ctrl+p:提示参数
        */

        //用户
        String user="atguigu";

        //1、获取到了客户端对象
        FileSystem fs = FileSystem.get(uri, configuration,user);

        //2、创建一个文件夹
        fs.mkdirs(new Path("/xiyou/huaguoshan"));

        //3、关闭资源
        fs.close();
    }

}

如果 FileSystem fs = FileSystem.get(uri, configuration,user);中不添加user,将会报如下的异常:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
添加user后执行完成之后,打开HDFS网页,会出现xiyou文件夹

在这里插入图片描述

//换一种写法:junit的@after、@before、@test

package com.atguigu.hdfs;
import com.sun.org.apache.xml.internal.utils.URI;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.net.URISyntaxException;

/*
客户端代码常用套路
1、获取一个客户端对象
2、执行相关的操作命令
3、关闭资源
HDFS zookeeper
*/

public class HdfsClient {

    private FileSystem fs;  //升级为全局变量

    @Before
    public void init() throws URISyntaxException, IOException, InterruptedException {
        // 连接的集群Namenode的地址:8020是内部的地址
        java.net.URI uri = new java.net.URI("hdfs://192.168.10.102:8020");

        //创建一个配置文件
        Configuration configuration = new Configuration();

        //用户
        String user="atguigu";

        //1、获取到了客户端对象
        // ctrl+alt+f:将fs变成全局变量
        fs = FileSystem.get(uri, configuration,user);
    }

    @After
    public void close() throws IOException {
        //3、关闭资源
        fs.close();
    }

    @Test
    public void testmkdir() throws Exception {
        //2、创建一个文件夹huaguoshan1
        fs.mkdirs(new Path("/xiyou/huaguoshan1"));

        //fs.mkdirs(new Path("/xiyou/huaguoshan1"));
    }

    /*执行顺序:
        首先执行before,执行完before之后再执行Test,Test结束之后再执行after
    */
}

在这里插入图片描述

48_尚硅谷_Hadoop_HDFS_API上传

(1)查看帮助
    hdfs dfs -help 
    
(2)查看当前目录信息
    hdfs dfs -ls /
    
(3)上传文件
    hdfs dfs -put /本地路径 /hdfs路径
    
(4)剪切文件
    hdfs dfs -moveFromLocal a.txt /aa.txt
    
(5)下载文件到本地
    hdfs dfs -get /hdfs路径 /本地路径
    
(6)合并下载
    hdfs dfs -getmerge /hdfs路径文件夹 /合并后的文件
    
(7)创建文件夹
    hdfs dfs -mkdir /hello
    
(8)创建多级文件夹
    hdfs dfs -mkdir -p /hello/world
    
(9)移动hdfs文件
    hdfs dfs -mv /hdfs路径 /hdfs路径
    
(10)复制hdfs文件
    hdfs dfs -cp /hdfs路径 /hdfs路径
    
(11)删除hdfs文件
    hdfs dfs -rm /aa.txt
    
(12)删除hdfs文件夹
    hdfs dfs -rm -r /hello
    
(13)查看hdfs中的文件
    hdfs dfs -cat /文件
    hdfs dfs -tail -f /文件
    
(14)查看文件夹中有多少个文件
    hdfs dfs -count /文件夹
    
(15)查看hdfs的总空间
    hdfs dfs -df /
    hdfs dfs -df -h /
    
(16)修改副本数    
    hdfs dfs -setrep 1 /a.txt

在这里插入图片描述

用客户端进行远程访问HDFS,然后上传文件
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

49_尚硅谷_Hadoop_HDFS_API参数的优先级


在这里插入图片描述

1)编写源代码
@Test
public void testCopyFromLocalFile() throws IOException, InterruptedException, URISyntaxException {

    // 1 获取文件系统
    Configuration configuration = new Configuration();
    configuration.set("dfs.replication", "2");
    FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:8020"), configuration, "atguigu");

    // 2 上传文件
    fs.copyFromLocalFile(new Path("d:/sunwukong.txt"), new Path("/xiyou/huaguoshan"));

    // 3 关闭资源
    fs.close();2)将hdfs-site.xml拷贝到项目的resources资源目录下
<?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>

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
优先级一般是就近原则
在这里插入图片描述
最高优先级是代码里面,其次是资源目录,再往前是hdfs-site.xml,然后最后是hdfs-defaule.xml

50_尚硅谷_Hadoop_HDFS_API文件下载

下载就是从HDFS里面把数据下载到我们windows本地
在这里插入图片描述
在这里插入图片描述

crc:循环校验文件,检错用的。目的是为了保证从hdfs传输过来的数据不会发生错误

最后一个参数userRalLocalFileSystem表示的是否开启本地模式(即是否开启本地校验crc,如果是true则开启本地校验,从hdfs下载下来的文件夹中会多出来一个以.crc结尾的文件,即循环校验文件;如果是false则下载下来的文件中没有循环校验文件)。这里可以不写,不用管它。

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

    // 1 获取文件系统
    Configuration configuration = new Configuration();
    FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:8020"), configuration, "atguigu");
    
    // 2 执行下载操作
    // boolean delSrc 指是否将原文件删除
    // Path src 指要下载的文件路径
    // Path dst 指将文件下载到的路径
    // boolean useRawLocalFileSystem 是否开启文件校验
    fs.copyToLocalFile(false, new Path("/xiyou/huaguoshan/sunwukong.txt"), new Path("d:/sunwukong2.txt"), true);
    
    // 3 关闭资源
    fs.close();
}

51_尚硅谷_Hadoop_HDFS_API文件删除

在这里插入图片描述
FileSystem.get里面已经设置URI了,后面的都是相对根目录的路径

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

	// 1 获取文件系统
	Configuration configuration = new Configuration();
	FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:8020"), configuration, "atguigu");
		
	// 2 执行删除
	fs.delete(new Path("/xiyou"), true);
		
	// 3 关闭资源
	fs.close();
}

52_尚硅谷_Hadoop_HDFS_API文件更名和移动

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

	// 1 获取文件系统
	Configuration configuration = new Configuration();
	FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:8020"), configuration, "atguigu"); 
		
	// 2 修改文件名称
	fs.rename(new Path("/xiyou/huaguoshan/sunwukong.txt"), new Path("/xiyou/huaguoshan/meihouwang.txt"));
		
	// 3 关闭资源
	fs.close();
}

53_尚硅谷_Hadoop_HDFS_API文件详情查看

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
那么通过客户端能不能拿到我这个文件存在那几个块上呢?也就是块信息的存储拿不拿得到?
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

	// 1获取文件系统
	Configuration configuration = new Configuration();
	FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:8020"), configuration, "atguigu");

	// 2 获取文件详情
	RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/"), true);

	while (listFiles.hasNext()) {
		LocatedFileStatus fileStatus = listFiles.next();

		System.out.println("========" + fileStatus.getPath() + "=========");
		System.out.println(fileStatus.getPermission());
		System.out.println(fileStatus.getOwner());
		System.out.println(fileStatus.getGroup());
		System.out.println(fileStatus.getLen());
		System.out.println(fileStatus.getModificationTime());
		System.out.println(fileStatus.getReplication());
		System.out.println(fileStatus.getBlockSize());
		System.out.println(fileStatus.getPath().getName());

		// 获取块信息
		BlockLocation[] blockLocations = fileStatus.getBlockLocations();
		System.out.println(Arrays.toString(blockLocations));
	}
	// 3 关闭资源
	fs.close();
}

54_尚硅谷_Hadoop_HDFS_API文件和文件夹判断

在这里插入图片描述
Ctrl+L:进行代码格式化
在这里插入图片描述
在这里插入图片描述

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

    // 1 获取文件配置信息
    Configuration configuration = new Configuration();
    FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:8020"), 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();
}

55_尚硅谷_Hadoop_HDFS_写数据流程

本节内容讲的是:我从客户端如何将数据写到HDFS集群的
既考虑了节点距离最近,有考虑了负载均衡(就近原则和负载均衡)
在这里插入图片描述
老师传给班长,班长传给组长,一层一层慢慢传比较好(串行)。如果是方案1,当一个DataNode结点没有传输,outputStrame还要继续等待,一直等到所有结点传输完成。

在这里插入图片描述
每个DataNode内部既向其它DataNode传输数据,又同时将写入磁盘,这样效率很高。(一边写一边出)
先是形成chunk,等达到64k过后就形成packet。形成一个一个packet之后,这个packet就发送到下一个DataNode
在这里插入图片描述
上游ack队列,进行判断应答是否成功

/*
(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步)。
*/

56_尚硅谷_Hadoop_HDFS_节点距离计算

在这里插入图片描述

网络拓扑-节点距离计算:
是到达共同祖先的步数和;
画一个树就知道了,同一个机器上的节点都是兄弟
就是到达同一个祖先所要连接线的个数
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

57_尚硅谷_Hadoop_HDFS_机架感知(副本存储节点选择)

一般情况下,它会选择你在哪台服务器上提交,我就优先选择谁
(机架感知的前提是,配置了机架感知系统)
在这里插入图片描述
在这里插入图片描述
第一个机架我选择本地,考虑的是结点距离最近,我上传速度最快;第二个数据为什么跑别的机架上去传了?保证了你的数据的可靠性,同时又要兼顾对应的效率,同机架内部传输比你跨机架传输网络速度要快一些。
在这里插入图片描述

58_尚硅谷_Hadoop_HDFS_读数据流程

客户端向NameNode请求,它要读取数据。为什么客户端不直接请求DataNode?因为NameNode是HDFS的老大,得问NameNode能不能读?那么客户端得创建一个客户端对象(分布式文件系统对象),类似于一个谈判代表跟NameNode交涉。最后还要创建一个FSDataInputStream数据流对象来对应读数据,它选择读取数据的原则是:首先选择结点距离最近的读,同时还会考虑当前这个结点的负载均衡能力。它是串行读取数据。
在这里插入图片描述

59_尚硅谷_Hadoop_HDFS_NN和2NN工作机制

在这里插入图片描述
在这里插入图片描述

内存:断电丢失
存储在磁盘里我们一般用fsimage(快照)来存储数据
Edits只记录你的过程,不给你进行计算
关机的时候才将fsimage和Edits进行合并,效率比较低
2NN将fsimage和Edits文件进行定期的进行合并(即做了一些我合并一些)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
当对元数据进行增删改请求,假如先更改内存再记账,如果断电了,edits_inprogress没有记录这条数据,那么整个这条数据就丢了。所以说非常严谨的办法就是先记账到edits_inprogress,然后再加载到内存。未来edits_inprogress和fsimage进行合并,就是当前内存当中最新的数据,也就是这条数据它不会丢。
在这里插入图片描述

重要提示:每当元数据有更新或者添加元数据时,修改内存中的元数据并追加到Edits中。
在这里插入图片描述

60_尚硅谷_Hadoop_HDFS_FsImage镜像文件

原始记录+日志记录=fsimage+edits=数据库常规操作
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
打开fsimage.txt文件里面对应的是根目录下对应的文件存储信息
在这里插入图片描述

61_尚硅谷_Hadoop_HDFS_Edits编辑日志

在这里插入图片描述
Edits的特点是:只进行追加,不进行合并修改
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

62_尚硅谷_Hadoop_HDFS_检查点时间设置

检查点设置就是:2NN给NN说需不需要进行合并,进行检查。这个时候的触发事件
在这里插入图片描述
在这里插入图片描述

63_尚硅谷_Hadoop_HDFS_DN工作机制

本节主要将老板和员工是如何工作的
在这里插入图片描述
在这里插入图片描述

64_尚硅谷_Hadoop_HDFS_数据完整性

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

65_尚硅谷_Hadoop_HDFS_掉线时限参数设置

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

66_尚硅谷_Hadoop_HDFS_总结

在这里插入图片描述
开发用到最多的是它的shell操作,而API用的少

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值