【面试重点】HDFS的读写数据流程以及优缺点

一、前言概述
HDFS是Hadoop Distributed File System的缩写,它是一个文件系统,用于存储文件,通过目录树来定位文件;其次,它是分布式的,由很多服务器联合起来实现其功能,集群中的服务器有各自的角色。

二、HDFS的使用场景:
适合一次写入,多次读出的场景,且不支持文件的修改。适合用来做数据分析,并不适合用来做网盘应用。

三、HDFS的优缺点:
优点:
1、 高容错性

  • 数据自动保存多个副本,通过增加副本的形式来提高容错性;
  • 在某一个副本丢失以后,它可以自动回复;

2、 适合处理大数据

  • 数据规模:能够处理数据规模达到GB、TB、甚至PB级别的数据;
  • 文件规模:能够处理百万规模以上的文件数量,数量相当之大;

3、 可构建在廉价机器上,通过多副本机制提高可靠性;
4、 流式数据访问,而不是随机读写
5、 简单一致性模型,假定文件是一次写入、多次读取

缺点:
1、 不适合低延时数据访问,比如毫秒级的存储数据是做不到的;
2、 无法高效对大量小文件进行存储
3、 不支持并发写入和文件随机修改

  • 一个文件只能有一个写入者,不允许多个线程同时写;
  • 仅支持数据append(追加),不支持对文件随机修改。

四、HDFS中Block、Packet、Chunk三个关键词的概念:

Block
是最大的一个单位。HDFS中的文件在物理上是分块(Block)存储的,块的大小可以通过配置参数(dfs.blocksize)来规定,默认大小在Hadoop2.X 版本中是128M,老版本是64M。一般不建议去改,因为块设置太小:寻址时间占比过高。块设置太大:Map任务数太少,作业执行速度变慢。

Packet
是第二大的单位,它是client端向DataNode,或DataNode的PipLine之间传数据的基本单位,默认64KB。

Chunk
是最小的单位,它是client向DataNode,或DataNode的PipLine之间进行数据校验的基本单位,默认512Byte,因为用作校验,故每个chunk需要带有4Byte的校验位。所以实际每个chunk写入packet的大小为516Byte。由此可见真实数据与校验值数据的比值约为128 : 1。(即64*1024 / 512)

在client端向DataNode传数据的时候,HDFSOutputStream会有一个chunk buff,在写满一个chunk后,会计算校验和并写入当前的chunk。之后再把带有校验和的chunk写入packet,当一个packet写满后,packet会进入dataQueue队列,其他的DataNode就是从这个dataQueue中获取client端上传的数据并存储的。同时一个DataNode成功存储一个packet后之后会返回一个ack packet,放入ack Queue中。

五、HDFS的写数据流程
在这里插入图片描述
具体写流程:

  1. 客户端通过Distributed FileSystem模块向NameNode请求上传文件;
  2. NameNode检查是否已存在文件和检查权限。若通过检查,直接先将操作写入EditLog,并返回输出流对象;
  3. 客户端按照配置参数(dfs.blocksize,比如128MB)的大小将文件切分为块(Block),并向NameNode请求上传第一个
    Block;
  4. NameNode返回分配的可写的DataNode列表,比如dn1、dn2、dn3;
  5. 客户端通过FSDataOutputStream模块向dn1请求上传数据,dn1收到请求会继续调用dn2,然后dn2调用dn3,将这个通信管道pipeline建 立完成;
  6. dn1、dn2、dn3逐级应答客户端;
  7. 客户端开始往dn1上传第一个Block(先从磁盘读取数据放到一个本地内存缓存),以Packet为单位,dn1收到一个Packet就会传给dn2,dn2传给dn3;dn1每传一个packet会放入一个应答队列等待应答;(注:并不是每写完一个packet后就返回确认信息,因为packet中的每个chunk都携带校验信息,没必要每写一个就汇报一下,这样效率太慢。正确的做法是写完一个block块后对校验信息进行汇总分析,进而得出是否有块写错的情况发生)
  8. 当一个Block传输完成之后,客户端再次请求NameNode上传第二个Block的服务器。(重复执行3-7步);
  9. 写完数据,关闭输出流。

补充注意:

  • 实际客户端只上传给一个datanode,其余两个是由namenode来完成的,它让dn2和dn3自己去复制,然后复制完成以后逐级返回结果给namenode。如果dn2和dn3复制失败,再由namenode分配新的datanode地址。对于客户端来说默认上传一个datanode就可以了,其余的由datanode自己复制。
  • datanode切片是由客户端自己完成的,另外datanode第二三个副本的上传和第一个上传是异步的。

六、HDFS的读数据流程
在这里插入图片描述
具体读流程:

  1. 客户端通过Distributed
    FileSystem向NameNode请求下载文件,NameNode通过查询元数据获得这个文件的数据块位置列表,返回输入流对象;
  2. 挑选一台DataNode(就近原则,然后随机)服务器,请求读取数据;
  3. DataNode开始传输数据给客户端(从磁盘里面读取数据输入流,以Packet为单位来做校验);
  4. 客户端以Packet为单位接收,先在本地缓存,然后写入目标文件;
  5. 写完数据,关闭输入流。

七、读写过程,数据完整性如何保持?

通过校验和。因为每个chunk中都有一个校验位,一个个chunk构成packet,一个个packet最终形成block,故可在block上求校验和。

HDFS 的client端即实现了对 HDFS 文件内容的校验和 (checksum) 检查。当客户端创建一个新的HDFS文件时候,分块后会计算这个文件每个数据块的校验和,此校验和会以一个隐藏文件形式保存在同一个 HDFS 命名空间下。当client端从HDFS中读取文件内容后,它会检查分块时候计算出的校验和(隐藏文件里)和读取到的文件块中校验和是否匹配,如果不匹配,客户端可以选择从其他 Datanode 获取该数据块的副本。

HDFS中文件块目录结构具体格式如下:

${dfs.datanode.data.dir}/
├── current
│ ├── BP-526805057-127.0.0.1-1411980876842
│ │ └── current
│ │ ├── VERSION
│ │ ├── finalized
│ │ │ ├── blk_1073741825
│ │ │ ├── blk_1073741825_1001.meta
│ │ │ ├── blk_1073741826
│ │ │ └── blk_1073741826_1002.meta
│ │ └── rbw
│ └── VERSION
└── in_use.lock

in_use.lock表示DataNode正在对文件夹进行操作
rbw是“replica being written”的意思,该目录用于存储用户当前正在写入的数据。
Block元数据文件(*.meta)由一个包含版本、类型信息的头文件和一系列校验值组成。校验和也正是存在其中。

猜你喜欢

转载自blog.csdn.net/weixin_43230682/article/details/107334723
今日推荐