首页 > 其他分享 >数据倾斜问题

数据倾斜问题

时间:2023-08-20 15:11:41浏览次数:37  
标签:task join Suffle 问题 key 倾斜 数据

数据倾斜的简介

数据倾斜即单个节点任务处理的数据量远高于同类型任务处理的数据量,成为整个作业的性能瓶颈。

本文将从产生数据倾斜的原因、不同计算引擎下的解决方法讨论。

数据倾斜的场景和对应的解决方案

Suffle过程

数据倾斜和Suffle过程是密不可分的,Suffle过程在MR和Spark中大体思想上是相差不大的,下面以Spark1.2以前的HashSuffle来简单描述一下。

Shuffle过程可以分为Suffle Write阶段和Suffle Read阶段。如下图所示。

以上哪些场景会出现数据倾斜呢?如下所示

主要可以分为Suffle Write阶段的数据倾斜和Suffle Read阶段的数据倾斜

Suffle Write阶段的数据倾斜

当write阶段的某一个task处理的数据特别多,就会导致该task成为瓶颈;那为什么这个task会处理相比于其他task多那么多的数据呢?所以需要看到源头。

不管是MR还是Spark,在输入数据的时候都会进行切片,当HDFS中某个文件非常大且压缩后不可切分的话,这个文件就只会由一个task进行处理,因此会导致这个task处理数据量相比于同类型任务非常大(如果是每个task的数据量都很大,就需要考虑切片数量的问题,在MR中可以通过调maxSize,在Sprak中可以调整average_size(total_size/minPartition))。解决方案是将文件改为可切分的压缩格式,如bzip2,Zip。

Suffle Read阶段的数据倾斜

这阶段的数据倾斜本质上就是因为数据中含有大量相同key,相同key通过hash code取模后会进入相同的分区导致某个task的处理数量量非常大。

同时,这种情景还可以分单key导致的倾斜和多key导致的倾斜;多key指的是单个key在一个task中可能可以接受,但是由于分区规则,导致多个中等大小的key都分到了一个task,这样这个task的任务依旧很重。单key指的是单个key它的数据量就非常大了。

减少Suffle或去除Suffle

不管哪种场景,首先考虑的是能不能减少Suffle甚至不要Suffle。就算不会数据倾斜,Suffle也是性能瓶颈的重要因素。

一个典型的场景就是大表join小表,通过将小表发给大表的task,直接在Map端进行join,从而避免Suffle过程。下面也从Hive和Spark分别说以下具体的措施。

Hive处理的大表join小表

Hive 处理就是将Repartition Join转为common mapJoin

common mapJoin的原理:MapJoin是先启动一个作业,读取小表的数据,在内存中构建哈希表,将哈希表写入本地磁盘,然后将哈希表上传到HDFS并添加到分布式缓存中。再启动一个任务读取B表的数据,在进行连接时Map会获取缓存中的数据并存入到哈希表中,B表会与哈希表的数据进行匹配,时间复杂度是O(1),匹配完后会将结果进行输出。具体可以看:https://blog.csdn.net/xiaozhaoshigedasb/article/details/105245698

使用common mapjoin有两种方式:一、使用MapJoin的hint语法;二、使用Hive配置MapJoin。

一、在实际生产环境中,不建议使用hint语法;因为如果小表的数据量在业务过程中激增,那hint关键字会强制进行mapJoin,最坏的情况会导致OOM。

二、使用Hive配置需要以下几项:

  • hive.auto.convert.join:在Hive0.11后,默认为true;
  • hive.smalltable.filesize:默认是25000000bytes;当小表小于这个值,会自动将repartition Join转为common map join。
Spark处理的大表join小表

思想是一样的,不过common map join在Spark中是Broadcast Join,就是将小表广播出去,让大表join。

我们可以在Spark Core中自己写代码广播小表,而在Spark SQL中可以更方便做这件事。

Spark SQL会自动检查数据量大小,把小的数据量广播出去。它会认为表的数据量小于spark.sql.autoBroadcastJoinThreshold=10M,就是小表。当然我们可以自己配置这个值。而Spark SQL获取表大小的信息是从metastore获取的,如果极端情况下metastore数据出错了,小表数据量实际很大,那么会导致广播后OOM;所以也可以配置spark.sql.statistics.fallBackToHdfs=true,从HDFS计算表大小。

Suffle不可避免

对于这种情景,我认为有一定的处理流程,

排查业务数据问题 ---> 倾斜key的判断 ---> 针对性措施

排查业务数据问题
  • 过滤大量无意义数据:如果数据存在大量业务含义是无意义的,例如空值或者空字符串,那么可以先将这些值过滤掉,Hive中where,Spark中filter这类措施。
  • 不能过滤的异常数据:在不影响其他指标的情况下,用随机数填充。
倾斜key的判断

判断的基本思路是通过对数据集进行抽样,了解key的大概情况。Hive的抽样函数,Spark的sample算子。

多次抽样后可以大致得到倾斜的key是哪个。

针对性措施
  1. 如果是多key导致的数据倾斜,可以尝试调整并行度,有一点的缺点就是,并行度只能凭感觉给,不过最好不要是之前并行度的倍数。
  2. 将相同key分散开来,分为两阶段聚合;具体做法是,在造成倾斜的key后面加一个随机数,先进行一次聚合,然后再去掉加上的随机数,再进行一次聚合。

情景:大表join大表发生数据倾斜

两个大表连接,如果连接键存在倾斜,必定会引发数据倾斜。此时的解决思路可以是如下:假设存在大表A和B,可以先对两表正常的key过滤出来join;而倾斜key则单独处理,将表A的key进行定制化加盐(假设在key后加一个1-20的随机数),对于表B的key进行定制化扩容(每一个key都新增1-20数的记录,相当于扩容20倍),然后进行一阶段join,然后再把随机数抹除掉,进行全局join。最后把正常key和倾斜key的结果union起来。

标签:task,join,Suffle,问题,key,倾斜,数据
From: https://www.cnblogs.com/nangk/p/17644020.html

相关文章

  • C语言的缺陷/错误处理问题探讨
    最近遇到一个问题,先看看如下代码:uint8_tBcd2Dec01(uint8_tbcd){ uint8_tone=(bcd&0x0F); uint8_tten=(bcd&0xF0)>>4; if((one>9)||(ten>9)) { printf("请输入合法的BCD码!"); return0; } returnone+(ten*10);}这是一个将单字节bcd......
  • vuepress 安装报错问题
    关于vuepress部署出现样式的问题及解决6月前作者:我yi癫狂分类: 博客文章阅读(35)原文违法举报 目录vuepress部署出现样式问题vuepress个人博客部署遇到的一些问题1、js和css出现404问题2、每次都要重复操作打包、运行、上传github很麻烦怎么办?3、github.io无法打开怎......
  • SpringBoot使用jasypt实现数据库配置加密
    我们在日常使用中有需要加密设置数据库连接配置的情况,我们可以使用第三方的依赖jasypt来实现我们的数据库配置加密,从而提高系统的安全性。一、引入jasypt依赖<!--jasypt--><dependency> <groupId>com.github.ulisesbocchio</groupId> <artifactId>jasypt-spring-boot-starter</......
  • 拥抱数据变革:知识引导的机器学习
    机器学习(ML)在大规模数据可用的许多应用中的成功,导致了人们对科学学科中类似成就的期望越来越高。数据科学的使用在涉及尚未完全理解的过程的科学问题中尤其有希望。然而,纯粹用数据驱动的方法来建模物理过程可能会有问题。例如,它可以创建一个复杂的模型,它既不能超越训练它的数据,......
  • Centos安装MySQL数据库
    写在前面本文使用的root账户进行操作,若不是root账户需要在操作前加上sudo大家一定要注意数据库安全问题啊......
  • COMP2401A Pokemon 问题
    COMP2401A–Assignment5PrerequisitesPleasereviewthelecturesuptoandincludingModule15–Scripting.DownloadthecsvfilecontainingPokemondescriptions.LearningObjectives•Convertasetofrequirementsintotheprogramdesignandimplementrunnin......
  • 考研数据结构——每日一题[希尔排序]
    shell_sort希尔排序//每组内的下标是等差数列//c++中的sort是快排+插排【当排序到<28时改为插入排序】voidshell_sort()//希尔排序【分组的插入排序】不稳定(间隔d的分为一组){for(intd=n/3;d;d=d==2?1:d/3)//特判2,等于2就用1,(最后要用1,而2时d/3=......
  • 基础入门-算法分析&传输加密&数据格式&密文存储&代码混淆&逆向保护
    基础入门-算法分析&传输加密&数据格式&密文存储&代码混淆&逆向保护基础入门-算法分析&传输加密&数据格式&密文存储&代码混淆&逆向保护传输数据-编码型&加密型等传输格式-常规&JSON&XML等密码存储-Web&系统&三方应用代码混淆-源代码加密&逆向保护加密:1.常见加密编码进制等算法解......
  • TiDB dumpling 导出MySQL 数据遇异常
    最近在学习研究TiDB数据库运维,据介绍逻辑导出工具dumpling是可以兼容MySQL数据库的,于是进行了测试数据库版本信息如下: 新建了两张表t1,t2: 利用存储过程批量插入500000行记录:dropPROCEDUREp_load2;delimiter$$createPROCEDUREp_load2(INtbnamevarchar(64),IN......
  • Sql Server数据库自身优化
    优化①:增加次数据文件,设置文件自动增长(粗略数据分区)  1.1:增加次数据文件从SQLSERVER2005开始,数据库不默认生成NDF数据文件,一般情况下有一个主数据文件(MDF)就够了,但是有些大型的数据库,由于信息很多,而且查询频繁,所以为了提高查询速度,可以把一些表或者一些表中的部分记录......