大数据常见面试题之hdfs

一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(64KB)为单位,dn1收到一个packet就会传给dn2,dn3传给dn3;dn1每传一个packet会放入一个应答队列等待应答。
  • 8.当一个block传输完成之后,客户端再次请求NameNode上传第二个block的服务器。(重复执行3-7步)。

二.hdfs读数据流程

在这里插入图片描述

  • 1.首先调用FileSystem.open()方法,获取到DistributedFileSystem实例。
  • 2.DistributedFileSystem向NameNode发起RPC(远程过程调用)请求获得文件的开始部分或全部block列表,对于每个返回的块,都包含块所在的DataNode地址。这些DataNode会按照Hadoop定义的集群拓扑结构得出客户端的距离,然后再进行排序。如果客户端本身就是一个DataNode,那么它将从本地读取文件。(只会选取一个最近的文件)
  • 3.DistributedFileSystem会向客户端client返回一个支持文件定位的输入流对象FSDataInputStream,用于客户端读取数据,FSDataInputStream包含一个DFSInputStream对象,这个对象用来管理DataNode和NameNode之间的I/O。
  • 4.客户端调用read()方法,DFSInputStream就会找出离客户端最近的datanode并连接datanode.
  • 5.DFSInputStream对象中包含文件开始部分的数据块所在的DataNode地址,首先它会连接包含文件第一块最近的DataNode。随后,在数据流中重复调用read()函数,直到这个块去全部读完为止。如果第一个block块的数据读完,就会关闭指向第一个block块的datanode连接,接着读取下一个block块。
  • 6.如果第一批block都读完了,DFSInputStream就会去NameNode拿下一批blocks的location,然后继续读,如果所有的block块都读完,这时就会关闭掉所有的流。
    注意 read方法是并行的读取block信息,不是一块一块的读取;NameNode只是返回Client请求包含块的DataNode地址,并不是返回请求块的数据。最终读取来所有的block会合并成一个完整的最终文件。

三.简单说说HDFS中NameNode,DataNode的作用?

1.NameNode

  • 就是Master,它是一个主管,管理者。也叫HDFS的元数据节点。集群中只能有一个Active的NameNode对外提供服务。
    1)管理HDFS的名称空间(文件目录树);HDFS很方便的一点就是对于用户来说很友好,用户不考虑细节的话,看到的目录结构和我们使用Window和Linux文件系统很像。
    2)管理数据块(Block)映射信息及副本信息;一个文件对应的块的名字以及块被存储在哪里,以及每一个文件备份多少都是由NameNode来管理。
    3)处理客户端读写请求。

2.DataNode

  • 就是Slave。实际存储数据块的节点,NameNode下达命令,DataNode执行实际的操作。
    1)存储实际的数据块
    2)执行数据库的读/写操作。

四.SecondaryNameNode的作用?或者是NameNode的启动过程?

SecondaryNameNode有两个作用:一是镜像备份,二是日志与镜像的定期合并,即合并NameNode的edit logs到fsimage文件中

第一阶段:NameNode启动
1)第一次启动NameNode格式化后,创建fsimage和edits文件。如果不是第一次启动,直接加载编辑日志和镜像文件到内存。
2)客户端对元数据进行增删改的请求。
3)NameNode记录操作日志,更新滚动日志。
4)NameNode在内存中对数据进行增删改查。

第二阶段:Secondary NameNode工作
1)Secondary NameNode询问NameNode是否需要checkpoint。直接带回NameNode是否检查结果。
2)Secondary NameNode请求执行checkpoint。
3)NameNode滚动正在写的edits日志。
4)将滚动前的编辑日志和镜像文件拷贝到Secondary NameNode。
5)Secondary NameNode加载编辑日志和镜像文件到内存,并合并。
6)生成新的镜像文件fsimage.chkpoint。
7)拷贝fsimage.chkpoint到NameNode。
8)NameNode将fsimage.chkpoint重新命名成fsimage。

五.集群安全模式?什么情况下会进入到安全模式?安全模式的解决办法?

1.进入安全模式的情况

  • 集群启动时必定会进入安全模式:
  • NameNode启动时,首先将镜像文件(fsimage)载入内存,并执行编辑日志(edits)中的各项操作。一旦在内存中成功建立文件系统元数据的映像,则创建一个新的fsimage文件和一个空的编辑日志。此时,NameNode开始监听DataNode请求。但是此刻,NameNode运行在安全模式,即NameNode的文件系统对于客户端来说是只读的。
  • 系统中的数据块的位置并不是由NameNode维护的,而是以块列表的形式存储在DataNode中。在系统的正常操作期间,NameNode会在内存中保留所有块位置的映射信息。在安全模式下,各个DataNode会向NameNode发送最新的块列表信息,NameNode了解到足够多的块位置信息之后,即可高效运行文件系统。
  • 如果满足“最小副本条件”,NameNode会在30秒钟之后就退出安全模式。所谓的最小副本条件指的是在整个文件系统中99.9%的块满足最小副本级别(默认值:dfs.replication.min=1)。在启动一个刚刚格式化的HDFS集群时,因为系统中还没有任何块,所以NameNode不会进入安全模式。

2.异常情况下导致的安全模式

  • 原因:block确实有缺失,当namenode发现集群中的block丢失数量达到一个阀值时,namenode就会进入安全模式状态,不再接受客户端的数据更新请求。

解决办法

  • 1)调低阀值
<!-- hdfs-site.xml中:-->
<name>dfs.namenode.safemode.threshold</name>
<value>0.999f</name>
  • 2)强制离开: hdfs dfsadmin -safemode leave
  • 3)重新格式化集群
  • 4)修复损坏的块文件

六.为什么HDFS不适合小文件

  • HDFS天生就是为存储大文件而生的,一个块的元数据大小大概在150字节左右,存储一个小文件就要占用NameNode150字节内存,如果存储大量的小文件很快就将NameNode内存耗尽,而整个集群存储的数据量很小,失去了HDFS的意义,同时也会影响NameNode的寻址时间,导致寻址时间过长。

七.HDFS支持的存储格式和压缩算法?

1.存储格式

1)SequenceFile
以二进制键值对的形式存储数据,支持三种记录存储方式。
• 无压缩:io效率较差,相对压缩,不压缩的情况下没有什么优势。
• 记录级压缩:对每条记录都压缩,这种压缩效率比较一般。
• 块级压缩:这里的块不同于HDFS中的块的概念,这种方式会将达到指定块大小的二进制数据压缩为一个块。

2)Avro

  • 将数据定义和数据一起存储在一条消息中,其中数据定义以JSON格式存储,数据以二进制格式存储。Avro标记用于将大型数据集分割成适合MapReduce处理的子集。

3)RCFile

  • 以列格式保存每个行组数据。它不是存储第一行然后是第二行,而是存储所有行上的第1列,然后是所行上的第2列,以此类推。

4)Parquet

  • 是Hadoop的一种列存储格式。提供了高效的编码和压缩方案。

2.压缩算法

1)Gzip压缩

  • 优点:压缩率比较高,而且压缩/解压速度也比较快;Hadoop本身支持,在应用中处理gzip格式的文件就和直接处理文本一样;大部分Linux系统都自带gzip命令,使用方便。
  • 缺点;不支持split。
  • 应用场景:当每个文件压缩之后在130M以内的(1个块大小内),都可以考虑用gzip压缩格式。例如说一天或者一个小时的日志压缩成一个gzip文件,运行MapReduce程序的时候通过多个gzip文件达到并发。Hive程序,streaming程序,和Java写的MapReduce程序完全和文本处理一样,压缩之后原来的程序不需要做任何修改。

2)Bzip2压缩

  • 优点:支持split;具有很高的压缩率,比gzip压缩率都高;Hadoop本身支持,但不支持native;在Linux系统下自带bzip2命令,使用方便。
  • 缺点:压缩/解压速度慢;不支持native。
  • 应用场景:适合对速度要求不高,但需要较高的压缩率的时候,可以作为MapReduce作业的输出格式;或者输出之后的数据比较大,处理之后的数据需要压缩存档减少磁盘空间并且以后数据用得比较少的情况;或者对单个很大的文本文件想压缩减少存储空间,同时又需要支持split,而且兼容之前的应用程序(即应用程序不需要修改)的情况。

3)Lzo压缩

  • 优点:压缩/解压速度也比较快,合理的压缩率;支持split,是Hadoop中最流行的压缩格式;可以在Linux系统下安装lzop命令,使用方便。
  • 缺点:压缩率比gzip要低一些;Hadoop本身不支持,需要安装;在应用中对lzo格式的文件需要做一些特殊处理(为了支持split需要建索引,还需要指定inputformat为lzo格式)。
  • 应用场景:一个很大的文本文件,压缩之后还大于200M以上的可以考虑,而且单个文件越大,lzo优点越明显。

4)Snappy压缩

  • 优点:高速压缩速度和合理的压缩率。
  • 缺点:不支持split;压缩率比gzip要低;Hadoop本身不支持,需要安装;
  • 应用场景:当MapReduce作业的Map输出的数据比较大时,作为Map到Reduce的中间数据的压缩格式;或者作为一个MapReduce作业的输出和另外一个MapReduce作业的输入。

八.HDFS的可靠性策略

1.文件完整性

  • 1)在文件建立时,每个数据块都产生校验和,校验和会保存在.meta文件内。
  • 2)客户端获取数据时可以检查校验和是否相同,从而发现数据块是否损坏。
  • 3)如果正在读取的数据块损坏,则可以继续读取其他副本。NameNode标记该块已经损坏,然后复制block达到预期设置的文件备份数。
  • 4)DataNode在其文件创建后三周验证其checksum。

2.网络或者机器失效时

  • 1)副本冗余。
  • 2)机架感知策略(副本放置策略)。
  • 3)心跳机制策略。

3.NameNode挂掉时

  • 1)主备切换(高可用)。
  • 2)镜像文件和操作日志磁盘存储。
  • 3)镜像文件和操作日志可以存储多份,多磁盘存储。

4.其他保障可靠性机制

  • 1)快照(和虚拟机快照意义相同,保存了系统某一时刻的影像,可以还原到该时)。
  • 2)回收站机制。
  • 2)安全模式

九.HDFS的优缺点?

1.HDFS优点

  • 1)高容错性:数据自动保存多个副本,副本丢失后,会自动恢复。
  • 2)适合批处理:移动计算而非数据,数据位置暴露给计算框架。
  • 3)适合大数据处理:GB,TB,甚至PB级数据,百万规模以上的文件数量,1000以上节点规模。
  • 4)流式文件访问:一次性写入,多次读取;保证数据一致性。
  • 5)可构建在廉价机器上:通过多副本提高可靠性,提供了容错和恢复机制。

2.HDFS缺点

  • 1)不适合低延迟数据访问:比如毫秒级,低延迟与高吞吐率。
  • 2)不适合小文件存取:占用NameNode大量内存,寻道时间超过了读取时间。
  • 3)不适合并发写入,文件随机修改:一个文件只能有一个写者,仅支持append。

十.DataNode宕机后,集群能否立即将宕机的DataNode下线?DataNode下线后,集群将进行什么工作?

  • 不能立即下线,需要等待10分钟30秒。
  • DataNode下线后,集群将复制下线的datanode管理的块。

十一.将一个集群重新格式化NameNode后,使用start-dfs.sh启动集群,DataNode能启动起来么?为什么?

  • 不能,namenode重新格式化后,clusterid改变了,而datanode还保持着原来的clusterid。

十二.DataNode在什么情况下不会备份?

  • DataNode在强制关闭或者非正常断电不会备份。

十三.3个DataNode中有一个DataNode出现错误会怎样?

  • 这个DataNode的数据会在其他的DataNode上重新做备份。

十四.一个DataNode宕机,怎么一个流程恢复

  • 将DataNode数据删除,重新当成新节点加入即可。

猜你喜欢

转载自blog.csdn.net/sun_0128/article/details/108559114