zoukankan      html  css  js  c++  java
  • hive调优

      怎样才能让程序花费的时间最短?Hadoop 是分布式处理系统,可以从两方面进行入手:控制任务的处理数量,使之均衡分布在每个reduce上,不会使哪个任务因为数据量多大而使用过长的时间;增加reduce到一定的数量。

    另外的制约因素是tasktracker的负载,一个tasktracker能同时运行多少个map任务,是由 mapred.taskertracker.map.tasks.maximun 属性控制,默认是2个任务。能同时运行多少个reduce任务数是由mapred.tasktracker.reduce.task.maximun属性所控制,默认也是2.
    在一个taskertracker 上同时运行的任务数取决于一台机器有多少个处理器,由于mapreduce作业通常是I/O-bound(I/O密集型,cpu通常要等硬盘/内存的读写),因此设置任务数大于处理器数有一定的道理。

      1. map的数量

      map的数量跟输入的文件大小和个数有关系,可以通过set dfs.block.size 来查看集群设置的文件块大小:

    hive> set dfs.block.size;
    dfs.block.size=134217728
      如果你输入一个文件file1 大小为450M,hdfs 会把它分成4个块,3个128M的和一个66M的文件块,map的数量就是4。
      如果你输入4个文件f 大小分别为10M,20M,100M,140M,则hdfs就会把其分成5个文件块:10,20,100,128,12。
      map数不是越多越好,如果输入的文件都是小文件,远小于128M,那么每一个文件都会被当作一个map进行处理,map任务启动和初始化时间会大于逻辑处理处理的时间,那么会造成资源的浪费,而且可同时执行的map数是受限制的,只能分批执行。
      map处理文件的大小也不是越接近128M越好,同时要根据这个文件记录的数量进行评估,比如文件只有一列,但有几千万行,用一个map来处理是比较费时的。根据实际情况,控制map数量要遵循两个原则: 使大数据量利用合适的map数,使单个map任务处理合适的数据量。
      如何合并小文件,减少map数量?
      假如有一个SQL任务:
    Select count(1) from popt_tbaccountcopy_mes where pt = ‘2012-07-04’;
     
    该任务的inputdir  /group/p_sdo_data/p_sdo_data_etl/pt/popt_tbaccountcopy_mes/pt=2012-07-04
    一共有194个文件,其中有很多文件远小于128M,总共9个G大小,正常会运行194个map任务
    Map总共消耗的计算资源: SLOTS_MILLIS_MAPS= 623,020
     我通过以下方法在map执行前合并小文件,减小map数:
     set mapred.max.split.size =  100000000; ---每个map最大输入的大小
     set mapred.min.split.size.per.node = 100000000;---一个节点上split至少的大小,决定了跨多个datanode 上的文件是否需要合并
     set mapred.min.split.size.per.rack = 100000000; ---一个交换机下split至少的大小,决定了多个交换机上的文件是否需要合并
     set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;---执行map前进行小文件的合并
     再执行以上的语句,用了74个map任务, map消耗的计算资源:SLOTS_MILLIS_MAPS= 333,500
     对于这个简单的SQL任务,执行时间差不多,但节省了一半的计算资源。
     前面三个参数确定合并文件块的大小,大于文件块的大小128M的,按照128来划分,小于128,大于100的,按照100来划分,把那些小于100(包括小文件和大文件划分剩下的)进行合并,最终得到了74块。
     
    如何增加map数量?
     当input文件都很大,执行逻辑复杂,map执行非常慢,可以考虑增加map数,来使得每个map处理的数量减少,提高任务执行效率。
     有一个任务:
     select id
    , count(distinct ...)
    , sum(case when ...)
    , sum(case when ...)
    ...
    from table1 group by id 
    ;
    如果table1只有一个文件块120M,但有几千万行,如果用一个map去处理这个任务,肯定会比较耗时,在这种情况下,我们可以把一个文件拆成多个文件。
    set mapred.reduce.task = 10;
    create table table2 as
    select * from table1
    distribute by rand();
    这样文件table2 就通过调整reduce数量输出了10个文件块,用来代替table1。再次查询就会用10个map任务去完成。10个map任务并行去处理肯定比一个map快。
     
     
     
     
     
      
      
     
  • 相关阅读:
    MySQL源代码解读(二)
    MySQL源代码解读(一)
    C语言中如何对串口进行操作
    mysql 运行概图
    Yacc 与 Lex
    外键建索引
    提高SQL查询效率
    MySQL源代码分析:(1)Main函数
    Linux "could not open default font 'fixed'."
    转帖 浅析ARM汇编语言子例程设计方法
  • 原文地址:https://www.cnblogs.com/dali133/p/9302552.html
Copyright © 2011-2022 走看看