【大数据入门笔记系列】第三节 Hdfs写数据处理流程

【大数据入门笔记系列】第三节 Hdfs写数据处理流程

Hdfs简介

一般而言,Hdfs是由一个NameNode节点和若干个DataNode节点组成(非高可用,高可用还有一个SecondNameNode)。

  • NameNode:管理分布式文件系统的元数据,这些元数据是一些诸如描述文件的存储路径以及block具体在哪些DataNode上的具体位置等;
  • DataNode:DataNode节点用来保存文件数据块(block),它只负责接受存储、查询发送文件,不负责文件的切块;
  • 文件切割:文件的切割默认是以128M为标准(该数值可通过参数设定),小于该标准的文件不切割,超过该标准的文件会被切成若干个block块;一个文件切割出来的多个block在存储时,每个block的存储地址都由NameNode决定,当一个block存储完毕后,下一个block要重新向NameNode申请存储地址;这些被切割出来的block块会根据replication(复制因子)复制出多个副本,且副本存放在不同的DataNode上;
  • 汇报机制:DataNode会定时向NameNode汇报自身的block信息,NameNode会负责保存这些DataNode汇报上来的元数据,并保存文件的副本数量,一旦副本数量不满足复制因子规定的数目,则NameNode会指定一台DataNode(没有改副本的节点)从有该副本的DataNode上拷贝(一个副本ID在一台DataNode上有且仅有一份);
  • 容错机制:如果存在DataNode宕机,那么当集群中的DataNode出发定时向NameNode汇报时,NameNode就会得知哪些机器宕机了,统计完副本分布情况之后,NameNode就知道哪些副本少了,于是NameNode就负责寻找一个没有这个副本节点从有这个副本的DataNode上拷贝一份(一个副本ID在一台DataNode上有且仅有一份);
  • 客户端请求方式:Hdfs的内部工作机制对客户端保持透明,客户端请求访问Hdfs都是通过NameNode申请实现的。

写数据处理流程

假设有一台NameNode和4台DataNode(非HA),我们的文件上传客户端可以在任何地方,前提是客户端能够与NameNode、DataNode连接。
在这里插入图片描述
一个大文件现在客户端进行分割,然后向NameNode请求上传block到指定文件夹,比如如下上传命令:

hadoop dfs -put 9F83F0668.mp4 /test/9F83F0668/

NameNode首先会看上传目标文件夹,然后它会去查询内部元数据该路径存在不存在,分一下几种情况:

  • 路径“/test/9F83F0668/”不存在
    创建路径“/test/9F83F0668/”,符合文件上传条件。
  • 路径“/test/9F83F0668/”存在,该路径下存在文件“9F83F0668.mp4”
    返回文件已存在,不符合文件上传条件(此举是为了方式覆盖文件)。
  • 路径“/test/9F83F0668/”存在,该路径下不存在文件“9F83F0668.mp4”
    符合文件上传条件。

如果符合文件上传条件,就意味着我们的客户端可以向Hdfs上传文件,这个时候客户端还不知往哪儿传送数据,客户端通过rpc请求上传一个block,NameNode分配三台DataNode(假设我们的复制因子为3)。
在这里插入图片描述
这里交代一下NameNode分配存储节点DataNode的机制:

  • 第一台DataNode
    第一台DataNode的分配规则是考虑节点的存储空间以及与NameNode的距离,优先选择存储空间大且离NameNode的节点(因为第一台DataNode要实时向NameNode汇报,所以第一台择优分配);
  • 第二台DataNode
    第二台DataNode的分配规则是优先选择存储空间大且离NameNode的节点(处于安全考虑);
  • 第三台DataNode
    第三台DataNode的选择标准与第一台DataNode一致,优先选择存储空间大且离NameNode的节点;
    当客户端拿到了存储对象(即NameNode传递过来的信息),解析一下就明白了上传地址在哪儿,于是它便尝试与DataNode1建立流(通道),执行以下流程:
    1. 客户端首先向DataNode1发送请求建立block传输通道channel,同时告诉DataNode1客户端还要发送block至DataNode2、DataNode3处;
    2. DataNode1接到DataNode1的请求,知道还要向DataNode2、DataNode3传输数据,DataNode1向DataNode2发送请求建立channel,并告诉DataNode2还要向DataNode3传输block;
    3. DataNode2接到DataNode1的请求后,知道还要向DataNode3传输block,于是向DataNode3发送建立channel请求;
      4)DataNode3接到DataNode2的请求之后,知道自己是最后一个,没有其他要存储的节点了,于是返回应答给DataNode2,表示DataNode2与DataNode3之间的通道建立;
      5)同理DataNode2返回应答给DataNode1,表示DataNode1与DataNode2之间的通道建立;
      6)DataNode1再返回应答给客户端,至此整个文件传输通道建立完成,开始写数据。
      在这里插入图片描述

客户端与DataNode1之间建立的连接管道名为pipeline,值得注意的是这个大小为“128M”的block块在往DataNode1上写的时候不是一次性传输的,而是又分成一个个packet数据包进行传输(默认64K),DataNode1每收到一个64k大小的packet包都要先验证其正确性,如果没有传输错误那就写到自己的文件目录下,在校验packet正确性和本地的过程之间还存在一个缓冲区,这个缓冲区向DataNode1自身的文件系统写校验正确的packet,同时向DataNode2发送该packet,DataNode2上面发生的事情和DataNode1上一样(也校验、进入缓冲区),DataNode3同理(校验、进入缓冲区,不发送了直接写入)。
宏观上看,客户端向DataNode1、DataNode2、DataNode3传输block的过程几乎是同步的,只会有一两个packet的差别。

  • 那么传输过程如果校验失败了怎么办?
    每一个节点收到前驱传来的packet包之后,都会向它的前驱应答,前驱再向前驱应答,以此类推,如果packet在DataNode1就失败了,那么客户端会重新向NameNode申请该block的存储地址(NameNode的小本本也会记下这几台性能不是很可靠的机器,下次不优先分配),如果packet在DataNode2或者DataNode3上失败,但是DataNode1传输成功这也不打紧,因为有NameNode的存在,NameNode会异步地从DataNode1上复制出错的packet到相应失败的节点上(NameNode依旧会在小本本上记下这些不可靠的机器,下次不优先分配)。
    等到一整个block传输成功以后,下一个block的传输过程一样是先请求NameNode分配存储地址(重新分配的地址可能是一样的,但是上一个block传输建立的pipeline不能够复用,必须重新请求建立),如此往复完成整个大文件“9F83F0668.mp4”的存储,整个过程会被NameNode记录下来,记录的数据就称为元数据
    在这里插入图片描述
    注意:DataNode在校验packet的传输正确性的时候并不是以64k为单位校验一次,而是以一个chunk(512byte)为单位校验一次。

后记

对Hdfs写数据处理流程的理解交代完了,后面再交代一下Hdfs读数据的处理流程,个人理解恐有失偏颇,欢迎流言指正。

跳转

【大数据入门笔记系列】写在前面
【大数据入门笔记系列】第一节 大数据常用组件
【大数据入门笔记系列】第二节 Zookeeper简介
【大数据入门笔记系列】第三节 Hdfs写数据处理流程

发布了40 篇原创文章 · 获赞 56 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/Jack_Roy/article/details/104305439