1.客户端通过调用FileSyste 对象的open()方法来打开希望读取的文件,对于Hdfs来说,这个对象是DistributedFileSystem的一个实例,
2.通过使用远程过程调用(RPC)来调用namenode,以确定文件起始块的位置,对于每个块,namenode返回存有该块副本的datanode的地址,并且datanode根据他们与客户端的距离来排序,如果该客户端本身就是一个datanode,那么该客户端将会从保存有相应数据块副本的本地datanode读取数据.
3.DistributedFileSystem 类返回一个FSDataInputStream对象给客户端以便读取数据。FSDataInputStream类转而封装DFSInputStream对象,该对象管理着datanode和namenode的IO,客户端对输入流调用read()方法,
4.存储着文件起始几个块的datanode地址的DFSInputStream随即连接距离最近的的文件中第一个块的datanode,通过对数据流反复调用read()方法,可以将数据从datanode传输到客户端。
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,如图:
优点:不仅提供很好的稳定性,并实现很好的负载均衡,包含写入带宽、读取性能和集群中块的均匀分布。
网友评论