• hive 中map和reduce的数量


    hive中如何控制mapper的数量

    参考文档:https://www.cnblogs.com/1130136248wlxk/articles/5352154.html

    1. 决定map的数据的决定因素有: input的文件总个数,input的文件大小,集群设置的文件块大小(目前为128M, 可在hive中通过set dfs.block.size;命令查看到,该参数不能自定义修改);

    2.是不是map数越多越好,如何减少?

      a. 不是越多越好,多了会造成资源的浪费;因为map任务的启动和初始化的时间,远远大于逻辑处理的时间;并且,map的数据是有限制的。

      b. 可以通过set设置,让map在执行前合并小文件,从而达到减少map数:

        比如:  set mapred.max.split.size=100000000; -- 决定每个map处理的最大的文件大小,单位为B
                            set mapred.min.split.size.per.node=100000000; -- 节点中可以处理的最小的文件大小
                            set mapred.min.split.size.per.rack=100000000; -- 机架中可以处理的最小的文件大小
                            set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;---实现map中的数据合并需要设置下面的参数,集群默认就是这个格式

    一般如下设置:

      set mapred.max.split.size = 256000000;
      set mapred.min.split.size.per.node = 128000000;
      set mapred.min.split.size.per.rack = 128000000;
      set hive.input.format = org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;

    3. 是不是每个map处理的接近128M的文件块,就OK了呢? 如果不OK,如何增加map的数量?

      a. 并不一定。当文件接近128M,但是里的内容却非常多的时候并且map处理的逻辑比较复杂。那么用一个map处理,则时间会比较长

      b. 把原来的单个文件拆分成多个的文件, 然后使用新的文件来执行sql。

          set mapred.reduce.tasks=10;
                       create table a_1 as 
                       select * from a 
                       distribute by rand(123);

    4. 控制map整体原则:

      1:大数据量要利用合适的map数;单个map要处理合适的数据量 。

      2:map占用资源要合并小文件;map不足要把大文件拆成小文件。

    5.reduce简单总结:

      a. 有多少个reduce,就会有多少个输出文件,如果生成了很多个小文件,那么如果这些小文件作为下一个任务的输入,则也会出现小文件过多的问题;

      b.什么情况下只有一个reduce:

        1. 没有group by就进行count(1)。

        2.使用了order by。

        3.存在笛卡儿积。因为这些都是全局操作,生成一个文件,就只有1个reduce。

      c. set mapred.reduce.tasks/set hive.exec.reducers.bytes.per.reducer=1073741824 -- 每个reduce处理的数据量,默认1GB

    6. map数量一些深入的知识:

      a. default_num = total_size/block_size,默认情况下map的个数

      b.可以通过set mapred.map.tasks = goal_num 来设置期望的map数量,但是这个数量仅在大于default_num 的时候才会生效。

      c. 可以通过set mapred.min.split.size来设置每个task的文件大小,但是这个数量在大于block_size的时候才会生效。

        split_size = max(mapred.min.split.size,block_size);

        split_num = total_szie/split_size

     

    控制hive任务的reduce数: 

    1.    Hive自己如何确定reduce数: 
    reduce个数的设定极大影响任务执行效率,不指定reduce个数的情况下,Hive会猜测确定一个reduce个数,基于以下两个设定:
    hive.exec.reducers.bytes.per.reducer(每个reduce任务处理的数据量,默认为1000^3=1G) 
    hive.exec.reducers.max(每个任务最大的reduce数,默认为999)
    计算reducer数的公式很简单N=min(参数2,总输入数据量/参数1)
    即,如果reduce的输入(map的输出)总大小不超过1G,那么只会有一个reduce任务;
    如:select pt,count(1) from popt_tbaccountcopy_mes where pt = '2012-07-04' group by pt; 
                /group/p_sdo_data/p_sdo_data_etl/pt/popt_tbaccountcopy_mes/pt=2012-07-04 总大小为9G多,因此这句有10个reduce

    2.    调整reduce个数方法一: 
    调整hive.exec.reducers.bytes.per.reducer参数的值;
    set hive.exec.reducers.bytes.per.reducer=500000000; (500M)
    select pt,count(1) from popt_tbaccountcopy_mes where pt = '2012-07-04' group by pt; 这次有20个reduce
             
    3.    调整reduce个数方法二; 
    set mapred.reduce.tasks = 15;
    select pt,count(1) from popt_tbaccountcopy_mes where pt = '2012-07-04' group by pt;这次有15个reduce

    4.    reduce个数并不是越多越好; 
    同map一样,启动和初始化reduce也会消耗时间和资源;
    另外,有多少个reduce,就会有多少个输出文件,如果生成了很多个小文件,那么如果这些小文件作为下一个任务的输入,则也会出现小文件过多的问题;

    5.    什么情况下只有一个reduce; 
    很多时候你会发现任务中不管数据量多大,不管你有没有设置调整reduce个数的参数,任务中一直都只有一个reduce任务;
    其实只有一个reduce任务的情况,除了数据量小于hive.exec.reducers.bytes.per.reducer参数值的情况外,还有以下原因:
    a)    没有group by的汇总,比如把select pt,count(1) from popt_tbaccountcopy_mes where pt = '2012-07-04' group by pt; 写成 select count(1) from popt_tbaccountcopy_mes where pt = '2012-07-04';
    这点非常常见,希望大家尽量改写。
    b)    用了Order by
    c)    有笛卡尔积
    通常这些情况下,除了找办法来变通和避免,我暂时没有什么好的办法,因为这些操作都是全局的,所以hadoop不得不用一个reduce去完成;
    同样的,在设置reduce个数的时候也需要考虑这两个原则:使大数据量利用合适的reduce数;使单个reduce任务处理合适的数据量;
     

    转自:

    https://www.cnblogs.com/chengdu-jackwu/p/10170895.html

    https://www.cnblogs.com/1130136248wlxk/articles/5352154.html

  • 相关阅读:
    mysql "The user specified as a definer ('root'@'%') does not exist" 问题
    mysql添加Federated引擎问题
    D7经典脚本[multi/handler]
    redhat7.4安装vertica-9.1.0教程
    批量在当前目录下所有的文件中添加指定字段
    mysql 水平分表技术
    linux普通用户提权
    两步完成利用procdump64+mimikatz获取win用户密码
    hibernate中对象的三种状态分析
    Hibernate 入门案例
  • 原文地址:https://www.cnblogs.com/Allen-rg/p/12841153.html
Copyright © 2020-2023  润新知