HDFS中小文件产生的原因以及解决 您所在的位置:网站首页 存储大量小文件怎么办 HDFS中小文件产生的原因以及解决

HDFS中小文件产生的原因以及解决

2024-03-20 19:10| 来源: 网络整理| 查看: 265

小文件产生的原因:

1、实时处理:比如我们使用 Spark Streaming 从外部数据源接收数据,然后经过 ETL 处理之后存储到 HDFS 中,这种情况下在每个 Job 中会产生大量的小文件。 2、hive中对表执行insert into 操作,每次插入数据都在表目录下形成一个小文件,这个小文件就是MR任务reduce端的输出文件。 解决:insert overwrite into table t_new as select * from t_old; 如下面所有的文件都是某个表中的数据,但是却有多个小文件: 在这里插入图片描述 3、hive中执行简单过滤操作,符合过滤条件的数据存在很多block块中,只走map,map输出有很多小文件。 开启map端的聚合。 4、mapreduce正常执行产生小文件。 将mapreduce输出不直接写hdfs,而是写入到hbase中。 设置map端文件合并及reduce端文件合并。 5、输入数据文件为小文件。 小文件合并后再计算。 CombineFileInputFormat: 它是一种新的inputformat,用于将多个文件合并成一个单独的 split切片,另外,它会考虑数据的存储位置。 或者 :CombineHiveInputFormat

设置map输入合并小文件的相关参数:

//每个Map最大输入大小(这个值决定了合并后文件的数量) set mapred.max.split.size=256000000; //一个节点上split的至少的大小(这个值决定了多个DataNode上的文件是否需要合并) 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;

设置map输出和reduce输出进行合并的相关参数:

//设置map端输出进行合并,默认为true set hive.merge.mapfiles = true //设置reduce端输出进行合并,默认为false set hive.merge.mapredfiles = true //设置合并文件的大小 set hive.merge.size.per.task = 256*1000*1000 //当输出文件的平均大小小于该值时,启动一个独立的MapReduce任务进行文件merge。 set hive.merge.smallfiles.avgsize=16000000 小文件的影响:

影响: 1、文件的元数据存储在namenode中,每个文件的元数据都差不多大,小文件过多会极大的占用namonode 的内存,制约集群的扩展。(主要影响) 2、在对小文件进行处理的时候,一个小文件对应一个maptask,一个maptask会开启一个JVM进程,JVM处理一个maptask后会关闭,这样JVM开关的时间会比处理maptask的时间更长,严重浪费了资源,因为进程的开启销毁会严重性能。(可以开启JVM重用) 3.HDFS读写小文件时也会更加耗时,因为每次都需要从NameNode获取元信息,并且对应的DataNode建立连接

解决方案:

1.采用har 归档的方式: Hadoop Archive或者HAR,是一个高效地将小文件放入HDFS块中的文件存档工具,它能够将多个小文件打包成一个HAR文件,这样在减少namenode内存使用的同时,仍然允许对文件进行透明的访问。 2.Sequence file sequence file由一系列的二进制key/value组成,如果为key小文件名,value为文件内容,则可以将大批小文件合并成一个大文件。 3.开启JVM重用:前提条件task必需属于同一个job

表示属于同一job的排队按顺序执行的task可以共享一个JVM,也就是说第二轮的map可以重用前一轮的JVM,而不是第一轮结束后关闭JVM,第二轮再启动新的JVM。

如果设置成-1,那么只要是同一个job的task(无所谓多少个),都可以按顺序在一个JVM上连续执行。

如果task属于不同的job,那么JVM重用机制无效,不同job的task需要不同的JVM来运行。

#默认是1,表示一个JVM上最多可以顺序执行的task数目(属于同一个Job)是1。也就是说一个task启一个JVM。 hive> set mapred.job.reuse.jvm.num.tasks=20; hive> set hive.exec.parallel=true; # 开启同步执行hive的多个阶段,hive在执行过程,将一个查询转化成一个或者多个阶段。

设置reducer 个数 设置 hive.exec.reducers.bytes.per.reducer(默认为1GB)(总输入数据量), 受hive.exec.reducers.max(默认为999)(参数1)影响:

hive>mapred.reduce.tasks = min ( 参数2,总输入数据量/参数1 )


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有