Hive的数据倾斜
数据分布不均匀,造成数据热点,引起性能问题。Jobs 数比较多的作业运行效率相对比较低。主要表现为,任务进度长时间维持在 99%或者 100%的附近,查看任务监控页面,发现只有少量 reduce 子任务未完成,因为其处理的数据量和其他的 reduce 差异过大。 单一 reduce 处理的记录数和平均记录数相差太大,通常达到好几倍之多,最长时间远大 于平均时长。
容易造成倾斜情况,及应对方法
空值产生的数据倾斜,把空值的 key 变成一个字符串加上一个随机数
不同数据类型关联产生数据倾斜,统一关联字段数据类型
大小表关联查询产生数据倾斜 使用map join,新版本可以配置参数设置mapjoin,老版本需要通过提示
map join 概念:将其中做连接的小表(全量数据)分发到所有 MapTask 端进行 Join,从 而避免了 reduceTask,前提要求是内存足以装下该全量数据,Map 端完成 Join 操作。
count(distinct col)和group by容易产生数据倾斜
Hive优化策略
优化常用手段
1、好的模型设计事半功倍
2、解决数据倾斜问题
3、减少 job 数
4、设置合理的 MapReduce 的 task 数,能有效提升性能。(比如,10w+级别的计算,用 160个 reduce,那是相当的浪费,1 个足够)
5、了解数据分布,自己动手解决数据倾斜问题是个不错的选择。这是通用的算法优化,但 算法优化有时不能适应特定业务背景,开发人员了解业务,了解数据,可以通过业务逻辑精 确有效的解决数据倾斜问题
6、数据量较大的情况下,慎用 count(distinct),group by 容易产生倾斜问题
7、对小文件进行合并,是行之有效的提高调度效率的方法,假如所有的作业设置合理的文 件数,对云梯的整体调度效率也会产生积极的正向影响
8、优化时把握整体,单个作业最优不如整体最优
排序选择
cluster by:对同一字段分桶并排序,不能和 sort by 连用
distribute by + sort by:分桶,保证同一字段值只存在一个结果文件当中,结合 sort by 保证 每个 reduceTask 结果有序
sort by:单机排序,单个 reduce 结果有序
order by:全局排序,缺陷是只能使用一个 reduce
笛卡尔积
当 Hive 设定为严格模式(hive.mapred.mode=strict)时,不允许在 HQL 语句中出现笛卡尔积, 这实际说明了 Hive 对笛卡尔积支持较弱。因为找不到 Join key,Hive 只能使用 1 个 reducer 来完成笛卡尔积。
当然也可以使用 limit 的办法来减少某个表参与 join 的数据量,但对于需要笛卡尔积语义的 需求来说,经常是一个大表和一个小表的 Join 操作,结果仍然很大(以至于无法用单机处 理),这时 MapJoin才是最好的解决办法。MapJoin,顾名思义,会在 Map 端完成 Join 操作。 这需要将 Join 操作的一个或多个表完全读入内存。
PS:MapJoin 在子查询中可能出现未知 BUG。在大表和小表做笛卡尔积时,规避笛卡尔积的 方法是,给 Join 添加一个 Join key,原理很简单:将小表扩充一列 join key,并将小表的条 目复制数倍,join key 各不相同;将大表扩充一列 join key 为随机数。
精髓就在于复制几倍,最后就有几个 reduce 来做,而且大表的数据是前面小表扩张 key 值 范围里面随机出来的,所以复制了几倍 n,就相当于这个随机范围就有多大 n,那么相应的, 大表的数据就被随机的分为了 n 份。并且最后处理所用的 reduce 数量也是 n,而且也不会 出现数据倾斜。
in/exists 语句
推荐使用 hive 的一个高效替代方案:left semi join
设置合理的 maptask 数量
Map 数过大
Map 阶段输出文件太小,产生大量小文件
初始化和创建 Map 的开销很大
Map 数太小
文件处理或查询并发度小,Job 执行时间过长
大量作业时,容易堵塞集群
参考资料:
https://www.cnblogs.com/qingyunzong/p/8847775.html