目录
1-背景
公司数据治理过程中,发现apache hadoop大数据环境下hdfs中有数量惊人的小文件。
如图所示为hdfs的web管理页面:

如上图所示可以看到hive中的这个表的20200630这个分区中有551个数据文件。
但是我们可以看到hdfs中的默认设置每个块大小为256M,而该表分区存储数据的每个块大小才为十几M,远远小于默认块大小,这就是小文件!
1.1-造成大量小文件的原因:
主要原因如下:
- 1.实时(流式)数据,flume,spark streaming,flink等组件生成,流式增量文件到hive(如设定几分钟生成一次文件)等。
- 2.在纯map任务下,大量的map任务;或者大量的reduce任务都会生成很多小文件块到hdfs。
1.2-小文件的危害:
首先要知道的是hdfs中的两大模块,namenode(存储文件元数据,管理读写流程)和datanode(存储数据)。
(1)对namenode的影响:
大量的元数据占用大量namenode的内存
以公司hdfs采用的是三副本策略,设置文件块大小默认为128M,
举个例子:

- 如图所示,一个文件192M,默认blocksize = 128M,服本数为3个,存储为两个block。
- namenode中的namespace中主要占存储对象是文件的目录个数,文件名长度,文件block数。在namenode中一个存储对象大概占用150字节的空间,存储文件占用namenode的内存空间计算公式如下:
- Memory = 150bytes * (一个文件inode + (文件的块数 * 副本数))
即当前该文件占用namenode的内存大小为:150 * (1 + (2 * 3)) = 1050bytes。
举第二个例子:

- 如图所示,同样一个192M的文件,默认blocksize = 128M,服本数为3个,存储为192个block。
- 所以当前文件存储模式下占用namenode内存为:150 * (192 + (192 * 3)) = 11520bytes。
- 总结:从以上两个例子可以看出来,同样一个文件大小不同形态的存储占用namenode的内存之比相差了109倍,所以大量的小文件会 占用大量的namenode内存,影响集群性能。
(2)对datanode的影响:
对于高负载的大数据集群,花费在寻址上的时间要比数据读取写入的时间更长(hdfs的读写流程)。
(3)对计算性能的影响:
大量的小文件(block),意味着更多的map任务调度,更多启动任务的开销,更多的任务管理开销。
2-解决方案实操
hive的官方文档解决方法截图如下:

2.1-解决方案1
`set hive.input.format = org.apache.hadoop.hive.ql.io.CombineHiveInputFormat; --官方默认值,也是当前平台默认值`
`set hive.merge.smallfiles.avgsize=16000000; (当输出文件的平均大小小于该值时,启动一个独立的map-reduce任务进行文件merge)`
`set hive.merge.size.per.task=256000000; --官方默认值,也是当前平台默认值(合并文件的大小)`
`set hive.merge.mapfiles =true ; --官方默认值,也是当前平台默认值`
`set hive.merge.mapredfiles = true ; --官方默认值,也是当前平台默认值`
`drop table if exists FDM_SOR.T_FSA_BHVR_NEW_EXPO_D_tmp_tmp;`
`cre

最低0.47元/天 解锁文章
5473

被折叠的 条评论
为什么被折叠?



