hive优化

  1. 确定合适的map个数
    map个数 = max[ ${maperd.min.split.size}, min( ${dfs.block.size} , ${mapred.max.split.size} )]

maperd.min.split.size:splt最小分片,默认1B
mapred.max.split.size:splt最大分片,默认256M
dfs.block.size:hdfs的block块大小

所以,上述公式取得默认1个map task处理256M数据。增大split分片,可以减少map任务个数。增大split分片,可以减小map任务个数。一般来讲,map task在10~20s完成时,可以考虑减少map任务个数,增大单个map处理的数据量。如果map完成时间接近1分钟或者几分钟,可以考虑减小分片大小,增大map任务个数

  1. 选择合适的reduce个数(默认3个)
    reduce个数 = min[ ${hive.exec.Reducers.max} , ( ${inpt.size}/${hive.exec.Reducers.per.Reducer} ) ]

inpt.size:给reduce的数据总量
hive.exec.Reducers.per.Reducer:每个reducer处理的数据量,默认1G
hive.exec.Reducers.max:hive的最大reduce数量

  1. 使用RCF文件格式
    RCF是行列结合的文件存储格式,首先按照行分块,保证同一行的数据在一个block上,其次,每块数据按列存储,有利于数据压缩和快速存取

    # 建表时指定RFC存储
    hive> create table test3(str STRING)  STORED AS RCFILE;  
    # 设置压缩格式
    hive> set hive.exec.compress.output=true;
    hive> set mapred.output.compress=true;
    hive> set mapred.output.compression.codec=com.hadoop.compression.lzo.LzoCodec;
    hive> set io.compression.codecs=com.hadoop.compression.lzo.LzoCodec;
    # 插入数据
    hive> INSERT OVERWRITE TABLE test3 SELECT * FROM test1;  
    
  2. 优先用本地模式运行mapreduce
    对于map输入文件个数小于4个,或总共文件大小小于128M的数据,让hive优先用本地模式启动job

    hive.exec.mode.local.auto=true
    hive.exec.mode.local.auto.tasks.max=4 #默认情况下为4
    hive.exec.mode.local.auto.inputbytes.max=128m #默认情况下为128m
    
  3. join优化
    分布式join采取2种方法:

(1)replication join:复制join,把其中一个表复制到每个节点,使得每个节点用这个小表的全部数据和大表的分片数据join
(2)repartition join:分片join,把2个表的join key按照hash值发到不同节点,让每个节点处理1个hash键值的join

以上2种方法,分别对应map段join和reduce端join。hive默认采用reduce段join(2个表join key的hash值分布join)。当1个表很小的时候,可以考虑map join,因为小表复制的代价,小于大表shuffle到不同节点的代价。多大的表才是小表呢,hive.smalltable.filesize默认为25m的算小表。2种方法开启map端的join:

(1)sql中指定那个表需要被replication:/*+MapJOIN (小表表名)*/
(2)hive.auto.convert.join = true
hive.smalltable.filesize = 25mb

  1. 数据倾斜
    hive的数据倾斜分为group by倾斜和join倾斜
    (1)group by倾斜2中解决方案

    # 1.在map端combiner
    set hive.Map.aggr=true #默认已经为true
    
    # 2. reduce操作时,不要把相同的key发往同一个reduce,要随机发放,在reduce聚合后,开启新一轮mrjob
    set hive.groupby. skewindata=true
    

    (2)join引起的数据倾斜
    当某一个join key很多时,就会发生倾斜,hive的解决方案叫做skew join,即:对于这种大数据量的特殊值,不要进行reduce,先保存成文件,然后开启新一轮的mrjob机选

    set Hive.optimize.skewjoin = true;  
    #大于该数值个数的join key称特殊值,在下一轮job处理
    set hive.skewjoin.key=100000 
    
  2. job间并行
    hive sql会产生多个job,有些情况下job间可以并行,例如子查询或union操作,或join操作

    hive.exec.parallel = true
    hive.exec.parallel. thread.number  #设置并行的job个数
    
  3. 使用严格模式
    严格模式禁止3中查询:
    (1)对于分区表,不加分区字段不能查询
    (2)对于order by:不加limit不能查询、
    (3)不允许笛卡尔集的查询,单独join不允许,要left join

  4. hive内置的虚拟列

    hive.exec.rowoffset = true  开启虚拟列查询  
    

    虚拟列有input_file_name , block_offset_inside_file,分别说明该条记录来自于哪个hdfs文件和在文件中的偏移量。这2个字段便于在hdfs中查找错误

  5. 开启推测执行
    当某一个map,reduce任务耗时超过平均任务耗时, 会启动一个新job执行这个mapreduce, 哪个先执行完, 哪个先返回结果,另一个kill掉

    hive.mapred.reduce.tasks.speculative.execution = true
    
原文地址:https://www.cnblogs.com/72808ljup/p/5353274.html