Hive小文件问题

1、小文件产生的原因

  • 数据源本身有很多小文件
  • reduce数量多导致生成的小文件增多
  • 使用动态分区导致小文件增多

2、小文件危害

  • HDFS内存资源消耗过大,并限制了数据存储规模:在HDFS中,具体的文件保存在datanode节点中,在namenode节点中会有一个内存对象与之对应,用于存储文件的元信息,如位置、大小、分块等,每个对象大约占用150个字节。因此,过多的碎片文件会使得namenode消耗大量的内存资源用于管理文件元数据,性能也会因此受到影响,这样namenode的内存容量严重制约了集群的发展。
  • 数据的访问更加耗时:处理小文件并非Hadoop的设计目标,HDFS的设计目标是流式访问大数据集。在HDFS中,每次读写文件都需要先从namenode获取文件元数据信息,然后与datanode建立连接。而访问大量的小文件会经常会需要大量的定位寻址操作,不断地在datanode间跳跃去检索小文件。这种访问方式严重影响性能。
  • 数据运算的时间成本以及计算资源成本更高:在计算层面,小文件越多,意味着MapReduce执行任务时需要创建的map也会越多,这样,任务的启动与释放将耗费大量时间。同时,每一个map都会开启一个JVM虚拟机用于执行任务,带来的调度以及计算成本也更高了。

3、解决思路

1)从源端限制小文件生成

2)对已产生的小文件进行处理

  • Hive参数调节
    Hive小文件问题_第1张图片
  • 动态分区插入式,保证有静态分区,不要误判产生大量分区
  • 按照分区合并导入:Hive SQL提供了distribute by语法用于控制map端如何拆分数据给reduce,根据distribute by后面的列对应的reduce个数进行分发,默认采用hash算法,在使用上如配合分区表的分区列 insert select到结构与源表一样的目标表,可以在目标表对数据按分区进行压缩;如果原表有大量小文件,在导入目标表的时候也会产生大量小文件。如果有分区如dt、hour,可以使用 distribute by dt,hour,
    保证每小时数据在一个reduce里面
insert into test select * from table distribute by dt(rand()*5)
  • 定期合并数据:类似于增量导入数据,会存在小文件,需要进行一天或者一周的定时文件合并
  • 覆盖原表数据:
  • 针对ORC存储的表:alter table test [partition(…)] concatenate

你可能感兴趣的:(hive,大数据,hive,hadoop,大数据)