六、Hive企业优化之Job并行度
在实际应用中,复杂的hive sql语句在执行的过程中会有多个job,如果说在这些个job中,没有相互依赖关系的job我们可以设定让他们并行执行
如图:
job-1、job-3、job-4、job-6有相互依赖的关系,job-2、job-5和其他没有相互依赖的关系,那么没有相互依赖关系的job我们可以设定让他们并行执行。
<property> <name>hive.exec.parallel</name> <value>false</value> <description>Whether to execute jobs in parallel</description> </property> <property> <name>hive.exec.parallel.thread.number</name> <value>8</value> <description>How many jobs at most can be executed in parallel</description> </property>
set hive.exec.parallel = true; //打开任务并行执行 set hive.exec.parallel.thread.number=8; //同一个sql允许最大并行度,默认为8。
首先测试不设置并行度:
select count(1) from order group by username union all select count(1) from order group by city;
它有3个job,在不设置并行度的情况下,他们是依次执行MR程序。
再测试设置了并行度的情况:
由此可以看出stage-1和stage-3并行执行,查看执行计划,stage-2依赖于stage-1和stage-3。
七、Hive企业优化之推测执行及JVM重用
1.jvm重用
当job提交到Yarn之后,每个job中的map任务或者reduce任务,都会分配一个container容器,map或者reduce任务的执行的资源由container提供,每个map任务或者reduce任务执行开始前都要初始化container,任务执行完成之后要销毁container。如果我们采用jvm重用,那么每一个任务执行完成之后,不需要销毁容器,container直接接受新的map任务或者reduce任务。
mapreduce.job.jvm.numtasks 默认值:1 (不重用) >1 重用 建议值:3或者5 不要超过8
2.推测执行
当某一个map任务或者reduce任务执行时间过长,并一直没有完成,这个时候MR会对这个任务进行推测执行,也就是MR认为这个任务有问题,需要发送到其他的节点上重新执行,任务执行结果以最快完成的那个节点为准。在hive的配置中,MR默认推测执行。
在实际的企业应用中,推测执行会被关闭
set hive.mapred.reduce.tasks.speculative.execution = false; (建议设为false)
<property> <name>hive.mapred.reduce.tasks.speculative.execution</name> <value>true</value> <description>Whether speculative execution for reducers should be turned on. </description> </property>
八、Hive企业优化之Strict Mode
strict mode(严格检查模式)
在生产环境中,我们一般会将strict mode设置为严格检查模式。
set hive.mapred.mode = strict;
<property> <name>hive.mapred.mode</name> <value>nonstrict</value> <description> The mode in which the Hive operations are being performed. In strict mode, some risky queries are not allowed to run. They include: Cartesian Product. No partition being picked up for a query. Comparing bigints and strings. Comparing bigints and doubles. Orderby without limit. </description> </property>
使用严格检查模式可以禁止3中类型的查询:
1.对分区表的查询,如果不加分区字段的过滤,不能被执行;
正常情况下,分区表要加分区字段过滤 select * from order where day = '09'(一定要加分区字段过滤)
2.对于order by 查询,必须要加limit语句的限制。如果不加会被禁止执行。
正常情况下: select * from order order by price limit 10;
3.限制笛卡尔积的查询(两个表的链接,如果不用join,而用where连接,会被禁止执行)
select * from a,b where a.id = b.id ;(这种方式被禁止执行) select * from a left join b on a.id = b.id(尽可能用这种方式)
九、Hive企业优化之join优化方案
1.map join
场景:小表与大表的join,将小表数据加载到内存中。然后在map端完成与大表数据的join
setup() map() cleaup()
2.reduce join/shuffle join/common join
两个表的数据作为map端的输入,在reduce端进行相同key的value值合并。
cumtomer表和order表,根据两个表的连接字段userid进行合并<userid,List(customer + order表)>
场景:两个表的数据量都比较大的时候,我们会采用shuffle join。
关于MR的join表,详细请看这篇文章
https://blog.csdn.net/weixin_45366499/article/details/109137735
3.SMB join (Sort-Merge-Bucket)优化
SMB 存在的目的主要是为了解决大表与大表间的 Join 问题,分桶其实就是把大表化成了“小表”,然后 Map-Side Join 解决之,这是典型的分而治之的思想
customer表 userid字段 (bucket -1 ) 0001 ---- 0009 (bucket -2 ) 0010 -----0020 (bucket -3 ) 0021 -----0030 order表 userid字段 (bucket -1 ) 0001 ---- 0009 (bucket -2 ) 0010 -----0020 (bucket -3 ) 0021 -----0030
set hive.auto.convert.sortmerge.join=true; set hive.optimize.bucketmapjoin = true; set hive.optimize.bucketmapjoin.sortedmerge = true;
十、Hive企业优化之数据倾斜解决方案
数据倾斜:一般的是由于数据的分布不均匀,造成大量的数据集中到一点,造成数据的热点。
1.哪些情况下会发生数据倾斜:
1).数据在节点上分布不均匀 block -> map (5M) block -> map (100M) 2).join时,key中存在个别值得数据量比较大(比如null值)group select * from a left join b on a.id = b.id 3)count(distinct key) 在数据量大的情况下,也是容易出现数据倾斜。因为distinct的时候,也是按照group by 字段进行分组
2.针对以上的数据倾斜,我们有哪些措施或者解决方案:
1)针对group by的情况 >>>在map端进行部分数据的合并 默认是true,也就是在map端进行合并 <property> <name>hive.map.aggr</name> <value>true</value> <description>Whether to use map-side aggregation in Hive Group By queries</description> </property> <property> <name>hive.groupby.mapaggr.checkinterval</name> <value>100000</value> <description>Number of rows after which size of the grouping keys/aggregation classes is performed</description> </property> >>> 负载均衡 第一个mr job中,首先会将map输出的结果随机分布到reduce中,每个reduce做部分聚合操作并输出结果。这样的话结果相同的 group by key 有可能被分发到不同的reduce中,从而达到负载均衡的目的。 第二个mr job中,会根据每个reduce预处理的结果完成最终的聚合操作 <property> <name>hive.groupby.skewindata</name> <value>false</value> <description>Whether there is skew in data to optimize group by queries</description> </property> set hive.groupby.skewindata = true; 当设置为true时,会变成两个MapReduce. 默认是false,不负载均衡。 2)针对count(distinct xx) 当xx字段存在大量的某个值是,比如null或者空记录时,容易数据倾斜 解决思路: 对于特定的值,我们选择特定的处理方式: 比如null,要么通过where 条件过滤掉;要么重新设置一个新的值,但这个值不影响数据分析
十一、Hive企业优化之limit优化
在时候select查询的时候通常会和limit一起使用。通常情况下使用limit是将所有的数据全部加载一遍,然后再从缓存的结果中去取其中几条,这样对于大量数据来操作会非常消耗性能,这里可以设置一个参数来优化一下,设置过之后就不需要全部加载,而是直接从HDFS文件中选几条数据
hive (db_hive)> select * from order limit 5;
<property> <name>hive.limit.optimize.enable</name> <value>false</value> <description>Whether to enable to optimization to trying a smaller subset of data for simple LIMIT first.</description> </property>
实际应用中,会设置为
set hive.limit.optimize.enable = true;