Hive---数据倾斜的产生及解决方法

一、数据倾斜的定义

数据倾斜是指在并行进行数据处理的时候,由于单个partition的数据显著多余其他部分,分布不均匀,导致大量数据集中分布到一台或者某几台计算节点上,使得该部分的处理速度远低于平均计算速度,成为整个数据集处理的瓶颈,从而影响整体计算性能。

二、几种数据倾斜的解决方案

1、空值引发的数据倾斜

在数据采集时,判断导致数据倾斜的key是不是提前过滤掉了。在inner join,也就是使用内连接时,hive默认过滤掉了空值,但对于left join等等,会保留左边有的值。空KEY过滤的使用场景:1.非inner join;2.不需要字段为Null的。

两种过滤方式:

(1) insert overwrite table jointable select n.* from (select * from nullidtable where id is not null) n left join bigtable o on n.id = o.id;//先过滤掉空值,再进行join

(2)有时虽然某个 key 为空对应的数据很多,但是相应的数据不是异常数据,必须要包含在 join 的结果中,此时我们可以表 a 中 key 为空的字段赋一个随机的值,使得数据随机均匀地分不到不同的 reducer 上。

insert overwrite table jointable select n.* from nullidtable n full join bigtable o on nvl(n.id,rand()) = o.id; //nvl(a, b):如果a为Null,则取b的值作为a的值。

2、大表join小表使用MapJoin

首先是在本地客户端生成的Task A,是一个MapReduce Local Task,负责把小表数据从HDFS读取到内存哈希表。读取后,它会将内存中的哈希表序列化为磁盘上的文件,并将哈希表文件压缩为tar文件
接下来是Task B,该任务是一个没有Reduce的MapReduce任务,启动的时候,上一步骤的tar文件会被放到Hadoop分布式缓存中,Hadoop分布式缓存将把tar文件填充到每个Mapper的本地磁盘并解压缩该文件。然后mapper可以将哈希表文件反序列化回内存,并像以前一样执行join工作,也就是根据大表中的每一条记录去和DistributeCache中小表对应的HashTable关联,并直接输出结果。

好处:没有shuffle阶段,减少了大量的网络传输;没有了reduce阶段,防止数据倾斜的发生;

3、group by造成的数据倾斜->使用两段聚合

原理:两阶段聚合指的是先局部聚合再全局聚合。局部聚合时候给每个key值加上随机前缀进行打散,原本相同的key值会变成不同的新key值,便可以让原来由一个task处理的数据根据加上随机前缀后的新key值分散到多个Task上做聚合,从而缓解单个task处理数据量过多的问题。再去除随机前缀做全局聚合,既可以得到最终结果。

4、考虑到分区数是不是不够用,适当提高(spark默认200分区,可适当提升)

最后

深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

小编已加密:aHR0cHM6Ly9kb2NzLnFxLmNvbS9kb2MvRFVrVm9aSGxQZUVsTlkwUnc==出于安全原因,我们把网站通过base64编码了,大家可以通过base64解码把网址获取下来。

猜你喜欢

转载自blog.csdn.net/m0_67265464/article/details/126790203