欢迎关注Hadoop、Spark、Flink、Hive、Hbase、Flume等大数据资料分享微信公共账号:iteblog_hadoop
  1. 文章总数:1033
  2. 浏览总数:13,371,823
  3. 评论:4083
  4. 分类目录:108 个
  5. 注册用户数:6786
  6. 最后更新:2019年6月12日
过往记忆博客公众号iteblog_hadoop
欢迎关注微信公众号:
iteblog_hadoop
大数据技术博客公众号bigdata_ai
Hadoop技术博文:
bigdata_ai

Hive:解决Hive创建文件数过多的问题

  今天将临时表里面的数据按照天分区插入到线上的表中去,出现了Hive创建的文件数大于100000个的情况,我的SQL如下:

/////////////////////////////////////////////////////////////////////
 User: 过往记忆
 Date: 2015-11-18
 Time: 23:24
 bolg: https://www.iteblog.com
 本文地址:https://www.iteblog.com/archives/1533
 过往记忆博客,专注于hadoop、hive、spark、shark、flume的技术博客,大量的干货
 过往记忆博客微信公共帐号:iteblog_hadoop
/////////////////////////////////////////////////////////////////////

hive> insert overwrite table test partition(dt)
    > select * from iteblog_tmp;

iteblog_tmp表里面一共有570多G的数据,一共可以分成76个分区,SQL运行的时候创建了2163个Mapper,0个Reducers。程序运行到一般左右的时候出现了以下的异常:

[Fatal Error] total number of created files now is 100385, which exceeds 100000. Killing the job.

  并最终导致了SQL的运行失败。这个错误的原因是因为Hive对创建文件的总数有限制(hive.exec.max.created.files),默认是100000个,而这个SQL在运行的时候每个Map都会创建76个文件,对应了每个分区,所以这个SQL总共会创建2163 * 76 = 164388个文件,运行中肯定会出现上述的异常。为了能够成功地运行上述的SQL,最简单的方法就是加大hive.exec.max.created.files参数的设置。但是这有个问题,这会导致在iteblog中产生大量的小文件,因为iteblog_tmp表的数据就570多G,那么平均每个文件的大小=570多G / 164388 = 3.550624133148405MB,可想而知,十万多个这么小的小文件对Hadoop来说是多么不好。那么有没有好的办法呢?有!

  我们可以将dt相同的数据放到同一个Reduce处理,这样最多也就产生76个文件,将dt相同的数据放到同一个Reduce可以使用DISTRIBUTE BY dt实现,所以修改之后的SQL如下:

hive> insert overwrite table test partition(dt)
    > select * from iteblog_tmp
    > DISTRIBUTE BY dt;

  修改完之后的SQL运行良好,并没有出现上面的异常信息,但是这里也有个问题,因为这76个分区的数据分布很不均匀,有些Reduce的数据有30多G,而有些Reduce只有几K,直接导致了这个SQL运行的速度很慢!

  能不能将570G的数据均匀的分配给Reduce呢?可以!我们可以使用DISTRIBUTE BY rand()将数据随机分配给Reduce,这样可以使得每个Reduce处理的数据大体一致。我设定每个Reduce处理5G的数据,对于570G的数据总共会起110左右的Reduces,修改的SQL如下:

/////////////////////////////////////////////////////////////////////
 User: 过往记忆
 Date: 2015-11-18
 Time: 23:24
 bolg: https://www.iteblog.com
 本文地址:https://www.iteblog.com/archives/1533
 过往记忆博客,专注于hadoop、hive、spark、shark、flume的技术博客,大量的干货
 过往记忆博客微信公共帐号:iteblog_hadoop
/////////////////////////////////////////////////////////////////////

hive> set hive.exec.reducers.bytes.per.reducer=5120000000;
hive> insert overwrite table test partition(dt)
    > select * from iteblog_tmp
    > DISTRIBUTE BY rand();

这个SQL运行的时间很不错,而且生产的文件数量为Reduce的个数*分区的个数,不到1W个文件。

本博客文章除特别声明,全部都是原创!
转载本文请加上:转载自过往记忆(https://www.iteblog.com/)
本文链接: 【Hive:解决Hive创建文件数过多的问题】(https://www.iteblog.com/archives/1533.html)
喜欢 (49)
分享 (0)
发表我的评论
取消评论

表情
本博客评论系统带有自动识别垃圾评论功能,请写一些有意义的评论,谢谢!
(2)个小伙伴在吐槽
  1. 你好,版主,对于这种 insert select情况,插入数据的表会创建多个文件,这个文件大小可以自己定义码?可以的话是哪个参数,谢谢

    灰太狼2017-03-29 22:07 回复
    • 上面不是有参数吗

      w3970907702017-03-31 09:13 回复