bigdata-07-Hdfs原理到实战

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: bigdata-07-Hdfs原理到实战

2.4-Hdfs核心原理

简介

HDFS的全称是Hadoop Distributed File System,即Hadoop分布式文件系统,它是一种允许文件通过网络在多台主机上分享的文件系统,可以让多台机器上的多个用户分享文件和存储空间,其实分布式文件管理系统有很多,HDFS只是其中一种实现而已,还有 GFS(谷歌的)、TFS(淘宝的)、S3(亚马逊的)等。

HDFS同时也是Hadoop项目的核心子项目,是分布式计算中数据存储管理的基础,是基于流数据模式访问和处理超大文件的需求而开发的,可以运行于廉价的商用服务器上。它所具有的高容错、高可靠性、高可扩展性、高获得性、高吞吐率等特征,为海量数据提供了不怕故障的存储。

HDFS优劣势分析

优势

1、可构建在廉价机器上,设备成本相对低

2、高容错性,HDFS将数据自动保存多个副本,副本丢失后,自动恢复,防止数据丢失或损坏

3、适合批处理,HDFS适合一次写入、多次查询(读取)的情况,适合在已有的数据进行多次分析,稳定性好

4、适合存储大文件,其中的大表示可以存储单个大文件,因为是分块存储,以及表示存储大量的数据

劣势

1、由于提高吞吐量,降低实时性

2、由于每个文件都会在namenode中记录元数据,如果存储了大量的小文件,会对namenode造成很大的压力 3、不合适小文件处理,在mapreduce的过程中小文件的数量会造成map数量的增大,导致资源被占用,而且速度慢。

4、不适合文件的修改,文件只能追加在文件的末尾,不支持任意位置修改,不支持多个写入者操作

架构

HDFS具有主/从架构

NameNode:管理节点

管理文件系统命名空间的主服务器和管理客户端对文件的访问组成,如打开,关闭和重命名文件和目录。负责管理文件目录、文件和block的对应关系以及block和datanode的对应关系,维护目录树,接管用户的请求。如下图所示:

1、将文件的元数据保存在一个文件目录树中 2、在磁盘上保存为:fsimage 和 edits 3、保存datanode的数据信息的文件,在系统启动的时候读入内存。

DataNode:数据节点

管理连接到它们运行的节点的存储,负责处理来自文件系统客户端的读写请求。DataNodes还执行块创建,删除.

Client:客户端

(客户端)代表用户通过与nameNode和datanode交互来访问整个文件系统,HDFS对外开放文件命名空间并允许用户数据以文件形式存储。用户通过客户端(Client)与HDFS进行通讯交互。

块和复制: 我们都知道linux操作系统中的磁盘的块的大小默认是512,而hadoop2.x版本中的块的大小默认为128M,那为什么hdfs中的存储块要设计这么大呢? 其目的是为了减小寻址的开销。只要块足够大,磁盘传输数据的时间必定会明显大于这个块的寻址时间。

那为什么要以块的形式存储文件,而不是整个文件呢? 1、因为一个文件可以特别大,可以大于有个磁盘的容量,所以以块的形式存储,可以用来存储无论大小怎样的文件。 2、简化存储系统的设计。因为块是固定的大小,计算磁盘的存储能力就容易多了 3、以块的形式存储不需要全部存在一个磁盘上,可以分布在各个文件系统的磁盘上,有利于复制和容错,数据本地化计算

块和副本在hdfs架构中分布如下图所示:

既然namenode管理着文件系统的命名空间,维护着文件系统树以及整颗树内的所有文件和目录,这些信息以文件的形式永远的保存在本地磁盘上,分别问命名空间镜像文件fsimage和编辑日志文件Edits。datanode是文件的工作节点,根据需要存储和检索数据块,并且定期的向namenode发送它们所存储的块的列表。那么就知道namenode是多么的重要,一旦那么namenode挂了,那整个分布式文件系统就不可以使用了,所以对于namenode的容错就显得尤为重要了,hadoop为此提供了两种容错机制

容错机制:

就是通过对那些组成文件系统的元数据持久化,分别问命名空间镜像文件fsimage(文件系统的目录树)和编辑日志文件Edits(针对文件系统做的修改操作记录)。

磁盘上的映像FsImage就是一个Checkpoint,一个里程碑式的基准点、同步点,有了一个Checkpoint之后,NameNode在相当长的时间内只是对内存中的目录映像操作,同时也对磁盘上的Edits操作,直到关机。下次开机的时候,NameNode要从磁盘上装载目录映像FSImage,那其实就是老的Checkpoint,也许就是上次开机后所保存的映像,而自从上次开机后直到关机为止对于文件系统的所有改变都记录在Edits文件中;将记录在Edits中的操作重演于上一次的映像,就得到这一次的新的映像,将其写回磁盘就是新的Checkpoint(也就是fsImage)。但是这样有很大一个缺点,如果Edits很大呢,开机后生成原始映像的过程也会很长,所以对其进行改进:每当 Edits长到一定程度,或者每隔一定的时间,就做一次Checkpoint,但是这样就会给namenode造成很大的负荷,会影响系统的性能。于是就有了SecondaryNameNode的需要,这相当于NameNode的助理,专替NameNode做Checkpoint。当然,SecondaryNameNode的负载相比之下是偏轻的。所以如果为NameNode配上了热备份,就可以让热备份兼职,而无须再有专职的SecondaryNameNode。所以架构图如下图所示:

SecondaryNameNode工作原理图:

SecondaryNameNode主要负责下载NameNode中的fsImage文件和Edits文件,并合并生成新的fsImage文件,并推送给NameNode,工作原理如下:

1、secondarynamenode请求主namenode停止使用edits文件,暂时将新的写操作记录到一个新的文件中; 2、secondarynamenode从主namenode获取fsimage和edits文件(通过http get) 3、secondarynamenode将fsimage文件载入内存,逐一执行edits文件中的操作,创建新的fsimage文件。 4、secondarynamenode将新的fsimage文件发送回主namenode(使用http post). 5、namenode用从secondarynamenode接收的fsimage文件替换旧的fsimage文件;用步骤1所产生的edits文件替换旧的edits文件。同时,还更新fstime文件来记录检查点执行时间。 6、最终,主namenode拥有最新的fsimage文件和一个更小的edits文件。当namenode处在安全模式时,管理员也可调用hadoop dfsadmin –saveNameSpace命令来创建检查点。

从上面的过程中我们清晰的看到secondarynamenode和主namenode拥有相近内存需求的原因(因为secondarynamenode也把fsimage文件载入内存)。因此,在大型集群中,secondarynamenode需要运行在一台专用机器上。

创建检查点的触发条件受两个配置参数控制。通常情况下,secondarynamenode每隔一小时(有fs.checkpoint.period属性设置)创建检查点;此外,当编辑日志的大小达到64MB(有fs.checkpoint.size属性设置)时,也会创建检查点。系统每隔五分钟检查一次编辑日志的大小。

图解流程

2.5-Hdfs shell

FS shell介绍

调用文件系统(FS)Shell命令应使用:

标准格式:

bin/hadoop fs

cat

将路径指定文件的内容输出到stdout

实例:

  • hadoop fs -cat hdfs://host1:port1/file1 hdfs://host2:port2/file2
  • hadoop fs -cat file:///file3 /user/hadoop/file4

返回值:

成功返回0,失败返回-1。

chgrp

改变文件所属的组。使用-R将使改变在目录结构下递归进行。

注意:命令的使用者必须是文件的所有者或者超级用户

实例:

  • hadoop fs -chgrp -R

chmod

改变文件的权限。使用-R将使改变在目录结构下递归进行

注意:命令的使用者必须是文件的所有者或者超级用户

实例:

  • hadoop fs -chmod -R

chown

改变文件的拥有者

注意:命令的使用者必须是超级用户

实例:

  • hadoop fs -chown

copyFromLocal

限定源路径是一个本地文件

从本地拷贝文件数据到hdfs

实例:

  • hadoop fs -copyFromLocal 本地路径 hdfsUrl

copyToLocal

从hdfs拷贝文件到本地

实例:

  • hadoop fs -copyToLocal hdfsUrl 本地路径

cp

将文件从源路径复制到目标路径。

这个命令允许有多个源路径,此时目标路径必须是一个目录。

示例:

  • hadoop fs -cp /user/hadoop/file1 /user/hadoop/file2
  • hadoop fs -cp /user/hadoop/file1 /user/hadoop/file2 /user/hadoop/dir

返回值:

成功返回0,失败返回-1。

du

使用方法:hadoop fs -du hdfsUrl

显示目录中所有文件的大小,或者当只指定一个文件时,显示此文件的大小。 示例: hadoop fs -du /user/hadoop/dir1 /user/hadoop/file1 hdfs://host:port/user/hadoop/dir1 返回值: 成功返回0,失败返回-1。

get

使用方法:hadoop fs -get

复制文件到本地文件系统。

示例:

  • hadoop fs -get /user/hadoop/file localfile
  • hadoop fs -get hdfs://host:port/user/hadoop/file localfile

返回值:

成功返回0,失败返回-1。

ls

使用方法:hadoop fs -ls

如果是文件,则按照如下格式返回文件信息: 文件名 <副本数> 文件大小 修改日期 修改时间 权限 用户ID 组ID 如果是目录,则返回它直接子文件的一个列表,就像在Unix中一样。

目录返回列表的信息如下: 目录名 修改日期 修改时间 权限 用户ID 组ID 示例: hadoop fs -ls /user/hadoop/file1 /user/hadoop/file2 hdfs://host:port/user/hadoop/dir1 /nonexistentfile 返回值: 成功返回0,失败返回-1。

lsr

使用方法:hadoop fs -lsr  ls命令的递归版本。类似于Linux中的ls -R。

mkdir

使用方法:hadoop fs -mkdir

接受路径指定的uri作为参数,创建这些目录。

其行为类似于Linux的mkdir -p,它会创建路径中的各级父目录。

示例:

  • hadoop fs -mkdir /user/hadoop/dir1 /user/hadoop/dir2
  • hadoop fs -mkdir hdfs://host1:port1/user/hadoop/dir hdfs://host2:port2/user/hadoop/dir

返回值:

成功返回0,失败返回-1。

mv

使用方法:hadoop fs -mv URI1 URl2

将文件从源路径移动到目标路径。

这个命令允许有多个源路径,此时目标路径必须是一个目录。不允许在不同的文件系统间移动文件。 示例:

  • hadoop fs -mv /user/hadoop/file1 /user/hadoop/file2
  • hadoop fs -mv hdfs://host:port/file1 hdfs://host:port/file2 hdfs://host:port/file3 hdfs://host:port/dir1

返回值:

成功返回0,失败返回-1。

put

使用方法:hadoop fs -put

从本地文件系统中复制单个或多个源路径到目标文件系统。也支持从标准输入中读取输入写入目标文件系统。

  • hadoop fs -put localfile /user/hadoop/hadoopfile
  • hadoop fs -put localfile1 localfile2 /user/hadoop/hadoopdir
  • hadoop fs -put localfile hdfs://host:port/hadoop/hadoopfile
  • hadoop fs -put - hdfs://host:port/hadoop/hadoopfile
  • 从标准输入中读取输入。

返回值:

成功返回0,失败返回-1。

rm

使用方法:hadoop fs -rm URI

删除指定的文件。只删除非空目录和文件。请参考rmr命令了解递归删除。 示例:

  • hadoop fs -rm hdfs://host:port/file /user/hadoop/emptydir

返回值:

成功返回0,失败返回-1。

rmr

使用方法:hadoop fs -rmr URI

delete的递归版本。 示例:

  • hadoop fs -rmr /user/hadoop/dir
  • hadoop fs -rmr hdfs://host:port/user/hadoop/dir

返回值:

成功返回0,失败返回-1。

setrep

使用方法:hadoop fs -setrep [-R]

改变一个文件的副本系数。-R选项用于递归改变目录下所有文件的副本系数。

示例:

  • hadoop fs -setrep -w 3 -R /user/hadoop/dir1

返回值:

成功返回0,失败返回-1。

stat

使用方法:hadoop fs -stat URI

返回指定路径的统计信息。

示例:

  • hadoop fs -stat path

返回值: 成功返回0,失败返回-1。

tail

使用方法:hadoop fs -tail [-f]

将文件尾部1K字节的内容输出到stdout。支持-f选项,行为和Unix中一致。

示例:

  • hadoop fs -tail pathname

返回值: 成功返回0,失败返回-1。

test

使用方法:hadoop fs -test -[ezd] URI

选项: -e 检查文件是否存在。如果存在则返回0。 -z 检查文件是否是0字节。如果是则返回0。 -d 如果路径是个目录,则返回1,否则返回0。

示例:

  • hadoop fs -test -e filename

text

使用方法:hadoop fs -text

将源文件输出为文本格式。允许的格式是zip和TextRecordInputStream。

touchz

使用方法:hadoop fs -touchz URI [URI …]

创建一个0字节的空文件。

示例:

  • hadoop -touchz pathname

返回值: 成功返回0,失败返回-1。

2.6-Hdfs Java Api

创建Maven项目添加依赖

<dependency>
  <groupId>org.apache.hadoop</groupId>
  <artifactId>hadoop-client</artifactId>
  <version>3.2.0</version>
</dependency>

前置代码

//创建一个配置对象
Configuration conf = new Configuration();
//指定HDFS的地址
conf.set("fs.defaultFS","hdfs://bigdata01:9000");
//获取操作HDFS的对象
FileSystem fileSystem = FileSystem.get(conf);

删除文件或目录

private static void delete(FileSystem fileSystem) throws IOException {
    //删除文件,目录也可以删除
    //如果要递归删除目录,则第二个参数需要设置为true
    //如果删除的是文件或者空目录,第二个参数会被忽略
    boolean flag = fileSystem.delete(new Path("/LICENSE.txt"),true);
    if(flag){
        System.out.println("删除成功!");
    }else{
        System.out.println("删除失败!");
    }
}

下载文件

private static void get(FileSystem fileSystem) throws IOException {
    //获取HDFS文件系统中的输入流
    FSDataInputStream fis = fileSystem.open(new Path("/README.txt"));
    //获取本地文件的输出流
    FileOutputStream fos = new FileOutputStream("D:\\README.txt");
    //下载文件
    IOUtils.copyBytes(fis,fos,1024,true);
}

上传文件

private static void put(FileSystem fileSystem) throws IOException {
    //获取本地文件的输入流
    FileInputStream fis = new FileInputStream("D:\\user.txt");
    //获取HDFS文件系统的输出流
    FSDataOutputStream fos = fileSystem.create(new Path("/user.txt"));
    //上传文件:通过工具类把输入流拷贝到输出流里面,实现本地文件上传到HDFS
    IOUtils.copyBytes(fis,fos,1024,true);
}

上述基础操作基本能够满足在公司中需求,扩展Api参考官方文档

2.7-Hdfs 核心进程剖析

NameNode

功能

NameNode是整个文件系统的管理节点,它主要维护着整个文件系统的文件目录树,文件/目录的信息 和 每个文件对应的数据块列表,并且还负责接收用户的操作请求

  • 目录树:表示目录之间的层级关系,就是我们在hdfs上执行ls命令可以看到的那个目录结构信息
  • 目录信息:目录的的一些基本信息,所有者 属组 修改时间 文件大小等信息
  • 数据块列表:如果一个文件太大,那么在集群中存储的时候会对文件进行切割,这个时候就类似于会给文件分成一块一块的,存储到不同机器上面。所以HDFS还要记录一下一个文件到底被分了多少块,每一块都在哪个节点存储。
  • 接收用户的操作请求:我们无论使用命令行,还是相关的Java Api都是与NameNode进行通信之后才去操作数据

文件信息

  • fsimage:元数据镜像文件,存储某一时刻NameNode内存中的元数据信息,就类似是定时做了一个快照操作。(元数据:文件目录树、文件/目录的信息、每个文件对应的数据块列表)
  • edits:操作日志文件【事务文件】,这里面会实时记录用户的所有操作
  • seen_txid:是存放transactionId的文件,format之后是0,它代表的是namenode里面的edits_*文件的尾数,namenode重启的时候,会按照seen_txid的数字,顺序从头跑edits_0000001~到seen_txid的数字。如果根据对应的seen_txid无法加载到对应的文件,NameNode进程将不会完成启动以保护数据一致性
  • VERSION:集群的版本信息

SecondaryNameNode

功能

  • 定期的把edits文件中的内容合并到fsimage中
  • 合并操作称为checkpoint,在合并的时候会对edits中的内容进行转换,生成新的内容保存到fsimage文件中。
  • PS:在NameNode的HA架构中没有SecondaryNameNode进程,文件合并操作会由standby NameNode负责实现
    所以在Hadoop集群中,SecondaryNameNode进程并不是必须的。

DataNode

功能

  • 提供真实文件数据的存储服务

核心店

  • Block:HDFS会按照固定的大小,顺序对文件进行划分并编号,划分好的每一个块称一个Block,HDFS默认Block大小是 128MB,Block块是HDFS读写数据的基本单位,不管你的文件是文本文件 还是视频或者音频文件,针对hdfs而言都是字节。HDFS中,如果一个文件小于一个数据块的大小,那么并不会占用整个数据块的存储空间。
  • Replication:副本表示数据有多少个备份,默认这个参数的配置是3,副本只有一个作用就是保证数据安全。副本个数可以配置,在hdfs-site.xml中进行配置的,dfs.replication=副本数

总结

NameNode维护了两份关系

  • 第一份关系:File 与Block list的关系,对应的关系信息存储在fsimage和edits文件中,当NameNode启动的时候会把文件中的元数据信息加载到内存中
  • 第二份关系:DataNode与Block的关系,对应的关系主要在集群启动的时候保存在内存中,当DataNode启动时会把当前节点上的Block信息和节点信息上报给NameNode

Hdfs回收站

  • HDFS会为每一个用户创建一个回收站目录:/user/用户名/.Trash/,每一个被用户在Shell命令行删除的文件/目录,会进入到对应的回收站目录中,在回收站中的数据都有一个生存周期,也就是当回收站中的文件/目录在一段时间之内没有被用户恢复的话,HDFS就会自动的把这个文件/目录彻底删除,之后,用户就永远也找不回这个文件/目录了。
  • 默认情况下hdfs的回收站是没有开启的,需要通过一个配置来开启,在core-site.xml中添加如下配置,value的单位是分钟,1440分钟表示是一天的生存周期
  • 注意:如果删除的文件过大,超过回收站大小的话会提示删除失败,需要指定参数 -skipTrash ,指定这个参数表示删除的文件不会进回收站

Hdfs安全模式

  • 集群刚启动时HDFS会进入安全模式,此时无法执行写操作
  • 查看安全模式:hdfs dfsadmin -safemode get
  • 离开安全模式:hdfs dfsadmin -safemode leave
相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
6月前
|
分布式计算 Java 大数据
【大数据技术Hadoop+Spark】HDFS Shell常用命令及HDFS Java API详解及实战(超详细 附源码)
【大数据技术Hadoop+Spark】HDFS Shell常用命令及HDFS Java API详解及实战(超详细 附源码)
693 0
|
6月前
|
存储 分布式计算 Hadoop
Hadoop【基础知识 01】【分布式文件系统HDFS设计原理+特点+存储原理】(部分图片来源于网络)
【4月更文挑战第3天】Hadoop【基础知识 01】【分布式文件系统HDFS设计原理+特点+存储原理】(部分图片来源于网络)
224 3
|
6月前
|
存储 分布式计算 Hadoop
【大数据技术Hadoop+Spark】HDFS概念、架构、原理、优缺点讲解(超详细必看)
【大数据技术Hadoop+Spark】HDFS概念、架构、原理、优缺点讲解(超详细必看)
462 0
|
5月前
|
存储 分布式计算 Hadoop
Hadoop Distributed File System (HDFS): 概念、功能点及实战
【6月更文挑战第12天】Hadoop Distributed File System (HDFS) 是 Hadoop 生态系统中的核心组件之一。它设计用于在大规模集群环境中存储和管理海量数据,提供高吞吐量的数据访问和容错能力。
634 4
|
1月前
Hadoop-09-HDFS集群 JavaClient 代码上手实战!详细附代码 安装依赖 上传下载文件 扫描列表 PUT GET 进度条显示(二)
Hadoop-09-HDFS集群 JavaClient 代码上手实战!详细附代码 安装依赖 上传下载文件 扫描列表 PUT GET 进度条显示(二)
40 3
|
1月前
|
分布式计算 Java Hadoop
Hadoop-09-HDFS集群 JavaClient 代码上手实战!详细附代码 安装依赖 上传下载文件 扫描列表 PUT GET 进度条显示(一)
Hadoop-09-HDFS集群 JavaClient 代码上手实战!详细附代码 安装依赖 上传下载文件 扫描列表 PUT GET 进度条显示(一)
40 2
|
1月前
|
分布式计算 Hadoop 网络安全
Hadoop-08-HDFS集群 基础知识 命令行上机实操 hadoop fs 分布式文件系统 读写原理 读流程与写流程 基本语法上传下载拷贝移动文件
Hadoop-08-HDFS集群 基础知识 命令行上机实操 hadoop fs 分布式文件系统 读写原理 读流程与写流程 基本语法上传下载拷贝移动文件
30 1
|
1月前
|
存储 机器学习/深度学习 缓存
Hadoop-07-HDFS集群 基础知识 分布式文件系统 读写原理 读流程与写流程 基本语法上传下载拷贝移动文件
Hadoop-07-HDFS集群 基础知识 分布式文件系统 读写原理 读流程与写流程 基本语法上传下载拷贝移动文件
42 1
|
6月前
|
存储 分布式计算 监控
Hadoop【基础知识 01+02】【分布式文件系统HDFS设计原理+特点+存储原理】(部分图片来源于网络)【分布式计算框架MapReduce核心概念+编程模型+combiner&partitioner+词频统计案例解析与进阶+作业的生命周期】(图片来源于网络)
【4月更文挑战第3天】【分布式文件系统HDFS设计原理+特点+存储原理】(部分图片来源于网络)【分布式计算框架MapReduce核心概念+编程模型+combiner&partitioner+词频统计案例解析与进阶+作业的生命周期】(图片来源于网络)
304 2
|
6月前
|
存储 运维 分布式计算
面经:HDFS分布式文件系统原理与故障排查
【4月更文挑战第10天】本文深入剖析了HDFS的底层原理和面试重点,包括HDFS的架构(NameNode、DataNode、Secondary NameNode)、文件读写流程、高级特性(快照、Erasure Coding、Federation、High Availability)以及故障排查方法。通过HDFS Shell命令示例,加强理解,并对比了HDFS与其他分布式文件系统的优缺点。掌握这些知识将有助于求职者在面试中脱颖而出,应对HDFS相关技术考察。
449 3

热门文章

最新文章

相关实验场景

更多