参数调节
set mapred.child.java.opts=-Xmx8000m; set mapreduce.map.java.opts=-Xmx8096m; set mapreduce.reduce.java.opts=-Xmx8096m; set mapreduce.map.memory.mb=8096; set mapreduce.reduce.memory.mb=8096; ———————————————— 版权声明:本文为CSDN博主「cow cow fly」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/XiangFei_Niu/article/details/88412159
知识点
http://www.imooc.com/article/259350
数据倾斜原因
join
其中一个表较小,但是 key 集中。分发到某一个或几个 Reduce 上的数据远高于平均值
大表与大表,但是分桶的判断字段 0 值或空值过多。 这些空值由一个 Reduce 处理,非常慢。
group by
group by 维度过小,某值的数量过多 处理某值的reduce非常耗时
count distinct
某特殊值过多 处理此特殊值的reduce耗时
1.2原因:
1)、key分布不均匀
2)、业务数据本身的特性
3)、建表时考虑不周
4)、某些SQL语句本身就有数据倾斜
limit
limit 限制,对于hive 很多时候都是需要进行全表统计,然后显示 limit 限制的条数的记录,对于执行速度并没有多大的提升,如果我们的需求是可以通过抽样来看整体情况的,那么全表扫描无疑是很浪费资源的,所以hive也是提供了相应的优化机制,来允许我们才用抽样使用 limit hive.limit.optimize.enable=true — 开启对数据源进行采样的功能 hive.limit.row.max.size — 设置最小的采样容量 hive.limit.optimize.limit.file — 设置最大的采样样本数 作者:慕哥9229398 链接:http://www.imooc.com/article/259350 来源:慕课网
本地执行
当我们觉得有些任务是杀鸡用牛到的时候,可以尝试运用本地运行,分布式计算只有再数据量足够大的时候才能体现其优势,否则单机是更快的。 通过 mapred.job.tracker=true 参数开启本地模式 当然,hive 也提供了自动开启本地模式的优化机制 通过 hive.exec.mode.local.auto开启自动执行,自动开启的条件如下: 1.job的输入数据量小于参数:hive.exec.mode.local.auto.inputbytes.max(默认128MB) 2.job的map数必须小于参数:hive.exec.mode.local.auto.tasks.max(默认4) 3.job的reduce数必须为0或者1 作者:慕哥9229398 链接:http://www.imooc.com/article/259350 来源:慕课网
join 优化
关于驱动表的选取,选用join key分布最均匀的表作为驱动表
做好列裁剪和filter操作,以达到两表做join的时候,数据量相对变小的效果。
map join
大表关联大表
写的不错的一篇博客
https://blog.csdn.net/yeweiouyang/article/details/45665727
把空值的key变成一个字符串加上随机数,把倾斜的数据分到不同的reduce上,由于null值关联不上,处理后并不影响最终结果。
大表关联小表
使用map join让小的维度表(1000条以下的记录条数) 先进内存。在map端完成reduce.
小表关联大表
count distinct1
count distinct大量相同特殊值
count distinct时,将值为空的情况单独处理,如果是计算count distinct,可以不用处理,直接过滤,在最后结果中加1。如果还有其他计算,需要进行group by,可以先将值为空的记录单独处理,再和其他计算结果进行union。
group by1
采用sum() group by的方式来替换count(distinct)完成计算。
特殊情况特殊处理:
在业务逻辑优化效果的不大情况下,有些时候是可以将倾斜的数据单独拿出来处理。最后union回去。
分桶
当数据量很大并且分布到一个节点处理时,单个节点处理的能力不够,这时候可以考虑采用分桶的方法对数据进行处理。
https://github.com/Joldnine/joldnine.github.io/issues/25
https://www.iteblog.com/archives/2362.html
有时间看看的博客
https://blog.csdn.net/zjerryj/article/details/77519595
知识点
http://www.imooc.com/article/259350
hive 执行计划
https://www.2cto.com/net/201701/587186.html
Hive SQL执行计划深度解析
数据倾斜原因
join
其中一个表较小,但是 key 集中。分发到某一个或几个 Reduce 上的数据远高于平均值
大表与大表,但是分桶的判断字段 0 值或空值过多。 这些空值由一个 Reduce 处理,非常慢。
group by
group by 维度过小,某值的数量过多 处理某值的reduce非常耗时
count distinct
某特殊值过多 处理此特殊值的reduce耗时
1.2原因:
1)、key分布不均匀
2)、业务数据本身的特性
3)、建表时考虑不周
4)、某些SQL语句本身就有数据倾斜
参数调节
hive.map.aggr = true
Map 端部分聚合,相当于Combiner
hive.groupby.skewindata=true
默认设置了hive.map.aggr=true,所以会在mapper端先group by一次,最后再把结果merge起来,为了减少reducer处理的数据量。注意看explain的mode是不一样的。mapper是hash,reducer是mergepartial。如果把hive.map.aggr=false,那将groupby放到reducer才做,他的mode是complete.
limit
limit 限制,对于hive 很多时候都是需要进行全表统计,然后显示 limit 限制的条数的记录,对于执行速度并没有多大的提升,如果我们的需求是可以通过抽样来看整体情况的,那么全表扫描无疑是很浪费资源的,所以hive也是提供了相应的优化机制,来允许我们才用抽样使用 limit hive.limit.optimize.enable=true — 开启对数据源进行采样的功能 hive.limit.row.max.size — 设置最小的采样容量 hive.limit.optimize.limit.file — 设置最大的采样样本数 作者:慕哥9229398 链接:http://www.imooc.com/article/259350 来源:慕课网
本地执行
当我们觉得有些任务是杀鸡用牛到的时候,可以尝试运用本地运行,分布式计算只有再数据量足够大的时候才能体现其优势,否则单机是更快的。 通过 mapred.job.tracker=true 参数开启本地模式 当然,hive 也提供了自动开启本地模式的优化机制 通过 hive.exec.mode.local.auto开启自动执行,自动开启的条件如下: 1.job的输入数据量小于参数:hive.exec.mode.local.auto.inputbytes.max(默认128MB) 2.job的map数必须小于参数:hive.exec.mode.local.auto.tasks.max(默认4) 3.job的reduce数必须为0或者1 作者:慕哥9229398 链接:http://www.imooc.com/article/259350 来源:慕课网
并行化
stage 并行执行
对于一些复杂的 hql 可能会需要多个 stage 一起执行来完成,默认情况下,hive 是根据其解析的计划串行执行一个个 stage 的,为了提高执行速度,我们可以开启 stage 并行执行。 通过 hive.exec.parallel=true
开启
作者:慕哥9229398 链接:http://www.imooc.com/article/259350 来源:慕课网
Hive小文件合并
解决小文件的问题可以从两个方向入手:
输入合并。即在Map前合并小文件
输出合并。即在输出结果的时候合并小文件
配置Map输入合并
– 每个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;
join 优化
关于驱动表的选取,选用join key分布最均匀的表作为驱动表
做好列裁剪和filter操作,以达到两表做join的时候,数据量相对变小的效果。
map join
大表关联大表
写的不错的一篇博客
https://blog.csdn.net/yeweiouyang/article/details/45665727
把空值的key变成一个字符串加上随机数,把倾斜的数据分到不同的reduce上,由于null值关联不上,处理后并不影响最终结果。
大表关联小表
使用map join让小的维度表(1000条以下的记录条数) 先进内存。在map端完成reduce.
小表关联大表
count distinct1
count distinct大量相同特殊值
count distinct时,将值为空的情况单独处理,如果是计算count distinct,可以不用处理,直接过滤,在最后结果中加1。如果还有其他计算,需要进行group by,可以先将值为空的记录单独处理,再和其他计算结果进行union。
group by1
采用sum() group by的方式来替换count(distinct)完成计算。
特殊情况特殊处理:
在业务逻辑优化效果的不大情况下,有些时候是可以将倾斜的数据单独拿出来处理。最后union回去。
分桶
当数据量很大并且分布到一个节点处理时,单个节点处理的能力不够,这时候可以考虑采用分桶的方法对数据进行处理。
https://github.com/Joldnine/joldnine.github.io/issues/25
https://www.iteblog.com/archives/2362.html
title: hive数据倾斜解决方法 date: 2020-02-27 categories: hive tags: hive 数据倾斜 published: false
调参
开启并行执行
set hive.exec.parallel=true;
开启任务并行执行
set hive.exec.parallel.thread.number=8;
同一个sql允许并行任务的最大线程数
Whether to execute jobs in parallel. Applies to MapReduce jobs that can run in parallel, for example jobs processing different source tables before a join. As of Hive 0.14, also applies to move tasks that can run in parallel, for example moving files to insert targets during multi-insert.
开启 stage 并行执行
hive.exec.parallel=true
对于一些复杂的 hql 可能会需要多个 stage 一起执行来完成,默认情况下,hive 是根据其解析的计划串行执行一个个 stage 的,为了提高执行速度,我们可以开启 stage 并行执行。 通过 开启
小文件处理的参数
hive.merge.mapredfiles=false | //reduce输出是否合并 |
hive.merge.mapfiles=true | //map输出是否合并 |
参数调节
hive.map.aggr = true
Map 端部分聚合,相当于 Combiner
hive.groupby.skewindata=true
默认设置了hive.map.aggr=true,所以会在mapper端先group by一次,最后再把结果merge起来,为了减少reducer处理的数据量。注意看explain的mode是不一样的。mapper是hash,reducer是mergepartial。如果把hive.map.aggr=false,那将groupby放到reducer才做,他的mode是complete.
知识点
http://www.imooc.com/article/259350
hive 执行计划
https://www.2cto.com/net/201701/587186.html
Hive SQL执行计划深度解析
数据倾斜原因
join
其中一个表较小,但是 key 集中。分发到某一个或几个 Reduce 上的数据远高于平均值
大表与大表,但是分桶的判断字段 0 值或空值过多。 这些空值由一个 Reduce 处理,非常慢。
group by
group by 维度过小,某值的数量过多 处理某值的reduce非常耗时
count distinct
某特殊值过多 处理此特殊值的reduce耗时
1.2原因:
1)、key分布不均匀
2)、业务数据本身的特性
3)、建表时考虑不周
4)、某些SQL语句本身就有数据倾斜
limit
limit 限制,对于hive 很多时候都是需要进行全表统计,然后显示 limit 限制的条数的记录,对于执行速度并没有多大的提升,如果我们的需求是可以通过抽样来看整体情况的,那么全表扫描无疑是很浪费资源的,所以hive也是提供了相应的优化机制,来允许我们才用抽样使用 limit hive.limit.optimize.enable=true — 开启对数据源进行采样的功能 hive.limit.row.max.size — 设置最小的采样容量 hive.limit.optimize.limit.file — 设置最大的采样样本数 作者:慕哥9229398 链接:http://www.imooc.com/article/259350 来源:慕课网
本地执行
当我们觉得有些任务是杀鸡用牛到的时候,可以尝试运用本地运行,分布式计算只有再数据量足够大的时候才能体现其优势,否则单机是更快的。 通过 mapred.job.tracker=true 参数开启本地模式 当然,hive 也提供了自动开启本地模式的优化机制 通过 hive.exec.mode.local.auto开启自动执行,自动开启的条件如下: 1.job的输入数据量小于参数:hive.exec.mode.local.auto.inputbytes.max(默认128MB) 2.job的map数必须小于参数:hive.exec.mode.local.auto.tasks.max(默认4) 3.job的reduce数必须为0或者1 作者:慕哥9229398 链接:http://www.imooc.com/article/259350 来源:慕课网
Hive小文件合并
解决小文件的问题可以从两个方向入手:
输入合并。即在Map前合并小文件
输出合并。即在输出结果的时候合并小文件
配置Map输入合并
– 每个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;
join 优化
关于驱动表的选取,选用join key分布最均匀的表作为驱动表
做好列裁剪和filter操作,以达到两表做join的时候,数据量相对变小的效果。
map join
大表关联大表
写的不错的一篇博客
https://blog.csdn.net/yeweiouyang/article/details/45665727
把空值的key变成一个字符串加上随机数,把倾斜的数据分到不同的reduce上,由于null值关联不上,处理后并不影响最终结果。
大表关联小表
使用map join让小的维度表(1000条以下的记录条数) 先进内存。在map端完成reduce.
小表关联大表
count distinct1
count distinct大量相同特殊值
count distinct时,将值为空的情况单独处理,如果是计算count distinct,可以不用处理,直接过滤,在最后结果中加1。如果还有其他计算,需要进行group by,可以先将值为空的记录单独处理,再和其他计算结果进行union。
group by1
采用sum() group by的方式来替换count(distinct)完成计算。
特殊情况特殊处理:
在业务逻辑优化效果的不大情况下,有些时候是可以将倾斜的数据单独拿出来处理。最后union回去。
分桶
当数据量很大并且分布到一个节点处理时,单个节点处理的能力不够,这时候可以考虑采用分桶的方法对数据进行处理。
https://github.com/Joldnine/joldnine.github.io/issues/25
https://www.iteblog.com/archives/2362.html
对特定 SQL 语句的优化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
collect_set()
Hive 0.10.0 以后版本支持
[Error 30017]: Skipping stats aggregation by error org.apache.hadoop.hive.ql.metadata.HiveException: [Error 30000]: StatsPublisher cannot be obtained. There was a error to retrieve the StatsPublisher, and retrying might help. If you dont want the query to fail because accurate statistics could not be collected, set hive.stats.reliable=false