vlambda博客
学习文章列表

hdfs读写过程是怎样的?

1.文件读取过程

    1.客户端通过调用FileSyste 对象的open()方法来打开希望读取的文件,对于Hdfs来说,这个对象是DistributedFileSystem的一个实例,

    3.DistributedFileSystem 类返回一个FSDataInputStream对象给客户端以便读取数据。FSDataInputStream类转而封装DFSInputStream对象,该对象管理着datanode和namenode的IO,客户端对输入流调用read()方法,

    5.到块的末端时,DFSInputStream关闭与该datanode的连接,然后寻找下一个块的最佳datanode。

    6.一旦客户端完成读取,就对FSDataInputStream调用close()方法 


2.文件写入过程

    1.客户端通过对DistributedFileSystem 对象调用create()新建文件;

    2.DistributedFileSystem 对namenode创建一个PRC调用,在文件系统的命名空间中新建一个文件,此时改文件中还没有对应的数据块,namenode执行各种不同的检测,以确保这个文件不存在以及客户端有新建该文件的权限,检测通过则namenode会创建新文件记录一条记录,否则报IO异常;

    3.DistributedFileSystem向客户端返回一个FSDataOutputStream对象,FSDataInputStream封装一个DFSoutPutstream对象,该对象负责处理datanode和namenode之间的通信;

    4.在客户端写入数据时,DFSoutPutstream将它分成一个个的数据包,并写入内部队列,称‘数据队列’,DataStreamer处理数据队列,挑选适合存储数据副本的一组datanode,并据此要求namenode分配新的数据块。

这一组datanode构成一个管线,假设复本数为3,所以管线中有3个节点。DataStreamer将数据包流式传输到管线中第一个datanode,该datanode存储数据包并将它发送到管线中的第2个datanode。同样第2个datanode存储该数据包并发送给管线中的第3个;

    5.DFSoutPutstream 也维护着一个内部数据包队列来等待datanode的收到确认回执,成’确认队列’,收到管道中所有datanode确认信息后,该数据包才会从确认队列删除。 

    注:如果任何datanode在数据写入期间发生故障,则执行以下操作,首先关闭管线,确认把队列中的所有数据包都添加回数据队列的最前端,以确保故障节点下游的datanode不会漏掉任何一个数据包,为存储在另一正常datannode的当前数据块指定一个新的标识,并将该标识传送给namenode,以便故障datanode在恢复后可以删除存储部分数据块,从管线中删除故障datanode,基于两个正常datanode构建一条新管线。余下的数据块写入管线中正常的datanode,namenode注意到块副本量不足时,会在另一个节点上创建一个新的副本,后续的数据块继续正常接收处理,在一个块被写入期间可能会有多个datanode同时发生故障,但非常少见。只要写入最小副本数(默认是1),写操作就会成功,并且这个块可以再集群中异步复制,直到达到其目标副本数。

    6.客户端完成数据的写入后,对数据流调用close()方法

    7.写入datanode管线完成后,会联系namenode告知其文件写入完成之前等待确认,namenode已经知道文件由哪些块组成,所以它在返回成功前只需要等待数据块进行最小量的复制。 


3.复本是如何放的呢?

    namenode如何选择在哪个datanode存储复本,需要对可靠性、写入带宽和读取带宽进行权衡。例如,把所有复本都存储在一个节点损失的写入带宽最小,但这并不提供真实的冗余,如果节点发生故障,那么该块中的数据会丢失。同时,同一机架上服务器间的读取带宽是很高的。另一个极端,把复本放在不同的数据中心可以最大限度地提高冗余,但带宽损耗非常大,即使在同一数据中心,也有多种可能的数据布局策略。

    Hadoop 默认布局策略,

1.在运行客户端的节点上放第一个复本,如果客户端运行在集群之外,就随机选一个节点,不过系统会避免挑选那些存储太慢或太忙的节点,

2.第二个复本放在与第一个不同且随机另外选择的机架中节点上,

3.第三个复本与第2个复本放在同一个机架上,且随机选择另一个节点,

4.其他复本放在集群中随机选的节点上,不过系统会尽量避免在同一个的机架上放太多复本。一旦选定复本的放置位置,就根据网络拓扑创建一个管线,如果复本数为3,如图

优点:不仅提供很好的稳定性,并实现很好的负载均衡,包含写入带宽、读取性能和集群中块的均匀分布。