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,并导入相应的依赖坐标+日志添加

org.apache.hadoop

hadoop-client

3.1.3

junit

junit

4.12

org.slf4j

slf4j-log4j12

1.7.30

在项目的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资源目录下

dfs.replication

1

优先级一般是就近原则 最高优先级是代码里面,其次是资源目录,再往前是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 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用的少

推荐阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: