hdfs小文件问题

一.dfs小文件带来的危害
1.在HDFS中数据和元数据分别由DataNode和NameNode负责,这些元数据每个对象一般占用大约150个字节。大量的小文件相对于大文件会占用大量的NameNode内存。对NameNode内存管理产生巨大挑战,可能会导致JVM频繁发生GC。
2.NameNode重启时,它需要将文件系统元数据从本地磁盘加载到内存中。如果NameNode的元数据很大,重启速度会非常慢。
3.NameNode会不断跟踪并检查集群中每个block块的存储位置。这是通过DataNode的定时心跳上报其数据块来实现的。数据节点需要上报的block越多,则也会消耗越多的网络带宽/时延。
4.对计算引擎如Spark、MapReduce性能造成负面影响。以MapReduce(以下简称MR)为例,大量小文件意味着大量的磁盘IO,磁盘IO通常是MR性能的最大瓶颈之一,在HDFS中对于相同数量的数据,一次大的顺序读取往往优于几次随机读取的性能。如果可以将数据存储在较少,而更大的一些block中,可以降低磁盘IO的性能影响。除了磁盘IO,还有内部任务的划分、资源分配等。

二.小文件的产生:
1.流式任务(如spark streaming/flink等实时计算框架)
在做数据处理时,无论是纯实时还是基于batch的准实时,在小的时间窗口内都可能产生大量的小文件。此外对于Spark任务如果过度并行化,每个分区一个文件,产生的文件也可能会增多
2.Hive分区表的分区设置不合理
Hive分区表的每个分区数据量很小(比如小于HDFS block size)的Hive表。那么Hive Metastore Server调用开销会随着表拥有的分区数量而增加,影响性能。此时,要衡量数据量重新进行表结构设计(如减少分区粒度)。
3.数据源有大量小文件,未做数据清洗直接迁移到hdfs上。
4.对于计算引擎处理任务,以MR为例。
大量的map和reduce task存在。在HDFS上生成的文件基本上与map数量 (对于Map-Only作业)或reduce数量(对于MR作业)成正比。此外,MR任 务如果未设置合理的reduce数或者未做限制,每个reduce都会生成一个独立的文件。对于数据倾斜,导致大部分的数据都shuffle到一个或几个reduce,然后其他的reduce都会处理较小的数据量并输出小文件。
对于Spark任务,过度并行化也是导致小文件过多的原因之一。
在Spark作业中,根据写任务中提到的分区数量,每个分区会写一个新文件。这类似于MapReduce框架中的每个reduce任务都会创建一个新文件。Spark分区越多,写入的文件就越多。控制分区的数量来减少小文件的生成。

三.筛选小文件
一个示例命令
hadoop fs -count /dtInsight/hive/warehouse/aecc_mall.db/* |awk ‘$2>800 && $4!~/select/ {print $2,$3/1024/1024,$4}’

四:解决
1…小文件合并
当产生小文件是不可避免时,文件合并是常见的解决方案。使用这种方法,你可以定期运行一个MR任务,读取某一个文件夹中的所有小文件,并将它们重写为较少数量的大文件。比如一个文件夹中有1000个文件,你可以在一个MR任务中指定reduce的数量为5,这样1000个输入文件会被合并为5个文件。随后进行一些简单的HDFS文件/文件夹操作(将新文件覆盖回原目录),则可以将NameNode的内存使用减少到200分之1,并且可以提高以后MR或其他计算引擎对同一数据处理的性能。

2.从hive/spark任务解决问题
小文件的出现大都是任务的sql写的不够好或者参数设置不合理需要进行优化
a.hive的优化:
输入合并和输出合并:
1.配置map输入合并
– 每个Map最大输入大小,决定合并后的文件数
set mapred.max.split.size=256000000;
– 一个节点上split的至少的大小 ,决定了多个data node上的文件是 否需要合并
set mapred.min.split.size.per.node=100000000;
– 一个交换机下split的至少的大小,决定了多个交换机上的文件是否需要合并
set mapred.min.split.size.per.rack=100000000;
– 执行Map前进行小文件合并
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
2.配置hive结果端合并
通过设置hive的配置项在执行结束后对结果文件进行合并:
b.sparksql优化
减少分区数
参数设置:spark_sql_shuffle_partitions设置executor的partitions个数,注意这个参数只对SparkSQL有用

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值