hdfs为啥不擅长存储大量的小文件

2019/2/25 星期一

hdfs为啥不擅长存储大量的小文件

hdfs的优点和缺点
优点:
1、可构建在廉价机器上
    通过多副本提高可靠性,提供了容错和恢复机制
    服务器节点的宕机是常态 必须理性对象
2、高容错性
数据自动保存多个副本,副本丢失后,自动恢复
    HDFS的核心设计思想: 分散均匀存储 + 备份冗余存储
3、适合批处理
移动计算而非数据,数据位置暴露给计算框架
    海量数据的计算 任务 最终是一定要被切分成很多的小任务进行
4、适合大数据处理
    GB、TB、甚至 PB 级数据,百万规模以上的文件数量,10K+节点规模
5、流式文件访问
     一次性写入,多次读取,保证数据一致性
hdfs缺点
1、低延迟数据访问
    比如毫秒级 低延迟与高吞吐率
2、小文件存取
    占用 NameNode 大量内存 150b* 1000W = 15E,1.5G 寻道时间超过读取时间
3、并发写入、文件随机修改
    一个文件只能有一个写者 仅支持 append

FastDFS与hadoop的区别
主要是定位和应用场合不一样。
hadoop的文件系统HDFS主要解决并行计算中分布式存储数据的问题。其单个数据文件通常很大,采用了分块(切分)存储的方式;
FastDFS主要用于大中网站,为文件上传和下载提供在线服务。所以在负载均衡、动态扩容等方面都支持得比较好,FastDFS不会对文件进行分快(切分)存储。

hdfs为什么不适合大量小文件的存储
namenode在内存中存储metadata。每个小文件都占150bytes.所以很多小文件的话, 内存就吃紧了。
不是不适合存小文件,而是不适合纯海量小文件。。。。 文件数不能太多。。。
管理每个文件需要占用master机器一定内存,管理文件过多,内存占用过多,会使集群运行变慢。
文件数过多 ,占用的内存也相应的多了,这样就会影响系统的处理速度,如果是少量的大容量文件,占用内存相应较低,处理速度就会更快
HDFS无法高效存储大量小文件,如何处理好小文件? https://blog.csdn.net/zyd94857/article/details/79946773
hadoop SequenceFile详解:https://blog.csdn.net/bitcarmanlee/article/details/78111289

(1)HDFS不适合大量小文件的存储,因namenode将文件系统的元数据存放在内存中,因此存储的文件数目受限于 namenode的内存大小。HDFS中每个文件、目录、数据块占用150Bytes。如果存放的文件数目过多的话会占用很大的内存
(2)HDFS适用于高吞吐量,而不适合低时间延迟的访问。如果同时存入大量的小文件会花费很长的时间
(3) 流式读取的方式,不适合多用户写入,以及任意位置写入。如果访问小文件,则必须从一个datanode跳转到另外一个datanode,这样大大降低了读取性能。

主要是定位和应用场合不一样。
hadoop的文件系统HDFS主要解决并行计算中分布式存储数据的问题。其单个数据文件通常很大,采用了分块(切分)存储的方式;
FastDFS主要用于大中网站,为文件上传和下载提供在线服务。所以在负载均衡、动态扩容等方面都支持得比较好,FastDFS不会对文件进行分快(切分)存储。

参考链接为:https://www.cnblogs.com/qingyunzong/p/8535995.html
这是和HDFS系统底层设计实现有关系的,HDFS本身的设计就是用来解决海量大文件数据的存储.,他天生喜欢大数据的处理,大文件存储在HDFS中,会被切分成很多的小数据块,任何一个文件不管有多小,都是一个独立的数据块,而这些数据块的信息则是保存在元数据中的,在之前的博客HDFS基础里面介绍过在HDFS集群的namenode中会存储元数据的信息,这里再说一下,元数据的信息主要包括以下3部分:
  1)抽象目录树
  2)文件和数据块的映射关系,一个数据块的元数据大小大约是150byte
  3)数据块的多个副本存储地

而元数据的存储在磁盘(1和2)和内存中(1、2和3),而服务器中的内存是有上限的,举个例子:

有100个1M的文件存储进入HDFS系统,那么数据块的个数就是100个,元数据的大小就是100*150byte,消耗了15000byte的内存,但是只存储了100M的数据。

有1个100M的文件存储进入HDFS系统,那么数据块的个数就是1个,元数据的大小就是150byte,消耗量150byte的内存,存储量100M的数据。


cdh官方的解释:为什么hdfs不适合存储大量的小文件 //很重要
文件和块

在HDFS中,数据和元数据是分离的。数据文件被拆分为块文件,这些块文件在群集中的DataNode上存储和复制。文件系统命名空间树和关联的元数据存储在NameNode上。
命名空间对象是指向DataNode上的块文件的文件inode和块。这些命名空间对象在NameNode的内存中存储为文件系统映像(fsimage),并且也在本地持久存在。元数据的更新将写入编辑日志。当NameNode启动时,或者采用检查点时,将应用编辑,清除日志,并创建新的fsimage。
重要说明:NameNode将整个命名空间映像保留在内存中。辅助NameNode在其自己的JVM上,在创建映像检查点时也是如此。

平均而言,每个文件占用1.5块存储空间。也就是说,平均文件被分成两个块文件 – 一个消耗整个分配的块大小,另一个消耗一半。在NameNode上,这个相同的平均文件需要三个命名空间对象 – 一个文件inode和两个块。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
磁盘空间与命名空间

CDH默认块大小(dfs.blocksize)设置为128 MB。 NameNode上的每个名称空间对象消耗大约150个字节。

在DataNodes上,数据文件是通过消耗的磁盘空间(实际数据长度)来衡量的,而不一定是整个块大小。例如,192 MB的文件占用192 MB的磁盘空间,而不是块大小的整数倍。使用128 MB的默认块大小,192 MB的文件被分成两个块文件,一个128 MB文件和一个64 MB文件。在NameNode上,命名空间对象由文件和块的数量来度量。相同的192 MB文件由三个命名空间对象(1个文件inode + 2个块)表示,并消耗大约450个字节的内存。

分割成较少块的大文件通常比生成许多块的小文件消耗更少的内存。一个128 MB的数据文件由NameNode上的两个名称空间对象(1个文件inode + 1个块)表示,并消耗大约300个字节的内存。相比之下,每个1 MB的128个文件由256个命名空间对象(128个文件inode + 128个块)表示,并消耗大约38,400个字节。然后,最佳分割大小是块大小的一些整数倍,用于存储器管理以及数据局部性优化。

默认情况下,Cloudera Manager为每百万个块(但不小于1 GB)分配1 GB的最大堆空间。实际需要多少内存取决于您的工作负载,尤其是每个命名空间中生成的文件,目录和块的数量。如果所有文件都以块大小分割,则可以为每百万个文件分配1 GB。但考虑到每个文件的历史平均值为1.5个块(2个块对象),对于每百万个块,更保守的估计是1 GB的内存。
重要说明:Cloudera建议每百万个块使用1 GB的NameNode堆空间来计算命名空间对象,必要的簿记数据结构和远程过程调用(RPC)工作负载。实际上,您的堆需求可能会低于此保守估计值。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
复制
默认块复制因子(dfs.replication)为3。复制影响磁盘空间但不影响内存消耗。复制会更改每个块所需的存储量,但不会更改块的数量。如果DataNode上的一个块文件(由NameNode上的一个块表示)被复制三次,则块文件的数量将增加三倍,但不会代表它们的块数。

关闭复制时,一个192 MB的文件占用192 MB的磁盘空间和大约450字节的内存。
//(计算方式为:128+64 也就是1个文件inode+2个块 大约消耗 450字节的内存)
如果你有一百万个这样的文件,或192 TB的数据,你需要192 TB的磁盘空间,而不考虑RPC工作负载,450 MB内存:(100万inode + 200万个块) 150个字节。启用默认复制后,您需要576 TB的磁盘空间:(192 TB 3)但内存使用率保持不变,450 MB。当您考虑簿记和RPC,并遵循每百万个块1 GB堆内存的建议时,对此方案更安全的估计是2 GB内存(有或没有复制)。

提示:
很多资料上说HDFS文件系统不适用于存储小文件。在我的经验中,我认为hdfs文件系统不是不能存小文件,而是不擅长存储大量的小文件。

参考链接:https://www.cloudera.com/documentation/enterprise/5-13-x/topics/admin_nn_memory_config.html

原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/tech/opensource/197831.html

(0)
上一篇 2021年11月17日 07:20
下一篇 2021年11月17日 07:20

相关推荐

发表回复

登录后才能评论