HDFS小文件危害以及如何解决

HDFS小文件危害以及如何解决

小文件的定义

文件大小小于或者等于30M的文件

hdfs小文件带来危害

(1)HDFS不适合大量小文件的存储,因namenode将文件系统的元数据存放在内存中,因此存储的文件数目受限于 namenode的内存大小。HDFS中每个文件、目录、数据块占用150Bytes。如果存放的文件数目过多的话会占用很大的内存甚至撑爆内存
(2)HDFS适用于高吞吐量,而不适合低时间延迟的访问。如果同时存入大量的小文件会花费很长的时间。hive或者spark计算的时候会影响他们的速度,因为spark计算时会将数据从硬盘读到内存,零碎的文件将产生较多的寻道过程。
(3) 流式读取的方式,不适合多用户写入,以及任意位置写入。如果访问小文件,则必须从一个datanode跳转到另外一个datanode,这样大大降低了读取性能。

解决方案

(1)生产上首先需要设置小文件的阈值,到达这个值对小文件进行合并。对于这个合并,一种是在HDFS存储之前就进行合并,还有一种就是计算完之后根据业务周期来进行合并。后一种需要在计算时格外对小文件进行调整。
(1.1)har回档:Apache官方提供了官方工具去合并hdfs上的小文件(Hadoop Archive或者HAR)这是一个高效地将小文件放入HDFS块中的文件存档工具,它能够将多个小文件打包成一个HAR文件。具体说来,HDFS存档文件对内还是一个一个独立文件,对NameNode而言却是一个整体,减少了NameNode的内存。这样在减少namenode内存使用的同时,仍然允许对文件进行透明的访问。
(1.2)CombineTextInputFormat:CombineTextInputFormat用于将多个小文件在切片过程中生成的一个单独切片或者少量的切片
(2)开启uber模式,实现JVM重用。默认情况下,每个Task任务都需要启动一个JVM来运行,如果Task任务计算的数据量很小,可以让同一个job的多个Task运行在一个JVM中,不必为每个Task都开启一个JVM。如果没有小文件,不要开启 JVM 重用,因为会一直占用使用到的 task 卡槽,直到任务完成才释放。
JVM 实例在同一个 job 中重新使用 N 次,N 的值可以在 Hadoop 的mapred-site.xml 文件中进行配置。通常在 10-20 之间

>
 >mapreduce.job.jvm.numtasks>
 >10>
 >How many tasks to run per jvm,if set to -1 ,there is no limit>
>

也许还有同学会提到增大NameNode的内存、甚至将元数据直接从硬盘中读取,但这些方法都是治标不治本,不适用。

知识拓展

数据在DataNode中如何存储?

HDFS默认的数据存储块是64MB,现在新版本的hadoop环境(2.7.3版本后),默认的数据存储块是128MB。

一个文件如果小于128MB,则按照真实的文件大小独占一个数据存储块,存放到DataNode节点中。同时 DataNode一般默认存三份副本,以保障数据安全。同时该文件所存放的位置也写入到NameNode的内存中,如果有Secondary NameNode高可用节点,也可同时复制一份过去。NameNode的内存数据将会存放到硬盘中,如果HDFS发生重启,将产生较长时间的元数据从硬盘读到内存的过程。

如果一个文件大于128MB,则HDFS自动将其拆分为128MB大小,存放到HDFS中,并在NameNode内存中留下其数据存放的路径。不同的数据块将存放到可能不同的DataNode中。

HDFS为什么将Block块设置为128M

(1)如果低于128M,甚至过小。一方面会造成NameNode内存占用率高的问题,另一方面会造成数据的寻址时间较多。

(2)如果于高于128M,甚至更大。会造成无法利用多DataNode的优势,数据只能从从一个DN中读取,无法实现多DN同时读取的速率优势。

参考:
https://blog.csdn.net/qq_41919792/article/details/112779626
https://blog.csdn.net/qq_43597431/article/details/119964997

你可能感兴趣的:(大数据,#,Hadoop,hdfs,hadoop,大数据)