【大数据之Hive】二十三、HQL语法优化之数据倾斜

news2025/2/22 13:03:45

1 数据倾斜概述

  数据倾斜指参与计算的数据分布不均,即某个key或者某些key的数据量远超其他key,导致在shuffle阶段,大量相同key的数据被发往同一个Reduce,导致该Reduce所需的时间远超其他Reduce,成为整个任务的瓶颈。
  Hive中的数据倾斜常出现在分组聚合和join操作的场景中 。

2 分组聚合导致的数据倾斜

2.1 优化说明

  Hive中未经优化的分组聚合,是通过一个MapReduce Job实现的。Map端负责读取数据,并按照分组字段分区,通过Shuffle,将数据发往Reduce端,各组数据在Reduce端完成最终的聚合运算。
  如果group by分组字段的值分布不均,就可能导致大量相同的key进入同一Reduce,从而导致数据倾斜问题。

解决思路:
Map-Site聚合和Skew-GroupBy优化。

1、Map-Side聚合

  开启Map-Side聚合后,数据会现在Map端完成部分聚合工作(可以看作大小一样的切片,相当于先完成切片内的聚合工作)。

  即便原始数据是倾斜的,经过Map端的初步聚合后,发往Reduce的数据也就不再倾斜了。最佳状态下,Map-端聚合能完全屏蔽数据倾斜问题。

相关参数:

--启用map-side聚合
set hive.map.aggr=true;

--用于检测源表数据是否适合进行map-side聚合。检测的方法是:
--先对若干条数据进行map-side聚合,若聚合后的条数和聚合前的条数比值小于该值,
--则认为该表适合进行map-side聚合;否则,认为该表数据不适合进行map-side聚合,
--后续数据便不再进行map-side聚合。
set hive.map.aggr.hash.min.reduction=0.5;

--用于检测源表是否适合map-side聚合的条数。
set hive.groupby.mapaggr.checkinterval=100000;

--map-side聚合所用的hash table,占用map task堆内存的最大比例,
--若超出该值,则会对hash table进行一次flush。
set hive.map.aggr.hash.force.flush.memory.threshold=0.9;

2、Skew-GroupBy优化

  Skew-GroupBy专门用于处理由于group by导致数据倾斜的方案。

原理:
  启动两个MR任务,第一个MR按照随机数分区,将数据分散发送到Reduce,完成部分聚合;
  第二个MR读取第一个Reduce端的数据按照分组字段分区,完成最终聚合。

相关参数:

--启用分组聚合数据倾斜优化
set hive.groupby.skewindata=true;

2.2 案例

1、示例SQL语句

select
    province_id,
    count(*)
from order_detail
group by province_id;

2、优化前
  表中的province_id字段是存在倾斜的,若不经过优化,通过观察yarn中reduce任务的执行过程,是能够看出数据倾斜现象的。
  hive中的map-side聚合是默认开启的,若想看到数据倾斜的现象,需要先将hive.map.aggr参数设置为false。
3、优化思路
(1)Map-Side聚合
设置参数:

--启用map-side聚合
set hive.map.aggr=true;
--关闭skew-groupby
set hive.groupby.skewindata=false;

执行计划:
在这里插入图片描述
  观察yarn中reduce任务的执行过程,很明显可以看到开启map-side聚合后,reduce数据不再倾斜。
(2)Skew-GroupBy优化
设置参数:

--启用skew-groupby
set hive.groupby.skewindata=true;
--关闭map-side聚合
set hive.map.aggr=false;

  开启Skew-GroupBy优化后,可以很明显看到该sql执行在yarn上启动了两个mr任务,第一个mr打散数据,第二个mr按照打散后的数据进行分组聚合。
在这里插入图片描述

2.3 总结

  Map-site优化优于Skew-GroupBy优化,能做Map-site聚合就做Map-site聚合。

  Map-site聚合要在Map端维护一个HashTable,HashTable消耗了内存,即内存不充足的情况下尽量不做Map-site聚合,但也可以做,当HashTable超过设定的内存阈值时,会flush刷新。

  当内存很小时会flush很多次导致map端聚合没有解决数据倾斜问题,此时可以用Skew-GroupBy聚合。也就是不管内存足部足够都能把数据打散再做聚合。

3 Join导致的数据倾斜

3.1 优化说明

  未经优化的join操作,默认是使用common join算法,也就是通过一个MapReduce Job完成计算。Map端负责读取join操作所需表的数据,并按照关联字段进行分区,通过Shuffle,将其发送到Reduce端,相同key的数据在Reduce端完成最终的Join操作。

  如果关联字段的值分布不均,就可能导致大量相同的key进入同一Reduce,从而导致数据倾斜问题。

  由join导致的数据倾斜问题,有如下三种解决方案:map join、skew join、调整SQL语句。

1、map join

  map join中join操作仅在map端就能完成,没有shuffle操作,没有reduce阶段,自然不会产生reduce端的数据倾斜。该方案适用于大表join小表时发生数据倾斜的场景。

原理:
  多个Mapper缓存小表数据,大表数据进行切片(切片只与大小有关,与key无关),均匀切成若干个片,一个map负责处理一个切片(逐条遍历然后找缓存的小表的数据join)再逐条输出,使得每个map处理的数据量一致,解决数据倾斜问题。

相关参数:

--启动Map Join自动转换
set hive.auto.convert.join=true;

--一个Common Join operator转为Map Join operator的判断条件,
--若该Common Join相关的表中,存在n-1张表的大小总和<=该值,则生成一个Map Join计划,
--此时可能存在多种n-1张表的组合均满足该条件,则hive会为每种满足条件的组合均生成一个Map Join计划,
--同时还会保留原有的Common Join计划作为后备(back up)计划,实际运行时,
--优先执行Map Join计划,若不能执行成功,则启动Common Join后备计划。
set hive.mapjoin.smalltable.filesize=250000;

--开启无条件转Map Join
set hive.auto.convert.join.noconditionaltask=true;

--无条件转Map Join时的小表之和阈值,若一个Common Join operator相关的表中
--存在n-1张表的大小总和<=该值,此时hive便不会再为每种n-1张表的组合均生成Map Join计划,
--同时也不会保留Common Join作为后备计划。而是只生成一个最优的Map Join计划。
set hive.auto.convert.join.noconditionaltask.size=10000000;

2、skew join

  skew join解决大表join大表出现数据倾斜的问题。

原理:
  为倾斜的大key单独启动一个map join任务进行计算,其余key进行正常的common join。
在这里插入图片描述
相关参数:

--启用skew join优化
sethive.optimize.skewjoin=true;
--触发skew join的阈值,若某个key的行数超过该参数值,则触发(按照行数进行检测)
set hive.skewjoin.key=100000;

  这种方案对参与join的源表大小没有要求,但是对两表中倾斜的key的数据量有要求,要求一张表中的倾斜key的数据量比较小(方便走mapjoin)。

3、调整SQL语句

  若参与join的两表均为大表,其中一张表的数据是倾斜的,可以对SQL语句进行相应的调整。
  假设原始SQL语句如下:A,B两表均为大表,且其中一张表的数据是倾斜的。

select
    *
from A
join B
on A.id=B.id;

在这里插入图片描述
  图中1001为倾斜的大key,被发往了同一个Reduce进行处理。

调整SQL语句如下:

select
    *
from(
    select --打散操作,加随机数0、1
        concat(id,'_',cast(rand()*2 as int)) id,
        value
    from A
)ta
join(
    select --扩容操作
        concat(id,'_',0) id,
        value
    from B
    union all
    select
        concat(id,'_',1) id,
        value
    from B
)tb
on ta.id=tb.id;

调整之后的SQL语句执行计划:
在这里插入图片描述

3.2 案例

1、示例SQL语句

select
    *
from order_detail od
join province_info pi
on od.province_id=pi.id;

2、优化前

--关闭Map Join自动转换
set hive.auto.convert.join=false;

--关闭skew join优化(默认为关闭状态)
sethive.optimize.skewjoin=false;

  order_detail表中的province_id字段是存在倾斜的,若不经过优化,观察yarn中的reduce任务可以看到数据倾斜的现象。
  hive中的map join自动转换是默认开启的,若想看到数据倾斜的现象,需要先将hive.auto.convert.join参数设置为false。
3、优化思路
(1)map join
设置参数:

--启用map join
set hive.auto.convert.join=true;
--关闭skew join
set hive.optimize.skewjoin=false;

  可以很明显看到开启map join以后,mr任务只有map阶段,没有reduce阶段,没有数据倾斜发生。
在这里插入图片描述
在这里插入图片描述
(2)skew join
设置参数:

--启动skew join
set hive.optimize.skewjoin=true;
--关闭map join
set hive.auto.convert.join=false;

开启skew join后,使用explain查看执行计划:
在这里插入图片描述
  skew join生效,任务既有common join,又有部分key走了map join。并且该sql在yarn上最终启动了两个mr任务,而且第二个任务只有map没有reduce阶段,说明第二个任务是对倾斜的key进行了map join。
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/754052.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

System.InvalidOperationException:对象当前正在其他地方使用

System.InvalidOperationException:对象当前正在其他地方使用 出现此情况&#xff0c;一般是对象被多个线程同时使用了 解决办法就是同一时间只允许单线程访问目标对象&#xff1b;

面试上海某小厂Java岗,全程一小时问的全是细节

之前分享很多大厂的面经&#xff0c;这次分享一家上海某小厂的 Java 岗位面试&#xff0c;面试的时间也挺长的&#xff0c;接近 1 个小时&#xff0c;无算法&#xff0c;全程抓着项目mysqlredisjava这 4 个方向问。 问题记录 项目 介绍你的项目 这个项目是企业里面做的还是学…

Redis数据结构 — Listpack

目录 listpack 结构 listpack 节点结构 quicklist 虽然通过控制 quicklistNode 结构里的压缩列表的大小或者元素个数&#xff0c;来减少连锁更新带来的性能影响&#xff0c;但是并没有完全解决连锁更新的问题。 于是&#xff0c;Redis 在 5.0 新设计一个数据结构叫 listpack…

助力环保问题检测,基于YOLOv5全系列模型【n/s/m/l/x】开发构建不同量级裸土检测识别模型,对比实验分析检测性能

道路裸土扬尘问题是城市环境中常见的环境污染问题之一。在以往的一些项目中也有实际接触到过类似的检测识别需求&#xff0c;本文的主要目的是单纯地从实验分析的角度来对比裸土这一数据场景下不同量级参数模型的实际性能。 首先看下整体效果&#xff1a; 接下来简单看下数据集…

uniapp微信小程序使用axios(vue3+axios+ts版)

版本号 "vue": "^3.2.45", "axios": "^1.4.0", "axios-miniprogram-adapter": "^0.3.5", 安装axios及axios适配器&#xff0c;适配小程序 yarn add axios axios-miniprogram-adapter 使用axios 在utils创建utils/…

ES6新特性基础总结

目录 简介 node.js安装 babel转码器 let命令 const命令 解构对象 字符串扩展 新增方法&#xff1a; 数组扩展 扩展运算符 伪数组 对象扩展 属性的简介表示法 属性名表达式 对象的扩展运算符 函数扩展 箭头函数 使用注意 Set数据结构 基本用法 size属性 特有方法 P…

【数据结构常见七大排序(二)】—选择排序篇【直接选择排序】And【堆排序】

目录 前言 1.直接选择排序 1.1基本思想 1.2直接选择排序实现过程 1.3动图助解 1.4直接选择排序源码 2.堆排序 2.1堆排序的概念 2.2堆排序源码 前言 选择排序有两种常见的【直接选择排序】、【堆排序】 1.直接选择排序 1.1基本思想 每一次从待排序的数据元素中选出最…

Kafka 入门到起飞 - 核心概念(术语解释)

在kafka之旅&#xff0c;我们会大量讨论Kafka中的术语&#xff0c;那么就让我们先来了解一下这些核心概念 消息(Message)&#xff1a; kafka的数据单元称为消息&#xff0c;相当于DB里的一行数据或一条记录 消息由字节数组组成 批次&#xff1a; 生产者组一批数据再向kafka推送…

短视频seo矩阵源码开发与实践分享

在短视频矩阵系统源码开发中&#xff0c;需要注意以下几个细节&#xff1a; 1. 确定系统的功能需求&#xff1a;在开发短视频矩阵系统源码时&#xff0c;必须先明确系统的功能需求&#xff0c;包括用户的基本操作、系统数据的生成和处理等。 2. 定义数据库结构&#xff1a;短…

提高开发效率!5个对开发者有用的Kotlin扩展函数

本文已同步发表于我的微信公众号&#xff0c;搜索 代码说 即可关注&#xff0c;欢迎与我沟通交流。 文章目录 runCatching代替try catchView的可见性dp、sp、px之间相互转换by lazy 替代findViewByIdToast、Log Kotlin 中扩展函数是一种允许在已有的类中添加新函数&#xff0c;…

Day52| 300.最长递增子序列 、 674. 最长连续递增序列 、718. 最长重复子数组

300.最长递增子序列 1.题目&#xff1a; 给你一个整数数组 nums &#xff0c;找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列&#xff0c;删除&#xff08;或不删除&#xff09;数组中的元素而不改变其余元素的顺序。例如&#xff0c;[3,6,2,7] 是数组 …

从编写metadata.yaml到测试processor文件成功

检查模型和客户端&#xff08; Excel 原型图&#xff09;字段是否对应 修改 applications\commands\metadata\cai_liao_ she_bei_metadata.yaml 文件 wen_jian_db_conf 下的 all 下的 content_field_name 选项&#xff0c;要根据 model 中写的文件路径找到对应的 model&#x…

论文阅读—2023.7.13:遥感图像语义分割空间全局上下文信息网络(主要为unet网络以及改unet)附加个人理解与代码解析

前期看的文章大部分都是深度学习原理含量多一点&#xff0c;一直在纠结怎么改模型&#xff0c;论文看的很吃力&#xff0c;看一篇忘一篇&#xff0c;总感觉摸不到方向。想到自己是遥感专业&#xff0c;所以还是回归遥感影像去谈深度学习&#xff0c;回归问题&#xff0c;再想着…

resultType和parameterType的基本使用和区别

我们在使用Mybatis的过程中不难发现Mapper文件中的select,insert,update,delect操作中都有一个parameterType 或 resultType属性。 resultType&#xff1a;返回值类型&#xff0c;类型即为对象类型&#xff0c;返回结果字段与对象属性匹配映射&#xff0c;类型中的属性名要与查…

数学建模-假设检验

原假设&#xff0c;备择假设P值&#xff0c;显著性水平单侧建议&#xff0c;双侧检验

IPUU的小工具拍了拍你(上)

IPUU是埃文科技旗下的综合性IP查询网站&#xff0c;提供多维度的IP数据信息。通过在线查询&#xff0c;用户可以获取目标IP地址的详尽信息&#xff0c;包括位置属性、网络属性、风险属性以及业务属性等&#xff0c;同时还可以查询域名信息。无论您是需要查看某个IP地址归属地&a…

VBA技术资料1-120

MF系列VBA技术资料 为了让广大学员在实际VBA编程中有切实可行的思路及有效的提高自己的编程技巧&#xff0c;我参考大量的资料&#xff0c;并结合自己的经验总结了这份MF系列VBA技术综合资料&#xff0c;而且开放源码&#xff08;MF04除外&#xff09;&#xff0c;其中MF01-04属…

一篇文章让你搞懂内存函数

内存操作函数 memcpy 库函数memcmp介绍 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。 这个函数在遇到 ‘\0’ 的时候并不会停下来。 如果source和destination有任何的重叠&#xff0c;复制的结果都是未定义的。 库函数memcmp的代码形式 v…

Ubuntu使用Samba设置共享文件夹提示“拒绝访问”的解决办法一

问题&#xff1a;看图片 IP正确&#xff0c;用户名也对。 解决&#xff1a;重新设置密码 sudo smbpasswd -a topeet 添加成功

详解CAS算法

CAS的全称是 Compare And Swap&#xff08;比较并交换&#xff09;&#xff0c;它是并发编程中的一个重要概念。本文结合Java的多线程操作来讲解CAS算法。 CAS算法的优势是可以在不加锁的情况下保证线程安全&#xff0c;从而减少线程之间的竞争和开销。 目录 一、CAS算法的内…