• 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快。
     
     
     
     
     
      
      
     
  • 相关阅读:
    [一、基础控件]18给图像视图添加遮罩以突出主题
    [一、基础控件]12Button按钮控件的使用
    延期通知 RocketMQ Summit 议题 全揭秘
    阿里云 VPC 内网性能测试最佳实践
    4/8 Serverless 技术实践营成都站持续报名中
    阿里云云原生应用平台总经理丁宇:“连接、合作、赋能”,携手加速器伙伴助力企业云上创新
    EventBridge 事件总线及 EDA 架构解析
    从建好到用好,阿里云原生微服务生态的演进
    如视技术副总裁杨永林:当传统产业遇到“数字空间”
    阿里云架构师梁旭:MES on 云盒,助力客户快速构建数字工厂
  • 原文地址:https://www.cnblogs.com/dali133/p/9302552.html
Copyright © 2020-2023  润新知