hadoop中hdfs写入文件的原理剖析

最近忙里偷闲,充充电,虽然在四线城市,但是也要为即将到来的大数据时代最准备不是

下面的大白话简单记录了hdfs在存储文件时都做了哪些个事情,问了将来集群问题的排查提供一些参考依据。

步入正题

创建一个新文件的过程:

第一步:客户端通过DistributedFilesystem对象中的creat()方法来创建文件,此时,RPC会通过一个RPC链接协议来调用namenode,并在命名空间中创建一个新文件,namenode执行各种权限以及文件isexist的检查,dfs返回一个输出流,否则抛出IOEXCEPTION。输出流控制一个DFSoutPutstream,负责处理数据节点和名称节点之间的通信

第二步:客户端开始通过输出流写入数据,DFSoutPutstream将客户端写入的数据分成一个个的数据包包,然后写入到dfs中的一个queue,这些queue中的数据包被dfs中的数据流管理,数据流通过一定的分发机制,将这些数据包形成副本并存放在datanode上,当前例如我们设置的dfs.replication=3,则需要将副本放在三个datanode上,这三个datanode会通过一个管线连接,数据流将包分流给管线中第一个的datanode,这个节点会存储包并且发送给管线中的第二个datanode。同样地,第二个数据节点存储包并且传给管线中第三个datanode

(我就不画流程图了,大家肯定能想明白咯)

第三步:其实第三步应该归属到第二步里面,上一步中所提到的DFSoutPutstream有一个内部等待确认queue,专门用来存放datanode收到的数据包,只有管线中所有的datanode收到副本并且存储成功返回成功标识后等待确认queue才会移除所有的数据包。大家此时可能要问了,如果在复制过程中管线中的某一个datanode发生了故障,hadoop是如何处理的呢?这就是hadoop的容错的强大之处了;

首先、管线会关闭,等待确认队列中的所有数据包都会被添加回到数据队列,由此可以保证数据包的完整性和顺序性

其次、当前块中取一个正常的数据节点,使其联系namenode,将故障节点告知namenode、由此下次故障节点恢复后能将里面残留的不完整的副本文件清空。

第三、故障节点被删除,余下的数据包继续写入到剩下的节点中。namenode注意到当前的副本不足(dfs.replication=3),则会在另外一个datanode上安排创建新的副本。

此时问题就来了(挖掘技术哪家强??),如果在写入期间,datanode大规模的发生故障怎么办眤??

其实这种情况很少发生但林子大了什么鸟都有是不是,我们在部署hadoop有一个配置选项:dfs.replication.min一般默认是1,意思就是说只要有一个节点成功,则hdfs就认为本次写入时成功的,后续的它本身会自己去意识到副本数的不足而去进行复制冗余。

最后、书接上文,客户端写入完成后就会通过DistributedFilesystem调用close()方法,该方法有一个神奇的作用,它会将数据队列剩下的所有包包都放在等待确认queue中,并等待确认,namenode中已经记录下来了所有副本存放的datanode。

看完理论知识和大家用简单地大白话分享下,可有意思了

相关推荐