HDFS应用场景分析

原文来自云台博客:http://yuntai.1kapp.com/?p=954        

虽然说之前也对HDFS的应用场景有个大致的认识,但是总感觉不是十分彻底,因此前几天花了点时间进行了整理,现在把它贴出来。

     

1.概况

1) HDFS不适合大量小文件的存储,因NameNode将文件系统的元数据存放在内存中,因此存储的文件数目受限于NameNode的内存大小。HDFS中每个文件、目录、数据块占用150Bytes。如果存放1million的文件至少消耗300MB内存,如果要存放1billion的文件数目的话会超出硬件能力,但是目前HDFS版本引入了Federation这种多NameNode的机制,可以支持NameNode的横向扩展;同时也可以适用HDFS的小文件合并为大文件的机制;

2) HDFS适用于高吞吐量,而不适合低时间延迟的访问(因为写文件可能存在初始化socket,初始化RPC,及其多次通信等)。如果同时存入1million的files,那么HDFS 将花费几个小时的时间;

3)流式读取的方式,不适合多用户写入一个文件(一个文件同时只能被一个客户端写),以及任意位置写入(不支持随机写),支持文件尾部apend操作,或者文件的覆盖操作;

4)没有HDFS HA机制之前,HDFS不能提供7*24小时的服务,由于有了HA机制出现,定时软硬件升级维护不再需要停机;

5)HDFS更加适合写入一次,读取多次的应用场景,通过线上HDFS集群的监控,hadoop目前业务的读写比为10:1,在设计上也是考虑了这一点,读速度比较快。

2.读写过程分析

在上面一部分,已经提到HDFS不适合低延迟的访问,原因是写入一个文件,经过的通信次数比较多;如果对于一个大文件,它写数据流的时间远远大于RPC通信,socket建立连接,及其磁盘寻址等时间,因此大文件比较适合;如果对于小文件则相反,其他方面所消耗时间比写数据流的时间消耗得多。

2.1.写文件


 由上图可知,写入文件大致经过如下流程:

1、首先创建RPC连接(客户端可创建一次,不再创建);

2、   创建文件元数据(必须);

3、   为文件分配块(文件有几个数据块,就请求分配几次);

4、   客户端与DataNode,DataNode之间建立socket(4,5,6),并且几者之间socket均建立成功才算成功,才能进行数据块的写入操作;

5、   每个DataNode接收完某个块会向NameNode进行报告;

6、   如果一个文件的每个块的三个副本中,只要有一个副本报告给NameNode,客户端发送消息给NameNode确认文件完成;

综合以上,对于一个比较小的文件,通信时间可能远大于数据上传时间,因此对于小文件给出以下建议:

上传小文件的时候,HDFS设置的数据块不宜太小,以免引起更多的通信交互,及其引起更多的磁盘寻址,建议用64MB即可。

备注:对于一个文件的数据块的3个副本,每个都上传成功,才算成功,否则该数据块上传失败,HDFS客户端重新选择DataNode进行上传。

2.2.读文件


上图仅表示出了在读取文件的时候的主要流程图,步骤如下:

1、首先创建RPC连接(客户端可创建一次,不再创建);

2、获取文件数据块位置(文件有几个数据块,就获取几次位置);

3、客户端与DataNode建立socket链接,该数据节点会选择离客户端最近的DataNode节点;

4、下载文件的数据块;

综合以上,对于一个相对比较小的文件,HDFS设置的数据块不宜太小,以免引起更多的通信交互,及其引起更多的磁盘寻址,建议用64MB即可;部署多客户端,而不是单客户端,这样可以平衡DataNode集群的IO;

3.HDFS自带的小文件存储解决方案

对于小文件问题,hadoop自身提供了三种解决方案:Hadoop Archive、 Sequence File 和 CombineFileInputFormat,具体细节可参考:http://www.open-open.com/lib/view/open1330605869374.html

4.集群管理

下线DataNode节点机器,rebalance等都比较成熟,方便。

5.多种API支持

   除了支持命令行,原始客户端调用方式之外,还支持WebHDFS REST APIHttpFS Gateway,挂载等方式。


你可能感兴趣的:(HDFS)