当前位置:   article > 正文

分布式文件系统HDFS_分布式文件系统hdfs头哥

分布式文件系统hdfs头哥

1.HDFS的来源

HDFS:Hadoop Distributed File system(hadoop分布式文件系统)

HDFS起源于Google的GFS论文(GFS,Mapreduce,BigTable为google的旧的三驾马车)HBASE

(1) 发表于2003年10月

(2)HDFS是GFS的克隆版

(3)易于扩展的分布式文件系统

(4)运行在大量普通廉价机器上,提供容错机制

(5)为大量用户提供性能不错的文件存取服务

2.HDFS的架构图之基础架构

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.1 master/slave 架构

NameNode是一个中心服务器,单一节点(简化系统的设计和实现),负责管理文件系统的名字空间(namespace)以及客户端对文件的访问

2.2 名字空间(NameSpace)

HDFS 支持传统的层次型文件组织结构。用户或者应用程序可以创建目录,然后将文件保存在这些目录里。文件系统名字空间的层次结构和大多数现有的文件系统类似:用户可以创建、删除、移动或重命名文件。

Namenode 负责维护文件系统的名字空间,任何对文件系统名字空间或属性的修改都将被Namenode 记录下来。

HDFS 会给客户端提供一个统一的抽象目录树,客户端通过路径来访问文件,

形如:hdfs://namenode:port/dir-a/dir-b/dir-c/file.data。

2.3 文件操作

namenode是负责文件元数据的操作,datanode负责处理文件内容的读写请求,跟文件内容相关的数据流不经过Namenode,只询问它跟哪个dataNode联系,否则NameNode会成为系统的瓶颈

2.4副本机制

为了容错,文件的所有 block 都会有副本。每个文件的 block 大小和副本系数都是可配置的。应用程序可以指定某个文件的副本数目。副本系数可以在文件创建的时候指定,也可以在之后改变。

2.5心跳机制

NameNode全权管理数据的复制,它周期性的从集群中的每个DataNode接收心跳信合和状态报告,接收到心跳信号意味着DataNode节点工作正常,块状态报告包含了一个该DataNode上所有的数据列表

2.6 一次写入,多次读出

HDFS 是设计成适应一次写入,多次读出的场景,且不支持文件的修改。

正因为如此,HDFS 适合用来做大数据分析的底层存储服务,并不适合用来做.网盘等应用,因为,修改不方便,延迟大,网络开销大,成本太高。

3.NameNode与Datanode的总结概述

在这里插入图片描述

3.1namenode 元数据管理

我们把目录结构及文件分块位置信息叫做元数据。Namenode 负责维护整个hdfs文件系统的目录树结构,以及每一个文件所对应的 block 块信息(block 的id,及所在的datanode 服务器)。

3.2 Datanode 数据存储

文件的各个 block 的具体存储管理由 datanode 节点承担。每一个 block 都可以在多个datanode 上。Datanode 需要定时向 Namenode 汇报自己持有的 block信息。 存储多个副本(副本数量也可以通过参数设置 dfs.replication,默认是 3)。

4.文件副本机制以及block块存储

在这里插入图片描述

所有的文件都是以block块的方式存放在HDFS文件系统当中,在hadoop1当中,文件的block块默认大小是64M,hadoop2当中,文件的block块大小默认是128M,block块的大小可以通过hdfs-site.xml当中的配置文件进行指定

5.元文件FSImage与edits

FSimage是一个完整的元数据文件

edits是每隔一个小时生成

客户端对hdfs进行写文件时会首先被记录在edits文件中。

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

每次hdfs更新时edits先更新后客户端才会看到最新信息。

fsimage:是namenode中关于元数据的镜像,一般称为检查点。

一般开始时对namenode的操作都放在edits中,为什么不放在fsimage中呢?
因为fsimage是namenode的完整的镜像,内容很大,如果每次都加载到内存的话生成树状拓扑结构,这是非常耗内存和CPU。
fsimage内容包含了namenode管理下的所有datanode中文件及文件block及block所在的datanode的元数据信息。随着edits内容增大,就需要在一定时间点和fsimage合并。
在这里插入图片描述

2.x的hadoop元数据合并条件

dfs.namenode.checkpoint.period: 默认是一个小时(3600s)

dfs.namenode.checkpoint.txns:默认为1000000条edits记录

FSimage文件当中的文件信息查看:

cd  /opt/servers/hadoop-2.7.7/hadoopDatas/name/current
hdfs oiv -i fsimage_0000000000000000864 -p XML -o hello.xml
  • 1
  • 2

edits当中的文件信息查看:

cd  /opt/servers/hadoop-2.7.7/data/dfs/nn/edits
hdfs oev -i  edits_0000000000000000865-0000000000000000866 -o myedit.xml -p XML
  • 1
  • 2

6、HDFS的文件写入过程

在这里插入图片描述

详细步骤解析:

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

2、 client请求第一个block该传输到哪些DataNode服务器上;

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

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

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

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

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

7、 当一个block传输完成之后,client再次请求NameNode上传第二个block到服务器。

7、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 列表;

6、 读取完一个 block 都会进行 checksum 验证,如果读取 DataNode 时出现错误,客户端会通知 NameNode,然后再从下一个拥有该 block 副本的DataNode 继续读。

7、 read 方法是并行的读取 block 信息,不是一块一块的读取;NameNode 只是返回Client请求包含块的DataNode地址,并不是返回请求块的数据;

8、 最终读取来所有的 block 会合并成一个完整的最终文件。

8.HDFS基本Shell操作

创建文件夹(不支持多级创建):

hadoop fs -mkdir -p /xxx
  • 1

查看目录:

hadoop fs -ls /xxx
  • 1

递归查看多级目录:

hadoop fs -lsr /xxx
  • 1

上传文件到HDFS:

hadoop fs -put xxx.txt /xxx
  • 1

下载文件到本地当前目录:

hadoop fs -get /xxx/xxx/xxx.txt
  • 1

删除文件:

hadoop fs -rm /xxx/xxx/xxx.txt
  • 1

删除文件夹(文件夹必须为空):

hadoop fs -rmdir /xxx/xxx
  • 1

强制删除文件夹或文件

Hadoop fs -rm -r /xxx
  • 1

9.HDFS的api操作

9.1前期准备

1.解决winutils.exe的问题

​ 1)把hadoop2.7.7(windows版)文件目录放到一个没有中文没有空格的路径下

​ 2)在window中配置handoop的环境变量,并且加入path中。

9.2 创建maven工程并导入jar包

<dependency>
  <groupId>org.apache.hadoop</groupId>
  <artifactId>hadoop-common</artifactId>
  <version>2.7.7</version>
</dependency>
<dependency>
  <groupId>org.apache.hadoop</groupId>
  <artifactId>hadoop-hdfs</artifactId>
  <version>2.7.7</version>
</dependency>
<dependency>
  <groupId>org.apache.hadoop</groupId>
  <artifactId>hadoop-client</artifactId>
  <version>2.7.7</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

9.2使用文件系统方式访问数据

在 java 中操作 HDFS,主要涉及以下 Class:

Configuration:该类的对象封转了客户端或者服务器的配置;

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

FileSystem fs = FileSystem.get(conf)
  • 1

get 方法从 conf 中的一个参数 fs.defaultFS 的配置值判断具体是什么类型的文件系统。如果我们的代码中没有指定 fs.defaultFS,并且工程 classpath下也没有给定相应的配置,conf中的默认值就来自于hadoop的jar包中的core-default.xml , 默 认 值 为 : file:/// , 则 获 取 的 将 不 是 一 个DistributedFileSystem 的实例,而是一个本地文件系统的客户端对象

9.3获取FileSystem的方式

Configuration configuration=new Configuration();
configuration.set("fs.defaultFS","hdfs://192.168.65.101:8020");
FileSystem fileSystem=FileSystem.get(configuration);
System.out.println(fileSystem.toString());
  • 1
  • 2
  • 3
  • 4

9.4创建文件夹

@Test
public void mkdirs() throws  Exception{
    FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.65.101:8020"), new Configuration());
    boolean mkdirs = fileSystem.mkdirs(new Path("/hello/mydir/test"));
    fileSystem.close();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

9.4下载文件

@Test
public void getFileToLocal()throws  Exception{
   Configuration configuration=new Configuration();
		configuration.set("fs.defaultFS","hdfs://192.168.65.101:8020");
	FileSystem fileSystem=FileSystem.get(configuration);
    FSDataInputStream open = fileSystem.open(new Path("/test/input/install.log"));
    FileOutputStream fileOutputStream = new FileOutputStream(new File("c:\\install.log"));
    IOUtils.copy(open,fileOutputStream );
    IOUtils.closeQuietly(open);
    IOUtils.closeQuietly(fileOutputStream);
    fileSystem.close();
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

9.5上传文件

@Test
public void putData() throws  Exception{
  	Configuration configuration=new Configuration();
		configuration.set("fs.defaultFS","hdfs://192.168.65.101:8020");
	FileSystem fileSystem=FileSystem.get(configuration);
    fileSystem.copyFromLocalFile(new Path("file:///c:\\install.log"),new Path("/hello/mydir/test"));
    fileSystem.close();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/408063
推荐阅读
相关标签
  

闽ICP备14008679号