百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

数仓|优化--Hive 表关联数据倾斜

bigegpt 2024-08-16 14:25 2 浏览


当数据量比较大且分布不均匀时,对数据进行JOIN操作很容易造成数据倾斜,因为在JOIN的执行阶段会将JOIN KEY相同的数据分发到同一个task任务上处理,如果某个key上的数据量比较多,会导致该task执行的时间比其他的task执行时间长。

具体表现为:大部分的task任务都已经执行完成,但只有少数的几个task一直处于运行当中。


维表JOIN

当JOIN的维表数据量较小时(可以通过参数配置不超过多大),可以使用map端join,避免分发引起数据倾斜。

空值

当JOIN的两个表数据量都很大,且数据倾斜是有空key造成的,可以将空key处理成随机值,避免分发到同一个task。

热点KEY

当JOIN的两个表的数据量都很大,且是有热点key导致的数据倾斜(某个key对应的数据量非常大),可以将热点key与非热点key分别处理,再合并数据即可。

比如电商网站在大促时期,某些店铺的PV远远大于普通店铺的PV,某些热门商品的PV也远远大于一些长尾商品的PV,这个时候如果进行维表的JOIN,很容易导致数据倾斜。


map端JOIN

Join倾斜时,如果某路输入比较小,可以采用Mapjoin避免倾斜。Mapjoin的原理是将Join操作提前到Map端执行,这样可以避免因为分发Key不均匀导致数据倾斜。但是Mapjoin的使用有限制,必须是Join中的从表比较小才可用。所谓从表,即Left Outer Join中的右表,或者Right Outer Join中的左表。

map端join适用于当一张表很小(可以存在内存中)的情况,即可以将小表加载至内存。Hive从0.7开始支持自动转为map端join,具体配置如下:

SET hive.auto.convert.join=true; -- hivev0.11.0之后默认true
SET hive.mapjoin.smalltable.filesize=600000000; -- 默认 25m
SET hive.auto.convert.join.noconditionaltask=true; -- 默认true
SET hive.auto.convert.join.noconditionaltask.size=10000000; -- 加载到内存的表大小

一旦开启map端join配置,Hive会自动检查小表是否大于hive.mapjoin.smalltable.filesize配置的大小,如果大于则转为普通的join,如果小于则转为map端join。

关于map端join的原理,如下图所示:


首先,Task A(客户端本地执行的task)负责读取小表a,并将其转成一个HashTable的数据结构,写入到本地文件,之后将其加载至分布式缓存。然后,Task B任务会启动map任务读取大表b,在Map阶段,根据每条记录与分布式缓存中的a表对应的hashtable关联,并输出结果。

注意:map端join没有reduce任务,所以map直接输出结果,即有多少个map任务就会产生多少个结果文件。

空值数据倾斜

如果是因为空值导致数据倾斜,且JOIN的两张表数据量都很大,此时无法使用Mapjoin,可以将空值处理成随机值。因为空值是无法关联上,只是分发到了一处,因此给予随机值即不会影响关联也能避免聚集。当然我们也可以提前对空值进行过滤。

SELECT .. .

FROM (SELECT * FROM tbl1 WHERE ds = '${cur_date}') a

LEFT OUTER JOIN (SELECT * FROM tbl1 WHERE ds = '${cur_date}') b

ON coalesce(a.id, rand() * 9999) = b.id -- 通过coalesce对空值进行随机分发,避免聚集

count distinct倾斜

场景

特殊值过多,常见于固定的特殊值比较多的场景,和join中易产生倾斜的key类似。

  • 解决方案

先过滤特殊值,在count结果的基础上加上特殊值的个数。或根据具体场景进行具体分析。



热点Key数据倾斜

假设有下面两张表,一张事实表,一张维表:

  • 事实表:fact_tbl
    • 数据量:100MB
    • 其中一个字段名是:code_id
    • 99MB的数据对应的code_id为100
    • 只有1MB的数据对应的code_id是均匀分布的
  • 维表:dim_tbl
    • 数据比较大,不能进行Map端join
    • code_id可以唯一约束一条记录

如果将上面两个表进行join:

SELECT *
FROM fact_tbl f
LEFT JOIN dim_tbl d
ON f.code_id = d.code_id

我们会注意到99%的reduce任务会快速运行结束,但是会有一个reduce任务运行的时间特别长(因为code_id=100对应的了99MB的数据),这也就是上面提到的数据倾斜。

解决方案

SkewJoin Hint可以通过自动或手动方式获取两张表的热点key,分别计算热点数据和非热点数据的Join结果并合并,加快Join的执行速度。

我们可以通过配置Skew Join 优化,如下:

set hive.optimize.skewjoin=true;
set hive.skewjoin.key=500000;
set hive.skewjoin.mapjoin.map.tasks=10000;
set hive.skewjoin.mapjoin.min.split=33554432;

  • hive.optimize.skewjoin

是否开启skew join优化,当开启参数时,在进行查询的时候会识别数据倾斜的key,首先将这些key存储在HDFS的临时文件上,在接下来的map-reduce过程中,再去处理这些数据倾斜的key(启动map端join专门计算这个特殊值)

  • hive.skewjoin.key

告诉hive这个join的skew key是什么,即如何判断哪个key是数据倾斜的key。根据该参数的配置值,比如默认100000,那么就认为超过100000条记录的值就是数据倾斜的key。

Skew Join的具体过程如下图所示:


大致的步骤为:现将引起数据倾斜的key分别写入到HDFS的临时文件中,如上图的HDFS File a-K1HDFS File b-K1,对倾斜key的数据执行map端join;对其他分布均匀的key正常执行join任务,最后将两份join的数据进行合并。

相关推荐

了解Linux目录,那你就了解了一半的Linux系统

大到公司或者社群再小到个人要利用Linux来开发产品的人实在是多如牛毛,每个人都用自己的标准来配置文件或者设置目录,那么未来的Linux则就是一团乱麻,也对管理造成许多麻烦。后来,就有所谓的FHS(F...

Linux命令,这些操作要注意!(linux命令?)

刚玩Linux的人总觉得自己在演黑客电影,直到手滑输错命令把公司服务器删库,这才发现命令行根本不是随便乱用的,而是“生死簿”。今天直接上干货,告诉你哪些命令用好了封神!喜欢的一键三连,谢谢观众老爷!!...

Linux 命令速查手册:这 30 个高频指令,拯救 90% 的运维小白!

在Linux系统的世界里,命令行是强大的武器。对于运维小白而言,掌握一些高频使用的Linux命令,能极大提升工作效率,轻松应对各种系统管理任务。今天,就为大家奉上精心整理的30个Linu...

linux必学的60个命令(linux必学的20个命令)

以下是Linux必学的20个基础命令:1.cd:切换目录2.ls:列出文件和目录3.mkdir:创建目录4.rm:删除文件或目录5.cp:复制文件或目录6.mv:移动/重命名文件或目录7....

提高工作效率的--Linux常用命令,能够决解95%以上的问题

点击上方关注,第一时间接受干货转发,点赞,收藏,不如一次关注评论区第一条注意查看回复:Linux命令获取linux常用命令大全pdf+Linux命令行大全pdf为什么要学习Linux命令?1、因为Li...

15 个实用 Linux 命令(linux命令用法及举例)

Linux命令行是系统管理员、开发者和技术爱好者的强大工具。掌握实用命令不仅能提高效率,还能解锁Linux系统的无限潜力,本文将深入介绍15个实用Linux命令。ls-列出目录内容l...

Linux 常用命令集合(linux常用命令全集)

系统信息arch显示机器的处理器架构(1)uname-m显示机器的处理器架构(2)uname-r显示正在使用的内核版本dmidecode-q显示硬件系统部件-(SMBIOS/DM...

Linux的常用命令就是记不住,怎么办?

1.帮助命令1.1help命令#语法格式:命令--help#作用:查看某个命令的帮助信息#示例:#ls--help查看ls命令的帮助信息#netst...

Linux常用文件操作命令(linux常用文件操作命令有哪些)

ls命令在Linux维护工作中,经常使用ls这个命令,这是最基本的命令,来写几条常用的ls命令。先来查看一下使用的ls版本#ls--versionls(GNUcoreutils)8.4...

Linux 常用命令(linux常用命令)

日志排查类操作命令查看日志cat/var/log/messages、tail-fxxx.log搜索关键词grep"error"xxx.log多条件过滤`grep-E&#...

简单粗暴收藏版:Linux常用命令大汇总

号主:老杨丨11年资深网络工程师,更多网工提升干货,请关注公众号:网络工程师俱乐部下午好,我的网工朋友在Linux系统中,命令行界面(CLI)是管理员和开发人员最常用的工具之一。通过命令行,用户可...

「Linux」linux常用基本命令(linux常用基本命令和用法)

Linux中许多常用命令是必须掌握的,这里将我学linux入门时学的一些常用的基本命令分享给大家一下,希望可以帮助你们。总结送免费学习资料(包含视频、技术学习路线图谱、文档等)1、显示日期的指令:d...

Linux的常用命令就是记不住,怎么办?于是推出了这套教程

1.帮助命令1.1help命令#语法格式:命令--help#作用:查看某个命令的帮助信息#示例:#ls--help查看ls命令的帮助信息#netst...

Linux的30个常用命令汇总,运维大神必掌握技能!

以下是Linux系统中最常用的30个命令,精简版覆盖日常操作核心需求,适合快速掌握:一、文件/目录操作1.`ls`-列出目录内容`ls-l`(详细信息)|`ls-a`(显示隐藏文件)...

Linux/Unix 系统中非常常用的命令

Linux/Unix系统中非常常用的命令,它们是进行文件操作、文本处理、权限管理等任务的基础。下面是对这些命令的简要说明:**文件操作类:*****`ls`(list):**列出目录内容,显...