HDFS(学习笔记)(1)

清除测试数据


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9ugWw4fV-1629014721326)(C:\Users\WANG\AppData\Roaming\Typora\typora-user-images\image-20210814204225595.png)]

HDFS文件写入过程


  1. Client发起文件上传请求,通过RPC与NameNode建立通讯,NameNode检查目标文件是否存在,父目录是否存在,返回是否可以上传

  2. Client请求第一个block该传输到哪些DataNode服务器上

  3. NameNode根据配置文件中指定的被封数量及机架感知原理进行文件分配,返回可用的DataNode地址如:A,B,C

Hadoop在设计时3考虑到数据的安全与高效,数据文件默认在HDFS上存放三份,存储测量为本地一份,同机机架内其他某一节点上一份,不同机架的某一节点上一份。

  1. Client请求3台DataNode中的一台A上传数据(本质上是一个RPC调用,建立pipeline),A收到请求会继续调用B,然后B调用C,将整个pipeline建立完成,后逐级返回client

  2. Client开始往A上传第一个block(先从磁盘读取数据放到一个本地内存缓存),以packet为单位(默认64K),A收到一个packet就会传给B,B传给C,A每传爱一个packet会放入一个应答队列等待应答

  3. 数据被分割成一个个packet数据包在pipeline上依次传输,在pipeline反方向上,逐个发送ack(命令正确应答),最终由pipeline中第一个DataNode节点A将pipelineack发送给Client

  4. 当一个block传输完成之后,Client再吃请求NameNode上传第二个block到服务1

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pMBOpW5h-1629014721326)(C:\Users\WANG\AppData\Roaming\Typora\typora-user-images\image-20210814205646759.png)]

HDFS文件读取过程


  1. Client向NameNode发起RPC请求,来确定请求文件block所在的位置

  2. NameNode会视情况返回文件的部分或者全部block列表,对于每个block,NameNode都会返回含有该block副本的DataNode地址;这些返回的DN地址,会按照集群拓扑结构得出DataNode与客户端的距离,然后进行排序,排序两个规则:网络拓扑结构中距离Client近的排靠前;心跳机制中超时汇报的DN状态为STALE,这样的排靠后

  3. Client选取排序靠前的DataNode来读取block,然后客户端本身就是DataNode,那么将从本地直接获取数据(短路读取特性)

  4. 底层上本质是建立Socket Stream(FSDataInputStream),重复的的调用父类DataInputStream的read方法,直到这个块上的数据读取完毕;

  5. 当读完列表的block后,若文件读取还没有结束,客户端会继续想NameNode获取下一批block列表;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IOiRiZ3H-1629014721327)(C:\Users\WANG\AppData\Roaming\Typora\typora-user-images\image-20210814212944070.png)]

HDFS的元数据辅助管理


当Hadoop的集群当中,NameNode的所有元数据信息都保存到FsImage与Eidts文件当中,这两个文件啊就记录了所有的是数据的元数据信息,元数据信息的保存目录配置在了hdfs-site.xml当中

dfs.namenode.name.dir

file:///export/servers/hadoop2.7.5/hadoopDatas/namenodeDatas,file:///export/servers/hadoop-2.7.5/hadoopDatas/namenodeDatas2

dfs.namenode.edits.dir

file:///export/servers/hadoop-2.7.5/hadoopoDatas/nn/edits

FsImage和Edits详解


edits

  • edits存放了客户端最近一段时间的操作日志

  • 客户端对HDFS进行写文件时会首先记录在edits文件中

  • edits修改时元数据也会更新

fsimage

  • NameNode中关于元数据的镜像,一般称为检查点,fsimage存放了一份比较完整的元数据信息

  • 因为fsimage是NameNode的完整的镜像,如果每次加载到内存生成树拓扑结构,这是非常耗内存和CPU,所以一般开始时对NameNode的操作都放在edits中

  • fsimage内容包含了NameNode管理下的所有DataNode文件及文件block及block所在的DataNode的元数据信息

  • 随着edits内容增大,就需要一定时间点和fsimage合并

fsimage中的文件信息查看

使用命令 hdfs oiv

cd /export/servers/hadoop2.7.5/hadoopDatas/namenodeDatas

hdfs oiv -i fsimage_0000000000000000864 -p XML -o hello.xml

edits中的文件信息查看

使用命令 hdfs oev

cd /export/servers/hadoop2.7.5/hadoopDatas/namenodeDatas

hdfs oev -i edits_0000000000000000865-0000000000000000866 -p XML -o myedit.xml

SecondaryNameNode如何辅助管理fsimage与edits文件?


  • SecondaryNameNode定期合并fsimage和edits,把edits控制在一个范围内

  • 配置SecondaryNameNode

  • SecondayNameNode在conf/masters中指定

  • 在masters指定的机器上,修改hdfs-site.xml

dfs.http.address

host:50070

  • 修改core-site.xml,这一步不做配置保持默认也可以

//多久记录一次 HDFS镜像,默认1小时

fs.checkpoint.period

3600

//一次记录多大,默认64M

fs.checkpoint

67108864

  1. SecondaryNameNode通知NameNode切换editlog

  2. SecondaryNameNode从NameNode中获得fsimage和editlog(通过http方式)

  3. SecondaryNameNode将fsimage载入内存,然后开始合并editlog,合并之后称为新的fsimage

  4. SecondaryNameNode将新的fsimage发回给NameNode

  5. NameNode用新的fsimage替换旧的fsimage

特点

完成合并的SecondaryNameNode,会请求NameNode停止使用edits,暂时将新鞋操作放入一个新的文件夹中edits_new

Hadoop核心-HDFS

==============================================================================

HDFS的API操作


配置Window下的Hadoop环境

在windows系统需要配置hadoop运行环境,否则直接运行代码会出现以下问题

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BXzJTdOh-1629014721328)(C:\Users\WANG\AppData\Roaming\Typora\typora-user-images\image-20210814233506617.png)]

步骤:

第一步:将hadoop2.7.5文件夹拷贝到一个没有中文没有空格的路径下面

第二步:在windows上面配置hadoop的环境变量:HADOOP_HOME,并将%HADOOP_HOME%\bin添加到path中

第三步:把hadoop2.7.5文件夹中bin目录下的hadoop.dll文件放到系统盘:C:\Window\System32目录

第四步:关闭windows重启

导入Maven依赖

org.apache.hadoop

hadoop-common

2.7.5

org.apache.hadoop

hadoop-client

2.7.5

org.apache.hadoop

hadoop-hdfs

2.7.5

org.apache.hadoop

hadoop-mapreduce-client-core

2.7.5

使用url方式访问数据(了解)


@Test

public void demo1() throws Exception{

//第一步:注册hdfs的url

URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());

//获取文件输入流

InputStream inputStream = new URL(“hdfs://node01:8020/a.txt”).openStream();

//获取文件输出流

FileOutputStream outputStream = new FileOutputStream(new File(“D:\hello.txt”));

//实现文件的拷贝

IOUtils.copy(inputStream,outputStream);

//关闭流

IOUtils.closeQuietly(inputStream);

IOUtils.closeQuietly(outputStream);

}

使用文件系统方式访问数据(掌握)


涉及的主要类

在Java中操作HDFS,主要涉及一下class:

Configuration

  • 该类的对象封装了客户端或者服务器的配置

FileSystem

该类的对象是一个文件系统对象,可以用该对象的一些方法来对文件进行操作,通过FileSystem的静态方法get获得该对象

FileSystem fs = FileSystem.get(conf)

get方法从conf中的一个参数fs.defaultFS的配置值判断具体是什么类

如果我们的代码中没有指定fs.defaultFS,并且工程ClassPath下也没有给定相应的配置,conf中的默认值就来自于Hadoop的Jar包中的core-default.xml

默认值为file:///,则获取的不是一个DistributedFileSystem的实例,而是一个本地文件系统的客户端对象

获取FileSystem的几种方式


第一种方式

@Test

public void getFileSystem1() throws IOException{

//创建Configuration对象

Configuration configuration = new Configuration();

//指定我们使用的文件系统类型

configuration.set(“fs.defaultFS”,“hdfs://node01:8020/”);

//获取指定的文件系统

FileSystem fileSystem = FileSystem.get(configuration);

System.out.println(fileSystem.toString());

}

第二种方式

@Test

public void getFileSystem2() throws Exception{

FileSystem fileSystem = FileSystem.get(new URI(“hdfs://node01:8020”), new Configuration());

System.out.println(“fileSystem:”+fileSystem);

}

第三种方式

@Test

public void getFileSystem3() throws Exception{

Configuration configuration = new Configuration();

configuratioin.set(“fs.defaultFS”,“hdfs://node01:8020”);

FileSystem fileSystem = FileSystem.newInstance(configurartion);

System.out.println(fileSystem.toString());

}

第四种方式

@Test

public void getFileSystem4() throws Exception{

FileSystem fileSystem = FileSystem.newInstance(new URI(“hdfs://node01:8020”),new Configuration());

System.out.println(fileSystem.toString());

}

遍历HDFS中所有文件


使用API遍历

@Test

public void listMyFiles() throws Exception{

//获取fileSystem类

FileSystem fileSystem = FileSystem.get(new URI(“hdfs://node01:8020”),new Configuration());

//获取RemoteIterator得到所有的文件或者文件夹,第一个参数指定遍历的路径,第二个参数表示是否要递归遍历

RemoteIterator locatedFileStatusRemoteIterator = fileSystem.listFiles(new Path(“/”),true);

while(locatedFileStatusRemoteIterator.hasNext()){

LocatedFileStatus next = locatedFileStatusRemoteIterator.next();

System.out.println(next.getPath().toString());

}

fileSystem.close();

}

HDFS上创建文件夹


@Test

public void mkdirs() throws Exception{

FileSystem fileSystem = FileSystem.get(new URI(“hdfs://node01:8020”), new Configuration());

boolean mkdirs = fileSystem.mkdirs(new Path(“/hello/mydir/test”));

fileSystem.close();

}

下载文件


@Test

public void getFileToLocal() throws Exception{

FileSystem fileSystem = FileSystem.get(new URI(“hdfs://node01:8020”),new Configuration());

FSDataInputStream inputStream = fileSystem.open(new Path(“/timer.txt”));

FileOutputStream outputStream = new FileOutStream(new File(“e:\timer.txt”));

IOUtils.copy(inputStream,outputStream);

IOUtils.closeQuietly(inputStream);

IOUtils.closeQuietly(outputStream);

fileSystem.close();

}

方式2:

@Test

public void downloadFile2() throws Exception{

//1、获取FileSystem

FileSystem fileSystem = FileSystem.get(new URI(“hdfs://node01:8020”),new Configuration());

//2、调用方法,实现文件的下载

fileSystem.copyToLocalFile(new Path(“/a.txt”),new Path(“D://a.txt”));

//3、关闭FileSystem

fileSystem.close();

}

文件上传


@Test

public void putData() throws Exception{

FileSystem fileSystem = FileSystem.get(new URI(“hdfs://node01:8020”),new Configuration());

fileSystem.copyFromLocalFile(new Path(“file:///c:\install.log”),new Path(“/hello/mydir/test”));

fileSystem.close();

}

hdfs访问权限控制


1、停止hdfs集群,在node01机器上执行以下命令

cd /export/servers/hadoop-2.7.5

sbin/stop-dfs.sh

2、修改node01机器上的hdfs-site.xml当中的配置文件

cd /export/servers/hadoop-2.7.5/etc/hadoop

vim hdfs-site.xml

dfs.permissions.enabled

true

小文件合并


由于Hadoop擅长存储大文件,因为大文件的元数据信息比较少,如果Hadoop集群当中有大量的小文件,那么每个小文件都需要维护一份元数据信息,会大大的增加集群管理元数据的内存压力,所以在实际工作当中,如果有必要一定要将小文件合并成大文件进行一起处理

在我们的HDFS的Shell命令模式下,可以通过命令行将很多hdfs文件合并成一个大文件下载到本地

cd /export/servers

hdfs dfs -getmerge /config/*.xm ./hello.xml

既然可以在下载的时候将这些小文件合并成一个大文件一起下载,那么肯定就可在上传的时候将小文件合并到一个大文件里面去

@Test

public void mergeFile() throws Exception{

//获取分布式文件系统

FileSystem fileSystem = FileSystem.get(new URI(“hdfs://192.168.52.250:8020”).new Configuration(),“root”);

FSDataOutputStream outputStream = fileSystem.create(new Path(“/bigfile.txt”));

//获取本地文件系统

LocalFileSystem local = FileSystem.getLocal(new Configuration());

//通过本地文件系统获取文件列表,为一个集合

FileStatus[] fileStatuses = local.listStatus(new Path(“file:///E:\input”));

for(FileStatus fileStatus: fileStatuses){

FSDataInputStream inputStream = local.open(fileStatus.getPath());

IOUtils.copy(inputStream,outputStream);

IOUtils.closeQuietly(inputStream);

}

IOUtils.closeQuietly(outputStream);

local.close();

fileSystem.close();

}

tem = FileSystem.get(new URI(“hdfs://192.168.52.250:8020”).new Configuration(),“root”);

FSDataOutputStream outputStream = fileSystem.create(new Path(“/bigfile.txt”));

//获取本地文件系统

LocalFileSystem local = FileSystem.getLocal(new Configuration());

//通过本地文件系统获取文件列表,为一个集合

FileStatus[] fileStatuses = local.listStatus(new Path(“file:///E:\input”));

for(FileStatus fileStatus: fileStatuses){

FSDataInputStream inputStream = local.open(fileStatus.getPath());

IOUtils.copy(inputStream,outputStream);

IOUtils.closeQuietly(inputStream);

}
IOUtils.closeQuietly(outputStream);
local.close();
fileSystem.close();
}

最后

ActiveMQ消息中间件面试专题

  • 什么是ActiveMQ?
  • ActiveMQ服务器宕机怎么办?
  • 丢消息怎么办?
  • 持久化消息非常慢怎么办?
  • 消息的不均匀消费怎么办?
  • 死信队列怎么办?
  • ActiveMQ中的消息重发时间间隔和重发次数吗?

ActiveMQ消息中间件面试专题解析拓展:

BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM


redis面试专题及答案

  • 支持一致性哈希的客户端有哪些?
  • Redis与其他key-value存储有什么不同?
  • Redis的内存占用情况怎么样?
  • 都有哪些办法可以降低Redis的内存使用情况呢?
  • 查看Redis使用情况及状态信息用什么命令?
  • Redis的内存用完了会发生什么?
  • Redis是单线程的,如何提高多核CPU的利用率?

BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM


Spring面试专题及答案

  • 谈谈你对 Spring 的理解
  • Spring 有哪些优点?
  • Spring 中的设计模式
  • 怎样开启注解装配以及常用注解
  • 简单介绍下 Spring bean 的生命周期

Spring面试答案解析拓展

BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM


高并发多线程面试专题

  • 现在有线程 T1、T2 和 T3。你如何确保 T2 线程在 T1 之后执行,并且 T3 线程在 T2 之后执行?
  • Java 中新的 Lock 接口相对于同步代码块(synchronized block)有什么优势?如果让你实现一个高性能缓存,支持并发读取和单一写入,你如何保证数据完整性。
  • Java 中 wait 和 sleep 方法有什么区别?
  • 如何在 Java 中实现一个阻塞队列?
  • 如何在 Java 中编写代码解决生产者消费者问题?
  • 写一段死锁代码。你在 Java 中如何解决死锁?

高并发多线程面试解析与拓展

BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM


jvm面试专题与解析

  • JVM 由哪些部分组成?
  • JVM 内存划分?
  • Java 的内存模型?
  • 引用的分类?
  • GC什么时候开始?

JVM面试专题解析与拓展!

BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM

lue存储有什么不同?

  • Redis的内存占用情况怎么样?
  • 都有哪些办法可以降低Redis的内存使用情况呢?
  • 查看Redis使用情况及状态信息用什么命令?
  • Redis的内存用完了会发生什么?
  • Redis是单线程的,如何提高多核CPU的利用率?

[外链图片转存中…(img-x2QZ8teE-1714296789881)]


Spring面试专题及答案

  • 谈谈你对 Spring 的理解
  • Spring 有哪些优点?
  • Spring 中的设计模式
  • 怎样开启注解装配以及常用注解
  • 简单介绍下 Spring bean 的生命周期

Spring面试答案解析拓展

[外链图片转存中…(img-hTkLrBZq-1714296789882)]


高并发多线程面试专题

  • 现在有线程 T1、T2 和 T3。你如何确保 T2 线程在 T1 之后执行,并且 T3 线程在 T2 之后执行?
  • Java 中新的 Lock 接口相对于同步代码块(synchronized block)有什么优势?如果让你实现一个高性能缓存,支持并发读取和单一写入,你如何保证数据完整性。
  • Java 中 wait 和 sleep 方法有什么区别?
  • 如何在 Java 中实现一个阻塞队列?
  • 如何在 Java 中编写代码解决生产者消费者问题?
  • 写一段死锁代码。你在 Java 中如何解决死锁?

高并发多线程面试解析与拓展

[外链图片转存中…(img-RkdpSdyK-1714296789882)]


jvm面试专题与解析

  • JVM 由哪些部分组成?
  • JVM 内存划分?
  • Java 的内存模型?
  • 引用的分类?
  • GC什么时候开始?

JVM面试专题解析与拓展!

[外链图片转存中…(img-WTn4oeHQ-1714296789882)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值