Hive优化笔记(2 - 数据倾斜)

news/2024/5/20 2:58:04 标签: sql, hive, hdfs, mapreduce, 大数据

一 基本概念

简单来说数据倾斜就是数据的key 的分化严重不均,造成一部分数据很多,一部分数据很少。默认情况下, Map 阶段同一 Key 数据分发给一个 reduce,当一个 key 数据过大时,就发生倾斜了

数据倾斜一般有两种情况:
变量值很少: 单个变量值的占比极大,常见的字段如性别、学历、年龄等
变量值很多: 单个变量值的占比极小,常见的字段如收入、订单金额之类的

其在reduce的表现有二:① 任务进度长时间维持在99%,只有少量reduce子任务未完成。这是因为其处理的数据量和其他reduce差异过大;② 单一reduce的时长与平均时长差异过大

二 造成数据倾斜的常见操作

关键词

情形

后果

Join

其中一个表较小,

但是key集中

分发到某一个或几个Reduce上的数据远高于平均值

大表与大表,

但是分桶的判断字段0值或空值过多

这些空值都由一个reduce处理,非常慢

group by

group by 维度过小,

某值的数量过多

处理某值的reduce非常耗时

Count Distinct

某特殊值过多

处理此特殊值的reduce非常耗时

三 优化方案

1、参数调节

sql">-- Map 端部分聚合,相当于Combiner
-- 默认就是true
hive.map.aggr=true

-- 负载均衡,默认是false
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 中),最后完成最终的聚合操作

2、SQL语句调节

 2.1 group by替换distinct

数据量大的情况下, 由于 count(distinct) 操作需要用一个Reduce job来完成, 这一个 Reduce 需要处理的数据量太大, 就会导致整个 Job 很难完成,这时可以用group by来改写

但,当数据集很小或者key的倾斜比较明显时,group by还可能会比distinct慢。这是因为group by写会启动两个MR job(单纯distinct只会启动一个)

2.2 大小表Join(MapJoin)

在对大表和一个或多个小表执行Join操作时,MapJoin会将小表全部加载到内存中,在Map阶段执行表连接,而非等到Reduce阶段才执行表连接,这样可以缩短大量数据传输时间,提升系统资源利用率,从而起到优化作业的作用

新版 hive默认对大小表 Join进行了优化,小表放在左边和右边没有区别。同时默认开启了MapJoin

sql">-- 大表小表的阈值设置(默认 25M 以下认为是小表)
set hive.mapjoin.smalltable.filesize = 25000000

 

2.3 cluster by替换order by

order by:对全部数据进行全局排序,并且只会启动一个reducer干活
sort by:是局部排序。会根据数据量的大小启动一到多个reducer来干活,并且,它会在进入reduce之前为每个reducer都产生一个排序文件。这样的好处是提高了全局排序的效率
distribute by:控制map结果的分发,它会将具有相同字段的map输出分发到一个reduce节点上做处理
cluster by:相当于 distribute by 和sort by 的结合,默认只能是升序

如下两种写法查询结果相同

sql">-- cluster by
select * from store cluster by myid;
-- distribute by,sort by
select * from store distribute by myid sort by myid asc;

https://blog.csdn.net/qq_40795214/article/details/82190827

 

2.4 空KEY过滤(这里的空key指代大量重复key值)

其使用条件是1:非inner join;2:不需要字段null

sql">select n.* from nullidtable n full join bigtable o on
nvl(n.id,rand()) = o.id; --给null赋值随机数

2.5 空key转换(这里的空key指代大量重复key值)

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

sql">-- NVL(表达式1,表达式2)
-- 如果表达式1为空值,NVL返回值为表达式2的值,否则返回表达式1的值。 
select a.* from table_a a full join table_b b on
nvl(a.id,rand()) = b.id;

2.6 单独处理倾斜key

一般来讲倾斜的key都很少,我们可以对其打上一个较小的随机数前缀(比如0~9),先进行一次运算,之后再恢复 key 进行最终聚合

2.7 数据类型转换

主要出现在相同业务含义的列发生过逻辑上的变化时。

举个例子,假如有一旧一新两张日历记录表,旧表的记录类型字段是(event_type int),新表的是(event_type string)。为了兼容旧版记录,新表的event_type也会以字符串形式存储旧版的值,比如'17'。当这两张表join时,经常要耗费很长时间。其原因就是如果不转换类型,计算key的hash值时默认是以int型做的,这就导致所有“真正的”string型key都分配到一个reducer上。所以要注意类型转换


http://www.niftyadmin.cn/n/975251.html

相关文章

2位前辈的经历告诉你Python新手好找工作吗?初级岗位多不多

么多人推荐学 Python 入IT 行的,如果他们学完 Python这一套找不到工作怎么办?这是笔者在网上看到的一个问题,那么真相究竟如何呢?到底学完Python是否好找工作,初级岗位多不多?我们来看看2位前辈的经历&…

80%大数据交易涉及个人信息

“当大数据进行交易的时候,目前据不完全统计80%是个人信息。这个冰山还没有浮出来,但是危害已经产生,所以在大数据交易的过程中最重要两个环节一是清洗和脱敏,脱敏又叫匿名化,但全球都尚未形成脱敏的具体标准。” 近日…

后缀自动机练习专题

后缀自动机练习专题 一些比较有用的东东: (1) \(\text{sam}\) 上一条从初始状态出发的路径对应一个子串(2) \(\text{parent}\) 树上一个节点能表示的最长的串对应一个前缀/后缀(3) \(len(u)\) 表示节点 \(u\) 能表示的最长串的长度(4) \(fa(u)\) 表示节点 \(u\) 的后…

WPF中应用字体图标

原文:WPF中应用字体图标一、什么是字体图标 我们在进行GDI(图形界面)编程的过程中图标是不可少的。近些年随着网络的繁荣和移动应用的繁荣,矢量图的应用越来越火。 矢量图是一种用数学方法描述的、由一系列点和线组成的图,因此相比…

SaaS方案提供商The SaaS Co.获80万欧元种子轮融资

The SaaS Co. 是一家软件即服务(SaaS)解决方案的初创公司,近日,该公司宣布获得了一笔 80 万欧元(约合 85 万美元)的种子轮融资,本轮融资的投资方包括一批匿名天使投资人,此外欧盟还为…

Hive优化笔记(3 - 一些参数)

动态分区 静态分区:手动指定分区名。动态分区:根据查询语句自动生成的分区名 https://blog.csdn.net/weixin_34104341/article/details/89795410 -- 开启动态分区。默认值是true set hive.exec.dynamic.partitiontrue; -- 默认值是strict&#xff0c…

动态存储区、静态存储区、堆和栈的区别

C/c程序经过编译连接后形成的二进制映像文件,这文件包含: 栈,堆,数据段(只读数据段,已经初始化读写数据段,未初始化数据段即BBS)和代码段组成. 1.栈区(stack): 由编译器自动分配释放…

几种加密算法的比较

由于计算机软件的非法复制,通信的泄密、数据安全受到威胁,解密及盗版问题日益严重,甚至引发国际争端,所以在信息安全技术中,加密技术占有不可替代的位置,因此对信息加密技术和加密手段的研究与开发&#xf…