3.1 HDFS 简介

HDFS (全称:Hadoop Distribute File System,Hadoop 分布式⽂件系统)是 Hadoop 核⼼组成,是分布式存储服务。

分布式⽂件系统横跨多台计算机,在⼤数据时代有着⼴泛的应⽤前景,它们为存储和处理超⼤规模数据提供所需的扩展能⼒。

HDFS是分布式⽂件系统中的⼀种。

重要概念

HDFS 通过统⼀的命名空间⽬录树来定位⽂件; 另外,它是分布式的,由很多服务器联合起来实现其功能,集群中的服务器有各⾃的⻆⾊(分布式本质是拆分,各司其职);

  • 典型的 Master/Slave 架构

主从架构:核心思想是基于分而治之的思想,将一个原始任务分解为若干个语义等同的子任务,并由专门的工作者线程来并行执行这些任务,原始任务的结果是通过整合各个子任务的处理结果形成的.主要的使用场景有

  • 并行计算,以提升计算性能
  • 容错处理,以提升计算的可靠性
  • 计算精度,以提高计算的精确程度
  • HDFS 的架构是典型的 Master/Slave 结构。
    HDFS集群往往是⼀个NameNode(HA架构会有两个NameNode,联邦机制)+多个DataNode组成;
    NameNode是集群的主节点,DataNode是集群的从节点。

  • 分块存储(block机制)
    HDFS 中的⽂件在物理上是分块存储(block)的,块的⼤⼩可以通过配置参数来规定;
    Hadoop2.x版本中默认的block⼤⼩是128M;

  • 命名空间(NameSpace)
    HDFS ⽀持传统的层次型⽂件组织结构。⽤户或者应⽤程序可以创建⽬录,然后将⽂件保存在这些⽬录⾥。⽂件系统名字空间的层次结构和⼤多数现有的⽂件系统类似:⽤户可以创建、删除、移动或重命名⽂件。
    Namenode 负责维护⽂件系统的名字空间,任何对⽂件系统名字空间或属性的修改都将被
    Namenode 记录下来。
    HDFS提供给客户单⼀个抽象⽬录树,访问形式:hdfs://namenode的hostname:port/test/input
    hdfs://linux121:9000/test/input

  • NameNode元数据管理
    我们把⽬录结构及⽂件分块位置信息叫做元数据。
    NameNode的元数据记录每⼀个⽂件所对应的block信息(block的id,以及所在的DataNode节点的信息)
    DataNode数据存储
    ⽂件的各个 block 的具体存储管理由 DataNode 节点承担。⼀个block会有多个DataNode来存储,DataNode会定时向NameNode来汇报⾃⼰持有的block信息。一个块出问题,可以把这个任务分配给其他副本的机器来执行,保证数据不丢失

  • 副本机制
    为了容错,⽂件的所有 block 都会有副本。每个⽂件的 block ⼤⼩和副本系数都是可配置的。应⽤程序可以指定某个⽂件的副本数⽬。副本系数可以在⽂件创建的时候指定,也可以在之后改变。副本数量默认是3个。

  • ⼀次写⼊,多次读出
    HDFS 是设计成适应⼀次写⼊,多次读出的场景,且不⽀持⽂件的随机修改。 (⽀持追加写⼊,不只⽀持随机更新)
    正因为如此,HDFS 适合⽤来做⼤数据分析的底层存储服务,并不适合⽤来做⽹盘等应⽤(修改不⽅便,延迟⼤,⽹络开销⼤,成本太⾼)

3.2 HDFS 架构

  • NameNode(nn):Hdfs集群的管理者,Master

    • 维护管理Hdfs的名称空间(NameSpace)
    • 维护副本策略
    • 记录⽂件块(Block)的映射信息
    • 负责处理客户端读写请求
  • DataNode:NameNode下达命令,DataNode执⾏实际操作,Slave节点。
    • 保存实际的数据块
    • 负责数据块的读写
  • Client:客户端
    • 上传⽂件到HDFS的时候,Client负责将⽂件切分成Block,然后进⾏上传
    • 请求NameNode交互,获取⽂件的位置信息
    • 读取或写⼊⽂件,与DataNode交互
    • Client可以使⽤⼀些命令来管理HDFS或者访问HDFS

3.3 HDFS 客户端操作

  1. 基本语法
hadoop fs 具体命令
hdfs dfs 具体命令
  1. 命令⼤全
[root@linux121 hadoop-2.9.2]# bin/hdfs dfs
Usage: hadoop fs [generic options][-appendToFile <localsrc> ... <dst>][-cat [-ignoreCrc] <src> ...][-checksum <src> ...][-chgrp [-R] GROUP PATH...][-chmod [-R] <MODE[,MODE]... | OCTALMODE> PATH...][-chown [-R] [OWNER][:[GROUP]] PATH...][-copyFromLocal [-f] [-p] [-l] [-d] <localsrc> ... <dst>][-copyToLocal [-f] [-p] [-ignoreCrc] [-crc] <src> ... <localdst>][-count [-q] [-h] [-v] [-t [<storage type>]] [-u] [-x] <path> ...][-cp [-f] [-p | -p[topax]] [-d] <src> ... <dst>][-createSnapshot <snapshotDir> [<snapshotName>]][-deleteSnapshot <snapshotDir> <snapshotName>][-df [-h] [<path> ...]][-du [-s] [-h] [-x] <path> ...][-expunge][-find <path> ... <expression> ...][-get [-f] [-p] [-ignoreCrc] [-crc] <src> ... <localdst>][-getfacl [-R] <path>][-getfattr [-R] {-n name | -d} [-e en] <path>][-getmerge [-nl] [-skip-empty-file] <src> <localdst>][-help [cmd ...]][-ls [-C] [-d] [-h] [-q] [-R] [-t] [-S] [-r] [-u] [<path> ...]][-mkdir [-p] <path> ...][-moveFromLocal <localsrc> ... <dst>][-moveToLocal <src> <localdst>][-mv <src> ... <dst>][-put [-f] [-p] [-l] [-d] <localsrc> ... <dst>][-renameSnapshot <snapshotDir> <oldName> <newName>][-rm [-f] [-r|-R] [-skipTrash] [-safely] <src> ...][-rmdir [--ignore-fail-on-non-empty] <dir> ...][-setfacl [-R] [{-b|-k} {-m|-x <acl_spec>} <path>]|[--set <acl_spec>
<path>]][-setfattr {-n name [-v value] | -x name} <path>][-setrep [-R] [-w] <rep> <path> ...][-stat [format] <path> ...][-tail [-f] <file>][-test -[defsz] <path>][-text [-ignoreCrc] <src> ...][-touchz <path> ...][-truncate [-w] <length> <path> ...][-usage [cmd ...]]
Generic options supported are:
-conf <configuration file> specify an application configuration file
-D <property=value> define a value for a given property
-fs <file:///|hdfs://namenode:port> specify default filesystem URL to use,
overrides 'fs.defaultFS' property from configurations.
-jt <local|resourcemanager:port> specify a ResourceManager
-files <file1,...> specify a comma-separated list of files to
be copied to the map reduce cluster
-libjars <jar1,...> specify a comma-separated list of jar files
to be included in the classpath
-archives <archive1,...> specify a comma-separated list of archives
to be unarchived on the compute machines

3.HDFS命令演示

  1. 启动Hadoop集群(⽅便后续的测试)
[root@linux121 hadoop-2.9.2]$ sbin/start-dfs.sh
[root@linux122 hadoop-2.9.2]$ sbin/start-yarn.sh
  1. -help:输出这个命令参数
[root@linux121 hadoop-2.9.2]$ hadoop fs -help rm
  1. -ls: 显示⽬录信息
[root@linux121 hadoop-2.9.2]$ hadoop fs -ls /
  1. -mkdir:在HDFS上创建⽬录
[root@linux121 hadoop-2.9.2]$ hadoop fs -mkdir -p /lagou/bigdata
  1. -moveFromLocal:从本地剪切粘贴到HDFS
[root@linux121 hadoop-2.9.2]$ touch hadoop.txt
[root@linux121 hadoop-2.9.2]$ hadoop fs -moveFromLocal ./hadoop.txt
/lagou/bigdata
  1. -appendToFile:追加⼀个⽂件到已经存在的⽂件末尾
[root@linux121 hadoop-2.9.2]$ touch hdfs.txt
[root@linux121 hadoop-2.9.2]$ vi hdfs.txt

输⼊

namenode datanode block replication
[root@linux121 hadoop-2.9.2]$ hadoop fs -appendToFile hdfs.txt
/lagou/bigdata/hadoop.txt
  1. -cat:显示⽂件内容
[root@linux121 hadoop-2.9.2]$ hadoop fs -cat /lagou/bigdata/hadoop.txt
  1. -chgrp 、-chmod、-chown:Linux⽂件系统中的⽤法⼀样,修改⽂件所属权限
[root@linux121 hadoop-2.9.2]$ hadoop fs -chmod 666
/lagou/bigdata/hadoop.txt
[root@linux121 hadoop-2.9.2]$ hadoop fs -chown root:root
/lagou/bigdata/hadoop.txt
  1. -copyFromLocal:从本地⽂件系统中拷⻉⽂件到HDFS路径去
[root@linux121 hadoop-2.9.2]$ hadoop fs -copyFromLocal README.txt /
  1. -copyToLocal:从HDFS拷⻉到本地
[root@linux121 hadoop-2.9.2]$ hadoop fs -copyToLocal /lagou/bigdata/hadoop.txt ./
  1. -cp :从HDFS的⼀个路径拷⻉到HDFS的另⼀个路径
[root@linux121 hadoop-2.9.2]$ hadoop fs -cp /lagou/bigdata/hadoop.txt /hdfs.txt
  1. -mv:在HDFS⽬录中移动⽂件
[root@linux121 hadoop-2.9.2]$ hadoop fs -mv /hdfs.txt /lagou/bigdata/
  1. -get:等同于copyToLocal,就是从HDFS下载⽂件到本地
[root@linux121 hadoop-2.9.2]$ hadoop fs -get /lagou/bigdata/hadoop.txt ./
  1. -put:等同于copyFromLocal
[root@linux121 hadoop-2.9.2]$ hadoop fs -mkdir -p /user/root/test/
#本地⽂件系统创建yarn.txt
[root@linux121 hadoop-2.9.2]$ vim yarn.txt
resourcemanager nodemanager
[root@linux121 hadoop-2.9.2]$ hadoop fs -put ./yarn.txt /user/root/test/
  1. -tail:显示⼀个⽂件的末尾
[root@linux121 hadoop-2.9.2]$ hadoop fs -tail /user/root/test/yarn.txt
  1. -rm:删除⽂件或⽂件夹
[root@linux121 hadoop-2.9.2]$ hadoop fs -rm /user/root/test/yarn.txt
  1. -rmdir:删除空⽬录
[root@linux121 hadoop-2.9.2]$ hadoop fs -mkdir /test
[root@linux121 hadoop-2.9.2]$ hadoop fs -rmdir /test
  1. -du统计⽂件夹的⼤⼩信息
[root@linux121 hadoop-2.9.2]$ hadoop fs -du -s -h /user/root/test
[root@linux121 hadoop-2.9.2]$ hadoop fs -du -h /user/root/test
  1. -setrep:设置HDFS中⽂件的副本数量
[root@linux121 hadoop-2.9.2]$ hadoop fs -setrep 10 /lagou/bigdata/hadoop.txt

就算配置调到10台,机器只有3台,那么实际也只有3个副本

3.4 JAVA客户端

3.4.1 客户端环境准备


<dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>RELEASE</version></dependency><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.8.2</version></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-common</artifactId><version>2.9.2</version></dependency><!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoopclient --><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-client</artifactId><version>2.9.2</version></dependency><!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-hdfs--><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-hdfs</artifactId><version>2.9.2</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

新建文件夹(mkdirs)

public class HdfsClient{@Testpublic void testMkdirs() throws IOException, InterruptedException,URISyntaxException {// 1 获取⽂件系统Configuration configuration = new Configuration();// 配置在集群上运⾏// configuration.set("fs.defaultFS", "hdfs://linux121:9000");// FileSystem fs = FileSystem.get(configuration);FileSystem fs = FileSystem.get(new URI("hdfs://linux121:9000"),configuration, "root");// 2 创建⽬录fs.mkdirs(new Path("/test"));// 3 关闭资源fs.close();}
}

遇到问题1:
如果不指定操作HDFS集群的⽤户信息,默认是获取当前操作系统的⽤户信息,出现权限被拒绝的问题,报错如下:

问题2:
windows解压安装Hadoop后,在调⽤相关API操作HDFS集群时可能会报错,这是由于Hadoop安装缺少windows操作系统相关⽂件所致,如下图:

从资料⽂件夹中找到winutils.exe拷⻉放到windows系统Hadoop安装⽬录的bin⽬录下即可!!

3.4.2 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://linux121:9000"),configuration, "root");// 2 上传⽂件fs.copyFromLocalFile(new Path("e:/lagou.txt"), new Path("/lagou.txt"));// 3 关闭资源fs.close();System.out.println("end");
}

也可以使用配置文件来设置

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

参数优先级
参数优先级排序:(1)代码中设置的值 >(2)⽤户⾃定义配置⽂件 >(3)服务器的默认配置

2 下载文件

@Test
public void testCopyToLocalFile() throws IOException, InterruptedException,URISyntaxException{// 1 获取⽂件系统Configuration configuration = new Configuration();FileSystem fs = FileSystem.get(new URI("hdfs://linux121:9000"),configuration, "root");// 2 执⾏下载操作// boolean delSrc 指是否将原⽂件删除// Path src 指要下载的⽂件路径// Path dst 指将⽂件下载到的路径// boolean useRawLocalFileSystem 是否开启⽂件校验fs.copyToLocalFile(false, new Path("/lagou.txt"), new Path("e:/lagou_copy.txt"), true);// 3 关闭资源fs.close();
}

3 删除文件

@Test
public void testDelete() throws IOException, InterruptedException,URISyntaxException{// 1 获取⽂件系统Configuration configuration = new Configuration();FileSystem fs = FileSystem.get(new URI("hdfs://linux121:9000"),configuration, "root");// 2 执⾏删除fs.delete(new Path("/api_test/"), true);// 3 关闭资源fs.close();
}

4 查看⽂件名称、权限、⻓度、块信息

@Test
public void testListFiles() throws IOException, InterruptedException,URISyntaxException{// 1获取⽂件系统Configuration configuration = new Configuration();FileSystem fs = FileSystem.get(new URI("hdfs://linux121:9000"),configuration, "root");// 2 获取⽂件详情RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/"),true);while(listFiles.hasNext()){LocatedFileStatus status = listFiles.next();// 输出详情// ⽂件名称System.out.println(status.getPath().getName());// ⻓度System.out.println(status.getLen());// 权限System.out.println(status.getPermission());// 分组System.out.println(status.getGroup());// 获取存储的块信息BlockLocation[] blockLocations = status.getBlockLocations();for (BlockLocation blockLocation : blockLocations) {// 获取块存储的主机节点String[] hosts = blockLocation.getHosts();for (String host : hosts) {System.out.println(host);}}System.out.println("-----------华丽的分割线----------");}// 3 关闭资源fs.close();
}

5 ⽂件夹判断

@Test
public void testListStatus() throws IOException, InterruptedException,URISyntaxException{// 1 获取⽂件配置信息Configuration configuration = new Configuration();FileSystem fs = FileSystem.get(new URI("hdfs://linux121:9000"),configuration, "root");// 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();
}

6 I/O流操作HDFS

以上我们使⽤的API操作都是HDFS系统框架封装好的。我们⾃⼰也可以采⽤IO流的⽅式实现⽂件的上传
和下载。
6.1 ⽂件上传

  1. 需求:把本地e盘上的lagou.txt⽂件上传到HDFS根⽬录
  2. 编写代码
@Test
public void putFileToHDFS() throws IOException, InterruptedException,URISyntaxException {// 1 获取⽂件系统Configuration configuration = new Configuration();FileSystem fs = FileSystem.get(new URI("hdfs://linux121:9000"),configuration, "root");// 2 创建输⼊流FileInputStream fis = new FileInputStream(new File("e:/lagou.txt"));// 3 获取输出流FSDataOutputStream fos = fs.create(new Path("/lagou_io.txt"));// 4 流对拷IOUtils.copyBytes(fis, fos, configuration);// 5 关闭资源IOUtils.closeStream(fos);IOUtils.closeStream(fis);fs.close();
}

6.2 ⽂件下载
3. 需求:从HDFS上下载lagou.txt⽂件到本地e盘上
4. 编写代码

@Test
public void getFileFromHDFS() throws IOException, InterruptedException,URISyntaxException{// 1 获取⽂件系统Configuration configuration = new Configuration();FileSystem fs = FileSystem.get(new URI("hdfs://linux121:9000"),configuration, "root");// 2 获取输⼊流FSDataInputStream fis = fs.open(new Path("/lagou_io.txt"));// 3 获取输出流FileOutputStream fos = new FileOutputStream(new File("e:/lagou_io_copy.txt"));// 4 流的对拷IOUtils.copyBytes(fis, fos, configuration);// 5 关闭资源IOUtils.closeStream(fos);IOUtils.closeStream(fis);fs.close();
}

6.3 seek 定位读取

  1. 需求:将HDFS上的lagou.txt的内容在控制台输出两次
  2. 编写代码
@Test
public void readFileSeek2() throws IOException, InterruptedException,URISyntaxException{// 1 获取⽂件系统Configuration configuration = new Configuration();FileSystem fs = FileSystem.get(new URI("hdfs://linux121:9000"),configuration, "root");// 2 打开输⼊流,读取数据输出到控制台FSDataInputStream in = null;try{in= fs.open(new Path("/lagou.txt"));IOUtils.copyBytes(in, System.out, 4096, false);in.seek(0); //从头再次读取IOUtils.copyBytes(in, System.out, 4096, false);}finally {IOUtils.closeStream(in);}}

3.5 HDFS的读写解析

3.5.1 HDFS读数据流程

  1. 客户端通过Distributed FileSystem向NameNode请求下载⽂件,NameNode通过查询元数据,找到⽂件块所在的DataNode地址。
  2. 挑选⼀台DataNode(就近原则,然后随机)服务器,请求读取数据。
  3. DataNode开始传输数据给客户端(从磁盘⾥⾯读取数据输⼊流,以Packet为单位来做校验)。
  4. 客户端以Packet为单位接收,先在本地缓存,然后写⼊⽬标⽂件。

3.5.2 HDFS写数据流程

  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步)。

验证Packet代码

@Test
public void testUploadPacket() throws IOException {//1 准备读取本地⽂件的输⼊流final FileInputStream in = new FileInputStream(new File("e:/lagou.txt"));//2 准备好写出数据到hdfs的输出流final FSDataOutputStream out = fs.create(new Path("/lagou.txt"), new Progressable() {public void progress() { //这个progress⽅法就是每传输64KB(packet)就会执⾏⼀次,System.out.println("&");}});//3 实现流拷⻉IOUtils.copyBytes(in, out, configuration); //默认关闭流选项是true,所以会⾃动关闭//4 关流 可以再次关闭也可以不关了
}

3.6 NN与2NN

3.6.1 HDFS元数据管理机制

问题1:NameNode如何管理和存储元数据?

  • 计算机中存储数据两种:内存或者是磁盘
  • 元数据存储磁盘:存储磁盘⽆法⾯对客户端对元数据信息的任意的快速低延迟的响应,但是安全性⾼
  • 元数据存储内存:元数据存放内存,可以⾼效的查询以及快速响应客户端的查询请求,数据保存在内存,如果断点,内存中的数据全部丢失。
  • 解决⽅案:内存+磁盘;NameNode内存+FsImage的⽂件(磁盘)
  • 新问题:磁盘和内存中元数据如何划分?

两个数据⼀模⼀样,还是两个数据合并到⼀起才是⼀份完整的数据呢?

  • ⼀模⼀样:client如果对元数据进⾏增删改操作,需要保证两个数据的⼀致性。FsImage⽂件操作起来效率也不⾼。
  • 两个合并=完整数据:NameNode引⼊了⼀个edits⽂件(⽇志⽂件:只能追加写⼊)edits⽂件记录的是client的增删改操作,不再选择让NameNode把数据dump出来形成FsImage⽂件(这种操作是⽐较消耗资源)。

元数据管理流程图

  • 第⼀阶段:NameNode启动

    • 第⼀次启动NameNode格式化后,创建Fsimage和Edits⽂件。如果不是第⼀次启动,直接加载编辑⽇志和镜像⽂件到内存。
    • 客户端对元数据进⾏增删改的请求。
    • NameNode记录操作⽇志,更新滚动⽇志。
    • NameNode在内存中对数据进⾏增删改。
  • 第⼆阶段:Secondary NameNode⼯作
    • Secondary NameNode询问NameNode是否需要CheckPoint。直接带回NameNode是否执⾏检查点操作结果。
    • Secondary NameNode请求执⾏CheckPoint。
    • NameNode滚动正在写的Edits⽇志。
    • 将滚动前的编辑⽇志和镜像⽂件拷⻉到Secondary NameNode。
    • Secondary NameNode加载编辑⽇志和镜像⽂件到内存,并合并。
    • ⽣成新的镜像⽂件fsimage.chkpoint。
    • 拷⻉fsimage.chkpoint到NameNode。
    • NameNode将fsimage.chkpoint重新命名成fsimage。

3.6.2 Fsimage与Edits⽂件解析

NameNode在执⾏格式化之后,会在/opt/lagou/servers/hadoop-2.9.2/data/tmp/dfs/name/current
⽬录下产⽣如下⽂件

  • Fsimage⽂件:是namenode中关于元数据的镜像,⼀般称为检查点,这⾥包含了HDFS⽂件系统所有⽬录以及⽂件相关信息(Block数量,副本数量,权限等信息)
  • Edits⽂件 :存储了客户端对HDFS⽂件系统所有的更新操作记录,Client对HDFS⽂件系统所有的更新操作都会被记录到Edits⽂件中(不包括查询操作)
  • seen_txid:该⽂件是保存了⼀个数字,数字对应着最后⼀个Edits⽂件名的数字
  • VERSION:该⽂件记录namenode的⼀些版本号信息,⽐如:CusterId,namespaceID等

NameNode启动时会将Fsimage⽂件加载到内存中,同时也把之前未合并元数据的Edits⽂件加载,集合两个⽂件中的元数据这样保证了NameNode中的元数据是最新最全的。通俗点说就是NameNode启动时把Fsimage和Edits⽂件进⾏了合并。

3.6.2.1 Fsimage⽂件内容

官⽅地址

https://hadoop.apache.org/docs/r2.9.2/hadoop-project-dist/hadoop-hdfs/HdfsImageViewer.html


问题:Fsimage中为什么没有记录块所对应DataNode?
在集群启动后,NameNode要求DataNode上报数据块信息,并间隔⼀段时间后再次上报。

3.6.2.2 Edits⽂件内容

  1. 基本语法
    hdfs oev -p ⽂件类型 -i编辑⽇志 -o 转换后⽂件输出路径
  2. 案例实操
[root@linux121 current]$ hdfs oev -p XML -i edits_0000000000000000266-0000000000000000267 -o /opt/lagou/servers/hadoop-2.9.2/edits.xml
[root@linux121 current]$ cat /opt/lagou/servers/hadoop-2.9.2/edits.xml

备注:Edits中只记录了更新相关的操作,查询或者下载⽂件并不会记录在内!!
问题:NameNode启动时如何确定加载哪些Edits⽂件呢?

需要借助fsimage⽂件最后数字编码,来确定哪些edits之前是没有合并到fsimage中,启动时只需要加载那些未合并的edits⽂件即可。

3.6.3 checkpoint周期

[hdfs-default.xml]

<!-- 定时⼀⼩时 -->
<property><name>dfs.namenode.checkpoint.period</name><value>3600</value>
</property><!-- ⼀分钟检查⼀次操作次数,3当操作次数达到1百万时,SecondaryNameNode执⾏⼀次 -->
<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 >

3.7 NN故障处理

NameNode故障后,HDFS集群就⽆法正常⼯作,因为HDFS⽂件系统的元数据需要由NameNode来管理维护并与Client交互,如果元数据出现损坏和丢失同样会导致NameNode⽆法正常⼯作进⽽HDFS⽂件系统⽆法正常对外提供服务。
如果元数据出现丢失损坏如何恢复呢?

  1. 将2NN的元数据拷⻉到NN的节点下
    此种⽅式会存在元数据的丢失。
  2. 搭建HDFS的HA(⾼可⽤)集群,解决NN的单点故障问题!!(借助Zookeeper实现HA,⼀个
    Active的NameNode,⼀个是Standby的NameNode)

3.8 Hadoop的限额与归档以及集群安全模式

⾼级命令

  • HDFS⽂件限额配置
    HDFS⽂件的限额配置允许我们以⽂件⼤⼩或者⽂件个数来限制我们在某个⽬录下上传的⽂件数量或者⽂件内容总量,以便达到我们类似百度⽹盘⽹盘等限制每个⽤户允许上传的最⼤的⽂件的量
  1. 数量限额
hdfs dfs -mkdir -p /user/root/lagou #创建hdfs⽂件夹hdfs dfsadmin -setQuota 2 /user/root/lagou # 给该⽂件夹下⾯设置最多上传两个⽂件,上传⽂件,发现只能上传⼀个⽂件hdfs dfsadmin -clrQuota /user/root/lagou # 清除⽂件数量限制
  1. 空间⼤⼩限额
hdfs dfsadmin -setSpaceQuota 4k /user/root/lagou # 限制空间⼤⼩4KB
#上传超过4Kb的⽂件⼤⼩上去提示⽂件超过限额
hdfs dfs -put /export/softwares/xxx.tar.gz /user/root/lagouhdfs dfsadmin -clrSpaceQuota /user/root/lagou #清除空间限额
#查看hdfs⽂件限额数量
hdfs dfs -count -q -h /user/root/lagou
  • HDFS的安全模式
    安全模式是HDFS所处的⼀种特殊状态,在这种状态下,⽂件系统只接受读数据请求,⽽不接受删除、修改等变更请求。在NameNode主节点启动时,HDFS⾸先进⼊安全模式,DataNode在启动的时候会向NameNode汇报可⽤的block等状态,当整个系统达到安全标准时,HDFS⾃动离开安全模式。如果HDFS出于安全模式下,则⽂件block不能进⾏任何的副本复制操作,因此达到最⼩的副本数量要求是基于DataNode启动时的状态来判定的,启动时不会再做任何复制(从⽽达到最⼩副本数量要求),HDFS集群刚启动的时候,默认30S钟的时间是出于安全期的,只有过了30S之后,集群脱离了安全期,然后才可以对集群进⾏操作。
hdfs dfsadmin -safemode
  • Hadoop归档技术
    主要解决HDFS集群存在⼤量⼩⽂件的问题!!
    由于⼤量⼩⽂件会占⽤NameNode的内存,因此对于HDFS来说存储⼤量⼩⽂件造成NameNode内存资源的浪费!
    Hadoop存档⽂件HAR⽂件,是⼀个更⾼效的⽂件存档⼯具,HAR⽂件是由⼀组⽂件通过archive⼯具创建⽽来,在减少了NameNode的内存使⽤的同时,可以对⽂件进⾏透明的访问,通俗来说就是HAR⽂件对NameNode来说是⼀个⽂件减少了内存的浪费,对于实际操作处理⽂件依然是⼀个⼀个独⽴的⽂件。
  1. 归档⽂件
    把/user/lagou/input⽬录⾥⾯的所有⽂件归档成⼀个叫input.har的归档⽂件,并把归档后⽂件存
    储到/user/lagou/output路径下。
[root@linux121 hadoop-2.9.2]$ bin/hadoop archive -archiveName input.har –p /user/root/input /user/root/output
  1. 查看归档
[root@linux121 hadoop-2.9.2]$ hadoop fs -lsr /user/root/output/input.har
[root@linux121 hadoop-2.9.2]$ hadoop fs -lsr har:///user/root/output/input.har
  1. 解归档⽂件
[root@linux121 hadoop-2.9.2]$ hadoop fs -cp har:///user/root/output/input.har/* /user/root

3 Hadoop-HDFS分布式⽂件系统相关推荐

  1. Hadoop HDFS分布式文件系统 常用命令汇总

    引言:我们维护hadoop系统的时候,必不可少需要对HDFS分布式文件系统做操作,例如拷贝一个文件/目录,查看HDFS文件系统目录下的内容,删除HDFS文件系统中的内容(文件/目录),还有HDFS管理 ...

  2. Hadoop (HDFS)分布式文件系统基本操作

    Hadoop HDFS提供了一组命令集来操作文件,它既可以操作Hadoop分布式文件系统,也可以操作本地文件系统.但是要加上theme(Hadoop文件系统用hdfs://,本地文件系统用file:/ ...

  3. Hadoop HDFS分布式文件系统原理及应用介绍

    HDFS有着高容错性特点,且设计用来部署在低廉的硬件上,提供高吞吐量来访问应用程序的数据,适合那些有着超大数据集的应用程序.HDFS放宽了POSIX的要求,可以实现流的形式访问文件系统中的数据. Ha ...

  4. HDFS 全称 Hadoop 分布式文件系统,其最主要的作用是作为 Hadoop 生态中各系统的存储服务。

    HDFS HDFS 全称 Hadoop 分布式文件系统,其最主要的作用是作为 Hadoop 生态中各系统的存储服务. 面对大规模的数据,HDFS 在设计上满足了以下目标: 高度容错性: HDFS 可能 ...

  5. 详细Ubuntu系统下搭建Hadoop完全分布式

    1.Hadoop的运行环境介绍 hadoop主要有三种运行模式:单机模式.伪分布模式.完全分布模式. 其中在单机模式下所有3个XML文件均为空,当配置文件为空时,Hadoop会完全运行在本地,因为不需 ...

  6. hadoop历史背景hdfs分布式文件系统hadoop的集群模式单机模式伪分布

    hadoop历史背景&hdfs分布式文件系统&hadoop的集群模式&单机模式&伪分布 1.hadoop的历史背景 lucense ---->nutch----& ...

  7. Hadoop、分布式文件系统HDFS、YARN、MAPREDUCE

    日萌社 人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新) 1.1 什么是Hadoop Hadoop名字的由来 作者:Do ...

  8. Windows 7 64位系统上搭建Hadoop伪分布式环境(很详细)

    在开始配置前,我们先了解Hadoop的三种运行模式. Hadoop的三种运行模式 独立(或本地)模式:无需运行任何守护进程,所有程序都在同一个JVM上执行.在独立模式下测试和调试MapReduce程序 ...

  9. 看完就能独自把集群搭起来!Hadoop HDFS完全分布式环境搭建以及技术详解

    作者 | 慢慢变成大佬 责编 | Carol 出品 | CSDN云计算(ID:CSDNcloud) 在文章开始之前,作者想要告诉大家:读懂本篇文章,能让小白快速入门,并且能够搭建完全分布式的集群,以及 ...

最新文章

  1. SSH-Struts第三弹:传智播客视频教程第一天上午的笔记
  2. 开源数据库表结构文档生成器
  3. oracle分页置顶,[置顶]       ibatis查询oracle分页
  4. UITableviewcell重用机制以及解决重绘出现的重叠现象
  5. 监管升级,央行变相加息,贷款难还在继续
  6. Linux下send错误代码32
  7. 一套 SQL 搞定数据仓库?Flink有了新尝试
  8. 光彩集团小宇智能机器人_【青春关注】集团公司首台智能巡检机器人在我矿上线运行...
  9. in-list iterator
  10. 2020 Fall Berkeley CS61A Hog
  11. 远程控制——一句话木马
  12. 帆软所有销量为0的显示为空值_fineReport网络报表工具使用总结
  13. 题223.2022寒假天梯赛训练-7-12 清点代码库 (25 分)
  14. uniapp小程序当前页面刷新
  15. 个人也可以通过维瑞申请VeriSign,Thawte 代码签名证书
  16. 帝国cms html广告,帝国后台管理-广告系统插件 - 搜外设计社
  17. 【附源码】Python计算机毕业设计特大城市地铁站卫生防疫系统
  18. 计算机应用基础模块三项目二,计算机应用基础 高职计算机大类专业 刁爱军模块三 项目二 海报的制作.pptx...
  19. JS逆向时碰到了恶心的死代码怎么办?手把手教你解决!
  20. node.js的前世今生(特色篇)

热门文章

  1. 详细解答Java中抽象类和接口的区别问题!
  2. 边玩边学,30个Python小游戏(含源码)
  3. 日志框架LOG4J2系列二——log4j2配置文件
  4. 应急部消防救援局职业技能鉴定中心发布调整鉴定报名方式公告
  5. Linux就该这么学--Samba NFS的配置
  6. 3dsmaxC4DbodypainterPS画贴图三、摆放已经调节好大小比例的UV。
  7. 写一篇关于 供给侧改革 的申论
  8. 2016年张晓洋《基于BIM的桥梁建设期模型数据集成和安全分析》(会议论文)
  9. 云呐|资产管理系统平台,固定资产平台解决方案
  10. 多维随机变量及其分布