Hive的常用优化设置

一、hive的常用参数

-- 设置名称
set mapred.job.name = "test";
-- 每个Map最大输入大小
set mapred.max.split.size = 300000000;
-- 每个Map最小输入大小
set mapred.min.split.size = 100000000;
-- 执行Map前进行小文件合并
set hive.input.format = org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
--是否自动转换为mapjoin
set hive.auto.convert.join = true;
set hive.mapjoin.smalltable.filesize = 25000000;
set hive.auto.convert.join.noconditionaltask = true;
set hive.auto.convert.join.noconditionaltask.size = 10000000;
-- 在Map-only的任务结束时合并小文件
set hive.merge.mapfiles = true;
-- 在Map-Reduce的任务结束时合并小文件
set hive.merge.mapredfiles = true;
-- join 倾斜
set hive.optimize.skewjoin=true;
set hive.skewjoin.key=100000; 
-- goupby 数据倾斜
set hive.map.aggr=true;
set hive.groupby.mapaggr.checkinterval = 100000;
set hive.groupby.skewindata=true;
-- 合并文件的大小
set hive.merge.size.per.task = 300000000;
set mapred.reduce.tasks = 30;
-- 动态分区
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict; 
-- 并行开启
set hive.exec.parallel=true;
set hive.exec.parallel.thread.number=8;

二、join参数解析

hive的join方式默认common join,但是common join 在大表join小表的时候速度很慢,而且容易发生数据倾斜,而,map join 就会优化了此方面的问题,大大加快了join速度和缓解了数据倾斜!

(一). map join 到底优化在哪里?
  1. 因为每个mapjoin都要执行一次map,需要读写一次数据,所以多个mapjoin就要做多次的数据读写,合并mapjoin后只用读写一次,自然能大大加快速度。但是执行map是内存大小是有限制的,在一次map里对多个小表做mapjoin就必须把多个小表都加入内存,为了防止内存溢出,所以加了hive.auto.convert.join.noconditionaltask.size参数来做限制。不过,这个值只是限制输入的表文件的大小,并不代表实际mapjoin时hashtable的大小。
  2. Hive的MapJoin,在Join 操作在 Map 阶段完成,如果需要的数据在 Map 的过程中可以访问到则不再需要Reduce。
    小表关联一个超大表时,容易发生数据倾斜,可以用MapJoin把小表全部加载到内存在map端进行join,避免reducer处理。
(二).join 参数说明
  1. 如果是小表,自动选择Mapjoin:
set hive.auto.convert.join = true; # 默认为false

该参数为true时,Hive自动对左边的表统计量,如果是小表就加入内存,即对 小表使用Map join

  1. 小表的最大文件大小,默认为25000000,即25M
set hive.mapjoin.smalltable.filesize;

hive.mapjoin.smalltable.filesize=25000000
默认值是25mb

  1. map join做group by 操作时,可以使用多大的内存来存储数据,如果数据太大,则不会保存在内存里
set hive.mapjoin.followby.gby.localtask.max.memory.usage;

默认值:0.55

  1. 本地任务可以使用内存的百分比
set hive.mapjoin.localtask.max.memory.usage;

默认值: 0.90

  1. 是否将多个mapjoin合并为一个
set hive.auto.convert.join.noconditionaltask = true;
  1. 多个mapjoin转换为1个时,所有小表的文件大小总和的最大值
set hive.auto.convert.join.noconditionaltask.size = 10000000;
(三).mapjoin的注意事项
  1. 用作join的关联字段的字段类型最好要一致
    原因:40万行的小表处理了好几个小时,正常情况下应该几秒钟就完成了。但是执行mapjoin 的local task时一直卡住,查了好久原因,结果原来是做join的关联字段的类型不一致,一边是int, 一边是string,hive解释计划里显示它们都会被转成double再来join。我把字段类型改为一致的,瞬间就快了。照理说就算转成double也不该这么慢,不知道是不是hive的bug。
  2. Mapjoin 不能使用与 outer join
(四).数据倾斜
  1. 根本原因
    发生数据倾斜主要是因为在数据进行shuffle的阶段的时候,数据分配不均匀,导致map处理的数据量差异过大,从而在大量ruduce完成任务后,需要等待少量(1个)reduce完成才能继续执行,任务进度卡在了99%.
  2. 导致的操作
    在这里插入图片描述
  3. 表现
    任务进度长时间维持在99%(或100%),查看任务监控页面,发现只有少量(1个或几个)reduce子任务未完成。因为其处理的数据量和其他reduce差异过大。单一reduce的记录数与平均记录数差异过大,通常可能达到3倍甚至更多。 最长时长远大于平均时长。
  4. 典型的业务场景
    (1) 空值产生的数据倾斜
    场景:经常有user_id缺失的情况,如果进行join操作,会导致数据倾斜。
    解决方法1: user_id为空的不参与关联
    (2) 不同数据类型关联产生数据倾斜
    场景:用户表中user_id字段为int,log表中user_id字段既有string类型也有int类型。当按照user_id进行两个表的Join操作时,默认的Hash操作会按int型的id来进行分配,这样会导致所有string类型id的记录都分配到一个Reducer中。
    解决方法:把数字类型转换成字符串类型
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值