3、Hive-sql优化,数据倾斜处理
一、Hive-sql优化
#增加reducer任务数量(拉取数量分流) set mapred.reduce.tasks=20; #在同一个sql中的不同的job是否可以同时运行,默认为false set hive.exec.parallel=true; #增加同一个sql允许并行任务的最大线程数 set hive.exec.parallel.thread.number=8; #设置reducer内存大小 set mapreduce.reduce.memory.mb=4096; set mapreduce.reduce.java.opts=-Xmx3584m; -- -Xmx 设置堆的最大空间大小。#mapjoin相关设置,小表加载到内存,无reduceset hive.mapjoin.smalltable.filesize=25000000; -- 刷入内存表的大小(字节)。注意:设置太大也不会校验,所以要根据自己的数据集调整set hive.auto.convert.join = true; -- 开启mapjoin,默认falseset hive.mapjoin.followby.gby.localtask.max.memory.usage=0.6 ;--map join做group by操作时,可使用多大的内存来存储数据。若数据太大则不会保存在内存里,默认0.55set hive.mapjoin.localtask.max.memory.usage=0.90; -- 本地任务可以使用内存的百分比,默认值:0.90-- 在设置成false时,可以手动的指定mapjoin /*+ MAPJOIN(c) */ 。-->c:放到内存中的表select /*+ MAPJOIN(c) */ * from user_install_status uinner join country_dict con u.country=c.code-- 如果不是做innerjoin, 做left join 、right join-- A left join B, 把B放到内存-- A right join B, 把A放到内存#设置执行引擎set hive.execution.engine=mr; -- 执行MapReduce任务,也可以设置为spark-- 设置内存大小set mapreduce.reduce.memory.mb=8192; -- reduce 设置的是 Container 的内存上限,这个参数由 NodeManager 读取并进行控制,当 Container 的内存大小超过了这个参数值,NodeManager 会负责 kill 掉 Containerset mapreduce.reduce.java.opts=-Xmx6144m; -- reduce Java 程序可以使用的最大堆内存数,要小于 mapreduce.reduce.memory.mbset mapreduce.map.memory.mb=8192; -- map申请内存大小set mapreduce.map.java.opts=-Xmx6144m;#动态分区设置,参考:https://www.cnblogs.com/cssdongl/p/6831884.htmlset hive.exec.dynamic.partition=true; 是开启动态分区set hive.exec.dynamic.partition.mode=nonstrict; 这个属性默认值是strict,就是要求分区字段必须有一个是静态的分区值,当前设置为nonstrict,那么可以全部动态分区#其他-- 开始负载均衡set hive.groupby.skewindata=true-- 开启map端combinerset hive.map.aggr=true
二、数据倾斜
2.1、数据倾斜的表现
- 任务进度长时间维持在99%(或100%),查看任务监控页面,发现只有少量(1个或几个)reduce子任务未完成。因为其处理的数据量和其他reduce差异过大。
- 单一reduce的记录数与平均记录数差异过大,通常可能达到3倍甚至更多。 最长时长远大于平均时长。
2.2、数据倾斜的解决方案
参数调节:
- 对于group by 产生倾斜的问题
- 开启map端combiner:【set hive.map.aggr=true;】
- 开启负载均衡:【set hive.groupby.skewindata=true;】
- 有数据倾斜的时候进行负载均衡,当选项设定为 true,生成的查询计划会有两个 MR Job。
- 第一个 MR Job 中,Map 的输出结果集合会随机分布到 Reduce 中,每个 Reduce 做部分聚合操作,并输出结果,这样处理的结果是相同的 Group By Key 有可能被分发到不同的 Reduce 中,从而达到负载均衡的目的;
- 第二个 MR Job 再根据预处理的数据结果按照 Group By Key 分布到 Reduce 中(这个过程可以保证相同的 Group By Key 被分布到同一个 Reduce 中),最后完成最终的聚合操作。
SQL 语句调节:
- 大小表Join:
- 使用map join让小的维度表先进内存。在map端完成join,不经过reduce。
- 大表Join大表:
- 非法数据太多,比如null,可以把空值的key变成一个字符串加上随机数,把倾斜的数据分到不同的reduce上,由于null值关联不上,处理后并不影响最终结果。
- 如果null值不要,可以通过where条件筛选掉;
- 将大量的非法数据转化成随机数+字符串,这样两个表的数据不会join在一起。
- count distinct大量相同特殊值:
- count distinct时,将值为空的情况单独处理
- 如果是计算count distinct,可以不用处理,直接过滤,在最后结果中加1。
- 如果还有其他计算,需要进行group by,可以先将值为空的记录单独处理,再和其他计算结果进行union。
- 采用sum group by的方式来替换 count(distinct) 完成计算。
- 特殊情况特殊处理:
- 在业务逻辑优化效果的不大情况下,有些时候是可以将倾斜的数据单独拿出来处理。最后union回去
- 比如:group by时维度过小,数据过于集中,数据自身倾斜,比如 北京的用户比其它地方的用户多很多
- 此时可以把北京的数据单独处理:先把北京的数据分成N块,每块的数据进行局部统计,再将每块的局部统计结果进行汇总,最终统计出结果
相关推荐
archive 2020-07-30
成长之路 2020-07-28
eternityzzy 2020-07-19
taisenki 2020-07-05
tugangkai 2020-07-05
SignalDu 2020-07-05
zlsdmx 2020-07-05
tomson 2020-07-05
tugangkai 2020-07-04
tomson 2020-07-05
Zhangdragonfly 2020-06-28
genshengxiao 2020-06-26
成长之路 2020-06-26
tomson 2020-06-26
蜗牛之窝 2020-06-26
成长之路 2020-06-25