文章目录

  • 1.hdfs是什么
  • 2.hdfs架构
  • 3.hdfs读写过程
  • 3.1 相关概念
  • 3.2 写文件过程
  • 3.2 读文件过程
  • 4.datenode什么情况下不会备份
  • 5.HDFS中大量小文件带来的问题以及解决的方案
  • 5.HDFS的核心组件及其作用
  • 6.fsimage和editlogs的作用
  • 7. fsimage和editlogs为什么要合并?如何合并?
  • 8. SecondaryNameNode的作用
  • 9. hdfs能否并发写入
  • 10. hdfs故障检测机制
  • 11. hdfs容错机制
  • 11.1 读容错
  • 11.2 写容错
  • 11.3 DataNode失效
  • 12. hdfs备份策略
  • 13. hdfs的HA架构


1.hdfs是什么

hdfs(Hadoop Distribute File System)是分布式文件系统。

分布式文件系统 distributed file system 是指文件系统管理的物理存储资源不一定直接链接在本地节点上,而是通过计算机网络与节点相连,可让多机器上的多用户分享文件和存储空间。

说简单点就是将一个大文件分布式存储在不同的机器节点上

2.hdfs架构

答:
1.HDFS为主从架构,由单个NameNode和多个DataNode组成,另外还包括SecondaryNameNode。
2.NameNode主要负责管理dataNode和记录元数据。由FsImage和EditLog两部分组成。

  • FsImage用户维护文件目录和元数据
  • EditLog则记录所有对文件操作的操作。

3.DataNode负责存储数据,同时定期与NameNode进行通信,汇报自己存储的信息。
4.SecondaryNameNode负责合并日志,定期将新的FsImage拷贝回dataNode。

详解:

HDFS具有主/从架构。HDFS集群由单个NameNode多个datanode构成。

1)Namenode是负责管理分布式文件系统的命名空间(Namespace),保存了两个核心的数据结构,即FsImage和EditLog。NodeName负责管理文件目录、文件和block的对应关系以及block和datanode的对应关系,维护目录树,接管用户的请求。NameNode节点仅存储元数据,而不存储真实的数据,可以理解NameNode存储真实的数据存放位置的信息。

  • FsImage用于维护文件系统树以及文件树中所有的文件和文件夹的元数据
  • 操作日志文件EditLog中记录了所有针对文件的创建、删除、重命名等操作。

如下图所示:

hadoop算法面试 hdfs面试问题_HDFS

2)datanode数据节点,用来具体的存储文件,维护了blockId 与 datanode本地文件的映射。 需要不断的与namenode节点通信,来告知其自己的信息,方便nameode来管控整个系统。

将大文件分块存储在dataNode上,通过NameNode的上信息可以知道一个文件被分成了多少块,每一块存储在哪个dataNode上。

注意:有一个副本的概念,就是每一个块会默认生成三个副本,存储在多个dataNode上,这样就会防止dataNode失效导致数据丢失。

hadoop算法面试 hdfs面试问题_hadoop算法面试_02

3.hdfs读写过程

3.1 相关概念

很多博文介绍HDFS读写流程上来就直接从文件分块开始,其实,要把读写过程细节搞明白前,你必须知道block、packet与chunk。

  • block:文件上传前需要分块,这个块就是block,一般为128MB,当然你可以去改,不顾不推荐。因为块太小:寻址时间占比过高。块太大:Map任务数太少,作业执行速度变慢。它是最大的一个单位。
  • packet:packet是第二大的单位,它是client端向DataNode,或DataNode的PipLine之间传数据的基本单位,默认64KB。
  • chunk:chunk是最小的单位,它是client向DataNode,或DataNode的PipLine之间进行数据校验的基本单位,默认512Byte,因为用作校验,故每个chunk需要带有4Byte的校验位。所以实际每个chunk写入packet的大小为516Byte。由此可见真实数据与校验值数据的比值约为128 : 1。(即64*1024 / 512)

3.2 写文件过程

  1. 客户端向NameNode发送写数据请求
  2. NameNode检查是否已存在文件、检查权限。若通过检查,直接先将操作写入EditLog
  3. 客户端切分文件为多个block。
  4. 客户端请求第一个 Block上传到哪几个DataNode服务器上
  5. NameNode返回多个DataNode节点,例如返回三个分别为dn1、dn2、dn3。表示这一个block的多个副本会存储在这些节点上。
  6. 客户端通过FSDataOutputStream模块请求dn1上传数据,dn1收到请求会继续通信dn2,然后dn2通信dn3,将这个通信管道建立完成。
  7. dn1、dn2、dn3逐级应答客户端。
  8. 客户端开始往dn1上传第一个Block(先从磁盘读取数据放到一个本地内存缓存),以Packet为单位,dn1收到一个Packet就会传给dn2,dn2传给dn3;dn1每传一个packet会放入一个应答队列等待应答。
    8)当一个Block传输完成之后,客户端再次请求NameNode上传第二个Block的服务器。(重复执行4-8步)

3.2 读文件过程

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

4.datenode什么情况下不会备份

设置备份数为1时, 就不会备份了.

延申—Hadoop中在哪里设置备份数, 是哪个字段?
在hdfs-site.xml中的dfs.replication变量

5.HDFS中大量小文件带来的问题以及解决的方案

问题:

  • hadoop中目录,文件和块都会以对象的形式保存在namenode的内存中, 大概每个对象会占用150bytes. 小文件数量多会大量占用namenode的内存; 使namenode读取元数据速度变慢, 启动时间延长; 还因为占用内存过大, 导致gc时间增加等.
  • 其次,MR实践中,会有很多小文件,单个文件产生一个mapper,资源比较浪费,后续没有reduce逻辑的话,会产生很多小文件,文件数量暴涨,对后续的hive job产生影响。

解决方法:

1)使用HAR
Archivehadoop Archive是一个高效地将小文件放入HDFS块中的文件存档文件格式,它能够将多个小文件打包成一个后缀为.har文件,这样减少namenode内存使用的同时,仍然允许对文件进行透明的访问。

使用HAR时需要两点

  • 第一,对小文件进行存档后,原文件并不会自动被删除,需要用户自己删除;
  • 第二,创建HAR文件的过程实际上是在运行一个mapreduce作业,因而需要有一个hadoop集群运行此命令。

该方案需人工进行维护,适用管理人员的操作,而且har文件一旦创建,Archives便不可改变,不能应用于多用户的互联网操作。

2)sequence file

sequence file由一系列的二进制key/value组成,如果为key小文件名,value为文件内容,则可以将大批小文件合并成一个大文件。

Hadoop-0.21.0中提供了SequenceFile,包括Writer,Reader和SequenceFileSorter类进行写,读和排序操作。

该方案对于小文件的存取都比较自由,不限制用户和文件的多少,但是SequenceFile文件不能追加写入,适用于一次性写入大量小文件的操作

3)CombineFileInputFormat

CombineFileInputFormat是一种新的inputformat,用于将多个文件合成一个单独的split,而且它还可以考虑数据的存储位置。在mapper中将多个文件合成一个split作为输入。

5.HDFS的核心组件及其作用

1 NameNode. 集群的核心, 是整个文件系统的管理节点. 维护着
a) 文件系统的文件目录结构和元数据信息
b) 文件与数据块列表的对应关系
2 DataNode. 存放具体数据块的节点, 主要负责数据的读写, 定期向NameNode发送心跳
3 SecondaryNameNode. 辅助节点, 同步NameNode中的元数据信息, 辅助NameNode对fsimage和editsLog进行合并.

6.fsimage和editlogs的作用

  • FsImage用于维护文件系统树以及文件树中所有的文件和文件夹的元数据
  • 操作日志文件EditLog中记录了所有针对文件的创建、删除、重命名等操作。

7. fsimage和editlogs为什么要合并?如何合并?

为什么要合并?

edits文件记录了客户端对HDFS所做的各种更新操作,客户端所有的写操作都被记录在了此文件中。
而fsimage文件记录了元数据的文件,这个文件不是实时的,通俗来说,更像是对HDFS的一个快照,它记录了某个时刻下的HDFS的状态信息。

在namenode运行期间, 客户端对hdfs的写操作都保存到edit文件中, 久而久之就会造成edit文件变得很大, 这对namenode的运行没有影响, 但是如果namenode重启, 它会将fsimage中的内容映射到内存中, 然后再一条一条执行edit文件中的操作, 所以日志文件太大会导致重启速度很慢. 所以在namenode运行的时候就要将edit logs和fsimage定期合并.

触发合并的条件

  • HDFS的重新启动
  • edits文件达到指定的大小(默认64M,可更改)
  • 设置了指定时间促使两文件合并(默认3600s,可更改)

合并过程:

那么这两个文件是如何合并的呢?这就引入了checkpoint机制

checkpoint机制:
因为文件合并过程需要消耗io和cpu所以需要将这个过程独立出来,在Hadoop1.x中是由Secondnamenode来完成,且Secondnamenode必须启动在单独的一个节点最好不要和namenode在同一个节点,这样会增加namenode节点的负担,而且维护时也比较方便。同样在HA集群中这个合并的过程是由Standbynamenode完成的。

详细请看:

其实总结一下:合并其实就是同步两个文件,生成一个新的fsimage文件,下次再启动hdfs的时候,就可以从上次同步的位置开始读取editlog即可。

8. SecondaryNameNode的作用

很多人会将SecondaryNameNode认为是NameNode节点的备份节点。但是实际上不是的,SecondaryNameNode的本质作用是辅助NameNode进行fsimage和editlogs的合并操作。

下图展示了SecondaryNameNode的工作过程:

hadoop算法面试 hdfs面试问题_hadoop算法面试_03

  1. 首先,它定时到NameNode去获取edit logs,并更新到fsimage上。[注:Secondary NameNode自己的fsimage]
  2. 一旦它有了新的fsimage文件,它将其拷贝回NameNode中。
  3. NameNode在下次重启时会使用这个新的fsimage文件,从而减少重启的时间。

Secondary NameNode的整个目的是在HDFS中提供一个检查点。它只是NameNode的一个助手节点。这也是它在社区内被认为是检查点节点的原因。

9. hdfs能否并发写入

不行, 因为客户端通过namenode接收到在数据块上写入的许可后, 那个块会锁定直到写入操作完成, 所以不能在同一个块上写入.

10. hdfs故障检测机制

故障的类型主要有以下三种,针对这三种故障类型,HDFS提供了不同的故障检测机制:

  • 针对DataNode失效问题, HDFS使用了心跳机制,DataNode定期向NameNode发送心跳信息,NameNode根据心跳信息判断DataNode是否存活;
  • 针对网络故障而导致无法收发数据的问题,HDFS提供了ACK的机制,在发送端发送数据后,如果没有收到ACK并且经过多次重试后仍然如此,则认为网络故障;
  • 针对数据损坏问题,所有DataNode会定期向NameNode发送自身存储的块清单,在传输数据的同时会发送总和校验码,NameNode依次来判断数据是否丢失或损坏。

11. hdfs容错机制

11.1 读容错

由于在读HDFS的过程中会从NameNode获取到数据块位置列表,如果某个DataNode失效,换个DataNode读即可。

11.2 写容错

写HDFS的过程中会对多个DataNode建立管道进行写入,每个DN收到数据包就会返回应答,如果数据发送者没有收到其中某个DataNode的ACK,则认为该DataNode失效,会跳过该DataNode并将数据写入剩余DataNode。

这样会导致副本数会减少,NameNode收集DataNode信息时发现文件的副本数与设置值不一致,会重新寻找一个DataNode保存副本。

11.3 DataNode失效

在NameNode中会持有数据块表和DataNode两张表。

hadoop算法面试 hdfs面试问题_HDFS_04


数据块表存储着某个数据块(包括副本)所在的DataNode,DataNode表存储着每个DataNode中保存的数据块列表。由于DataNode会周期性地给NameNode发送自己所持有的数据块信息,因此NameNode会持续更新数据块表和DataNode表。

  • 如果发现某个DataNode上的数据块错误,NameNode会从数据块表删除该数据块;
  • 如果发现某个DataNode失效,NameNode会对两张表进行更新。

NameNode还会周期性地扫描数据块表,如果发现数据块表中某个数据库的备份数量低于所设置的备份数,则会协调从其它DataNode复制数据到另一个DataNode上完成备份。

12. hdfs备份策略

首先我们要明白机架与数据节点,集群会被分给不同的机架,每个机架上又有多个DN节点。

数据块的第一个副本优先放在写入数据块的客户端所在的节点上,但是如果这个客户端上的数据节点空间不足或者是当前负载过重,则应该从该数据节点所在的机架中选择一个合适的数据节点作为本地节点。

如果客户端上没有一个数据节点的话,则从整个集群中随机选择一个合适的数据节点作为此时这个数据块的本地节点

HDFS的存放策略是将一个副本存放在本地机架节点上,另外两个副本放在不同机架的不同节点上。

这样集群可在完全失去某一机架的情况下还能存活。同时,这种策略减少了机架间的数据传输,提高了写操作的效率,因为数据块只存放在两个不同的机架上,减少了读取数据时需要的网络传输总带宽。这样在一定程度上兼顾了数据安全和网络传输的开销。

13. hdfs的HA架构

对于NameNode本身就存在单点故障,如果NameNode出现故障,则整个集群会直接宕机。因此HDFS提供了HA的架构,对于一个典型的HA集群而言,NameNode会被配置在两台独立的机器上,在任何时间上,一个NameNode处于Active状态,而另一个NameNode处于Standby状态,Active状态的NameNode会响应集群中所有的客户端的请求,Standby状态的NameNode只是作为一个副本,保证在必要的时候提供一个快速的转移,使得上层对NameNode的切换无感知,Standby NameNode与Active NameNode应时刻保持同步,在Active NameNode和Standby NameNode之间要有个共享的存储日志的地方,Active NameNode把EditLog写到共享的存储日志中,Standby NameNode读取日志并执行,使得Active NameNode和Standby NameNode内存中的HDFS元数据保持同步。