HDFS架构
在阅读了GFS的论文之后,对GFS的框架有了基本的了解,进一步学习自然是对HDFS的解析,不得不说,之前对GFS的一些了解,对理解HDFS还是很有帮助的,毕竟后者是建立在前者之上的分布式文件系统,二者在框架上可以找到很多的共同点,建议初次接触HFDS的技术人员可以先把GFS的那篇论文啃个两三遍,毕竟磨刀不砍柴工。
一下是本人根据网络上的资源进行整合,浅谈HFDS的原理,架构与特性,希望能够帮助读者在短时间掌握HFDS的基础知识,对其框架有一些基本的认识。下面言归正传。
HFDS的读文件流程
流程分析
•使用HDFS提供的客户端开发库Client,向远程的Namenode发起RPC请求;
• Namenode会视情况返回文件的部分或者全部block列表,对于每个block,Namenode都会返回有该block拷贝的DataNode地址;
•客户端开发库Client会选取离客户端最接近的DataNode来读取block;如果客户端本身就是DataNode,那么将从本地直接获取数据.
•读取完当前block的数据后,关闭与当前的DataNode连接,并为读取下一个block寻找最佳的DataNode;
•当读完列表的block后,且文件读取还没有结束,客户端开发库会继续向Namenode获取下一批的block列表。
•读取完一个block都会进行checksum验证,如果读取datanode时出现错误,客户端会通知Namenode,然后再从下一个拥有该block拷贝的datanode继续读。
HFDS的写文件流程
流程分析
•使用HDFS提供的客户端开发库Client,向远程的Namenode发起RPC请求;
•Namenode会检查要创建的文件是否已经存在,创建者是否有权限进行操作,成功则会为文件 创建一个记录,否则会让客户端抛出异常;
•当客户端开始写入文件的时候,会将文件切分成多个packets,并在内部以数据队列"data queue"的形式管理这些packets,并向Namenode申请新的blocks,获取用来存储replicas的合适的datanodes列表,列表的大小根据在Namenode中对replication的设置而定。
•开始以pipeline(管道)的形式将packet写入所有的replicas中。把packet以流的方式写入第一个datanode,该datanode把该packet存储之后,再将其传递给在此pipeline中的下一个datanode,直到最后一个datanode,这种写数据的方式呈流水线的形式。
•最后一个datanode成功存储之后会返回一个ack packet,在pipeline里传递至客户端,在客户端的开发库内部维护着"ack queue",成功收到datanode返回的ack packet后会从"ack queue"移除相应的packet。
•如果传输过程中,有某个datanode出现了故障,那么当前的pipeline会被关闭,出现故障的datanode会从当前的pipeline中移除,剩余的block会继续剩下的datanode中继续以pipeline的形式传输,同时Namenode会分配一个新的datanode,保持replicas设定的数量。
在GFS中,当Master创建了一个chunk,它会根据如下因素来选择chunk副本的初始位置:(1) 新副本所在的Chunk Server的磁盘利用率低于平均水平;(2) 限制每个Chunk Server”最近”创建的数量。(3)每个chunk的所有副本不能在同一个机架。第二点容易忽略但却很重要,因为创建完chunk以后通常需要马上写入数据,如果不限制”最近”创建的数量,当一台空的Chunk Server上线时,由于磁盘利用率低,可能导致大量的chunk瞬间迁移到这台机器从而将它压垮。
HDFS与GFS的策略很相似,在大多数情况下,副本系数是3,HDFS的存放策略是将一个副本存放在本地机架节点上,一个副本存放在同一个机架的另一个节点上,最后一个副本放在不同机 架的节点上。这种策略减少了机架间的数据传输,提高了写操作的效率。机架的错误远远比节点的错误少,所以这种策略不会影响到数据的可靠性和可用性。与此同 时,因为数据块只存放在两个不同的机架上,所以此策略减少了读取数据时需要的网络传输总带宽。在这种策略下,副本并不是均匀的分布在不同的机架上:一个放在本节点上,一个放在同一机架中的另一个节点上,还有一个副本放在另一个不同的机架中的一个节点上,这种策略在不损害数据可靠性和读取性能的情况下改进了写的性能。HDFS采用的副本策略,其目的是为了提高系统的可靠性,可用性。下面就来看看HDFS是如何来具体实现这一策略的。
(Hadoop-0.2.0版本)
HFDS的矛盾分析
因为 Namenode 把文件系统的元数据放置在内存中,所以文件系统所能 容纳的文件数目是由 Namenode 的内存大小来决定。一般来说,每一个文件 、文件夹和 Block 需要占据 150 字节左右的空间,所以,如果你有 100 万个文 件,每一个占据一个 Block ,你就至少需要 300MB 内存。当前来说,数百万 的文件还是可行的,当扩展到数十亿时,对于当前的硬件水平来说就没法实 现了。还有一个问题就是,因为 Map task 的数量是由 splits 来决定的,所以 用 MR 处理大量的小文件时,就会产生过多的 Maptask ,线程管理开销将会 增加作业时间。举个例子,处理 10000M 的文件,若每个 split 为 1M ,那就会 有 10000 个 Maptasks ,会有很大的线程开销;若每个 split 为 100M ,则只有 100 个 Maptasks ,每个 Maptask 将会有更多的事情做,而线程的管理开销也 将减小很多。
已有 0 人发表留言,猛击->> 这里<<-参与讨论
ITeye推荐