zoukankan      html  css  js  c++  java
  • 解决HDFS小文件带来的计算问题

    hive优化

    ### 一.小文件简述 #### 1.1. HDFS上什么是小文件? HDFS存储文件时的最小单元叫做Block,Hadoop1.x时期Block大小为64MB,Hadoop2.x时期Block大小为128MB。(在hadoop部署下可以通过dfs.block.size进行设置) 小文件就是指,在HDFS上落地的文件大小远远小于一个Block块大小的文件。 #### 1.2. 小文件形成的原因 #### 1.3. 小文件的危害 * **内存占用** 小文件存储在HDFS上,对应的每个文件都会在namenode中存有相应的元数据信息(在namenode的内存中均被表示为一个对象(object)).如果每一个文件的元数据信息占用内存100byte,那么有10万个文件, 就占用了namenode10G的内存空间 * **数据查询** HDFS对小文件的读取, 涉及到磁盘读取, 同时涉及到从跨datanode的文件查询(Reading through small files normally causes lots of seeks and lots of hopping from datanode to datanode to retrieve each small file) * **任务启动** 在hadoop上进行数据计算时,每一个小文件都要对应一个task,每一个task也要对应的申请slot。task启动阶段会耗费大量的时间在任务资源申请和释放上。

    二. 小文件的处理方式

    2.1. HDFS上现存的小文件

    问题 : HDFS集群上目前存在的大量小文件
    解决 : 不定期调用HDFS和sync()方法 和 append()方法, 整理小文件生成大文件

    2.2. MapReduce上的小文件

    上面已经描述过,一个文件对应启动一个mapTask,则小文件太多,会带来相应的很多问题。处理方式如下:

    2.2.1. Hadoop Archive(略)
    2.2.2. Sequence File(略)
    2.2.3. CombineFileInputFormat方法

    思路主要是, 将几个小文件合并在一起, "打包"提供给Task进行计算, 避免一个文件启动一个Task。
    具体说来就是: Hadoop内置了CombineFileInputFormat类专门用于处理小文件, 将HDFS上多个小文件合并成一个InputSplit, 然后启用一个map来处理这个InputSplit。
    这个环节主要包含如下的几个参数的使用:

    mapreduce.input.fileinputformat.split.minsize.per.node
    mapreduce.input.fileinputformat.split.minsize.per.rack
    mapreduce.input.fileinputfornat.split.maxsize
    

    mapreduce.input.fileinputfornat.split.maxsize参数说明

    • 如果未进行设置, 默认就会将同一个机架上的所有小文件组成一个InputSplit, 交由一个MapTask处理。
    • 如果进行了设置, 同一个节点(node)上的文件会组成一个InputSplit

    2.3. Hive上的小文件

    2.3.1. 输入文件多的解决方案

    设置mapper输入文件合并的参数如下:

    ## Mapper执行前进行小文件合并
    hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
    ## 每一个mapper最大的输入大小
    mapred.max.split.size = 256000000
    ## 一个节点上split的至少的大小(这个值决定了多个DataNode上的文件是否需要合并)
    mapred.min.split.size.per.node = 100000000
    ## 一个机架下split的至少的大小(这个值决定了该机架下的文件是否需要合并)
    mapred.min.split.size.per.rack = 100000000
    
    2.3.2. 输出文件过多(包括中间过程和输出结果)
    ## Map-only的任务结束时合并小文件(map-only应该就是只有map阶段没有reduce阶段吧)
    hive.merge.mapfiles = true
    ## 在Map-reduce的任务结束时合并小文件
    hive.merge.mapredfiles = true (默认是false)
    ## 控制合并文件的大小
    hive.merge.size.per.task = 25610001000
    ## 当输出文件的平均大小小于该值时,启动一个独立的map-reduce任务进行文件merge
    hive.merge.smallfiles.avgsize = 16000000
    
    2.3.3. 生成的结果文件多的另一种折中处理

    对reducer进行调整 a.调整reducer个数 b.调整reducer大小

    ## 设定reducer个数
    set mapred.reduce.tasks = 50;
    ## 设定reduce的大小
    set hive.exec.reducers.bytes.per.reducer = 512000000
    

    ps:Hive对创建的文件总数是有限制的, 通过hive.exec.max.created.files参数进行控制(默认是10000).如果hive表有100个分区, 1000个mapper, 则总共创建的文件数就会是100*1000 = 100000, 任务执行阶段就会触发exceeds 100000.Killing the job的错误, 进行 hive.exec.max.created.files参数的放大可解决这个错误, 但同时会导致小文件。

  • 相关阅读:
    HDU 5247
    HDU 4965
    CodeForces 445B
    HDU 5835
    CodeForces 731C
    HDU 5783
    CodeForces 660D
    POJ 1631
    HDU 6112
    HDU 5860
  • 原文地址:https://www.cnblogs.com/Sinkinghost/p/11665418.html
Copyright © 2011-2022 走看看