hive优化

什么是数据倾斜
大量的相同key被partition分配到一个分区里,造成了’一个人累死,其他人闲死’的情况
#问题描述:
倾斜
小文件 join 大文件
内容倾斜
JOBS多
join
union
sub_query
count(distinct)
Task过多

		#解决方案:整体考虑
			建模
				分层=>轻量聚合
				分区=>避免交换
				压缩=>减少体量
			配置优化
				合理减少job,并行无依赖job,增加jvm重用
				合理控制mapper和reducer的数量
					核数
					内存
					单节点并行jvm数
					数据的规模
					hive内部配置
				开启分区倾斜自动处理机制
				合并小文件
			语句优化
				列裁剪			不用*进行全列扫描,只列出需要的列
								set hive.optimize.cp=true;
				分区裁剪		不指定分区进行全表扫描(在子查询中加where,或者在on后面加and)
								set hive.optimize.pruner=true;
				谓词下推PPD		条件优化放在子查询中执行,减少下游处理的数据量
				sort by 替换 order by		全局排序导致一个Reducer
											distribute by + sort by
				group by 替换 distinct		distinct类似于order by
											group by + set mapred.reduce.tasks=N;			并发

小表+大表 build table 前置 map join
probe table 后置 #小表前置,方便自动mapjoin
set hive.cbo.enable=default true
set hive.map.aggr=true;
set hive.auto.conver.join=true;
set hive.mapjoin.smalltable.filesize=25m; 小于该值自动mapjoin
set hive.mapjoin.cache.numrows=25000; 缓存小表多少行记录到内存
set hive.optimize.bucketmapjoin=true; 分桶表专用

join join是key相同 合并job 并行化
#如果是join过程出现倾斜应设置为true
set hive.optimize.skewjoin=default false;
#join的键对应的记录条数超过这个值则会进行分拆,值根据具体数据量设置
set hive.skewjoin.key=default 100000;
#优化第二job的mapper数量
set hive.skewjoin.mapjoin.map.tasks=10000;

group by #set hive.groupby.skewindata=true; default false
#set hive.groupby.mapaggr.checkinterval-100000;
#map端聚合的最大行数,超出则分解

		#配置
		#hadoop
		{
			#memory
				free/top
							  total        used        free      shared  buff/cache   available
				Mem:        7990136     3987248     1732108       10652     2270780     3697444
				Swap:       8257532        1800     8255732
				
				#虚拟机安装后将所有大数据环境安装,查看虚拟机的资源剩余
				#预留20%内存防止系统运行时卡阻或OOM
				#container(内存从1G自动递增1G) 1~4
				yarn.nodemanager.resource.memory-mb=4						#default 1.5G
				
			#core
				yarn.nodemanager.resource.pcores-vcores-multiple=2			#default undefined
				yarn.nodemanager.resource.cpu-vcores=4						#default -1
				yarn.scheduler.minimum-allocation-vcores=1					#default 1
				#官方和cloudrea建议不超过5个
				yarn.scheduler.maxiimum-allocation-vcores=4					#default undefined
		}
		#hive
		{
			<!--Container内存上限,由nodemanager读取并控制,实际使用超出时会被nodemanager kill Connection reset by peer-->
			<property>
				<name>mapreduce.map.memory.mb</name>
				<value>1024</value>
			</property>
			<!--Container启动jvm时,传递给jvm的参数,实际使用超出时会抛出OutoMemory异常-->
			<property>
				<name>mapreduce.map.java.opts</name>
				<value>-Xmx1024M</value>
			</property>
			<property>
				<name>mapreduce.map.java.opts</name>
				<value>-Xms1024M</value>
			</property>
			<property>
				<name>mapreduce.reduce.memory.mb</name>
				<value>2048</value>
			</property>
			<property>
				<name>mapreduce.reduce.java.opts</name>
				<value>-Xmx2048M</value>
			</property>
			<property>
				<name>mapreduce.map.java.opts</name>
				<value>-Xms256M</value>
			</property>
		}
						
		#控制Mapper数量
		Mapper数量=input size / math.max(minsize,math.min(blocksize,maxsize))
		set mapred.map.tasks=default 2
		
		#Mapper合并:输入合并
		#每个Map最大输入大小,决定合并后的文件数
		set mapred.max.split.size=256000000;
		#一个节点上split的最少大小,决定了多个data node上的文件是否需要合并
		set mapred.min.split.size.per.node=100000000;
		#一个交换机下split最少大小,决定了多个交换机上的文件是否需要合并
		set mapred.min.split.size.per.rack=100000000;
		#执行Map前进行小文件合并
		set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
		
		#Reducer合并:输出合并
		#在map-only job后合并文件,默认true
		set hive.merge.mapfiles
		#在map-reduce job后合并文件,默认false
		set hive.merge.mapredfiles
		#合并后每个文件的大小,默认256000000
		set hive.merge.size.per.task
		#平均文件大小,是决定是否执行合并操作的阈值,默认16000000
		set hive.merge.smallfiles.avgsize
		
		#控制Reducer数量
		set mapred.reduce.tasks=8;
		#不设置reducer数量,hive自动计算
		set hive.exec.reducers.bytes.per.reducer=default 0.25G
		set hive.exec.reducers.max=default 1009
		#如果input bytes size / bytes per reduce > max ? max : insize/bytesPerReducer
		
		#启动本地模式涉及到三个参数:
		#打开hive自动判断是否启动本地模式的开关
		set hive.exec.mode.local.auto=default false;
		#map任务数最大值,不启用本地模式的task最大个数
		set hive.exec.mode.local.auto.input.files.max=default 4
		#map输入文件最大大小,不启动本地模式的最大输入文件大小
		set hive.exec.mode.local.auto.inputbytes.max=default 128M;
		
		#开启任务并执行
		#同一个sql允许并行任务的最大线程数
		
		#开启任务并行执行
		#同一个sql允许并行任务的最大线程数
		set hive.exec.parallel=true;				#default false
		set hive.exec.parallel.thread.number=8;		#default 8
		set hive.exec.reducers.max=8;				#default 1009
		set mapred.reduce.tasks=8;					#default -1
		
		<property>
			<name>hive.exec.parallel</name>
			<value>true</value>
		</property>
		<property>
			<name>hive.exec.parallel.thread.number</name>
			<value>16</value>
		</property>
		
		#虚拟机重用
		set mapred.job.reuse.jvm.num.tasks=10;
		多小文件或多任务,且数据不倾斜,因为小任务端的mapper或reducer会一直占用task插槽

#拉链表:org.apache.hadoop.hive.ql.io.AcidOutputFormat 或者 buckketed
create table groupbyorder(
buytime date,
name string,
pay decimal(10,2)
)
row format delimited
fields terminated by ‘,’
lines terminated by ‘\n’
stored as textfile
location ‘kb12/hive/groupbyskew’;

create table orderhistory(
name string,
total decimal(10,2),
modified date
)
row format delimited
fields terminated by ‘,’
stored as orc
tblproperties(“transactional”=“true”)

#hive 2之后新增批量更新功能:代替拉链表
set hive.support.concurrency=true;
set hive.enforce.bucketing = true;
set hive.exec.dynamic.partition.mode=nonstrict;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.compactor.initiator.on=true;
set hive.compactor.worker.thread=1;
set hive.auto.convert.join=false;
set hive.merge.cardinality.check=false; #目标表中出现重复匹配时要设置该参数

#合并数据
MERGE INTO orderhistory h USING (
select name,sum(pay) tsum,current_date() modtime
from groupbyorder group by name
)g
ON h.name=g.name
WHEN MATCHED THEN UPDATE SET total=total+tsum,modified=modtime
WHEN NOT MATCHED THEN INSERT VALUES(g.name,g.tsum,g.modtime);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值