兼顾性能的数据倾斜处理方案

目录

前言

一、场景描述

二、常见的优化方法

2.1 Mapjoin

2.2 特殊值/空值打散

2.3 热点值打散,副表呈倍数扩散

2.4 热点数据单独处理/SkewJoin

2.5 方案总结

三、Distmapjoin

3.1 核心思路

3.2 代码实现

3.3 真实效果

四、方案总结

   文章主要是介绍在支付宝支付数据链路改造升级过程中,针对数据倾斜的优化实践方案,在解决数据倾斜问题的同时,还能兼顾更优的计算性能。

一、场景描述

  数据倾斜可能发生在join,group by,count distinct等环节,但本质上其实都类似,即因为数据重分发或重分布等原因,导致大部分数据仅分发到少数几个计算节点上。以ODPS场景为例,少数几个Fuxi Instance处理的数据量,远大于同一环节的其他Instance处理的数据量,并伴有明显的长尾现象。

  典型的案例是在淘宝双十一场景中,交易订单明细大表需要关联商家信息维表以补全商家信息,在数据关联处理中,同一个商家对应的交易订单个维表对应商家信息,将根据卖家ID shuffle至同一个数据处理节点上。由于TOP商家在大促中产生的交易单量远大于普通商家, 从而导致大量的数据集中到一台或者几台机器上计算,这些数据的计算速度将远远低于平均计算速度,导致整个计算过程被拖慢。

  如上图所示,数据重分发过程中,按照Join Key(即卖家ID)进行shuffle,大部分交易数据记录分发至处理节点1,导致三个并发处理节点中,处理节点1需要处理的数据量远大于其他两个处理节点,从而造成数据处理的不均匀,即数据倾斜。

二、常见的优化方法

2.1 Mapjoin

  实现原理是:通过把小表广播到大表所在计算节点上,有效避免了大表的shuffle,因而避免了数据重分布导致的数据倾斜。若大表数据的原始分布本身就有不均匀的情况,此时也可以通过增加随机重分布的临时打散方式,将数据打的散一些,再通过Mapjoin实现数据关联。

SELECT /*+MAPJOIN(dim)*/  * 
FROM (SELECT * FROM dwd_tbl) base 
LEFT OUTER JOIN (SELECT * FROM dim_tbl) dim
ON base.dim_key = dim.dim_key

2.2 特殊值/空值打散

  • 特殊值/空值场景也比较普遍,比如主表中有个属性字段在某些场景下为空或者为一些无业务含义的特殊字符串(如DEFAULT),然后此属性字段本身对应了一张数据量较大的维表,需要关联打宽补全。此时做数据关联,由于两张表按照关联key进行shuffle,就会导致主表中该字段为空/相同特殊字符串的数据记录shuffle到同一个节点上,从而导致数据倾斜。
  • 此类场景好解决,对特殊值/空值在关联时转为随机值就行。
SELECT * 
FROM (SELECT * FROM dwd_tbl) base 
LEFT JOIN (SELECT * FROM dim_tbl) dim
ON IF(COALESCE(base.dim_key,'')='',CONCAT('HIVE_',RAND()),base.dim_key) = dim.dim_key

2.3 热点值打散,副表呈倍数扩散

  • 此类方法使用较少,实现原理是对主表附加一个随机值(例如1~10)字段,记为ext_a字段,然后对应被关联维表数据按照对应倍数进行复制膨胀,并依次赋予1~10的编号,记为ext_b字段,然后在关联两张表时把ext_a、ext_b两个字段也作为关联字段之一。
  • 此方法适用于被关联表远远比主表小,但又因数据大小超过内存容量而无法使用Mapjoin,且主表的数据倾斜程度不大的情况下可以使用,但整体上此方案只能对数据热点成倍数的削弱
SELECT * 
FROM (SELECT *,CAST(RAND()*10 AS BIGINT) AS ext_aFROM dwd_tbl--主表dwd_tbl
) base 
LEFT JOIN (SELECT *FROM dim_tbl--被关联表 dim_tblLATERAL VIEW EXPLODE(SPLIT('0;1;2;3;4;5;6;7;8;9',';')) tt AS ext_b-- 或者Join一个用于倍数膨胀的小表
) dim
ON  base.dim_key = dim.dim_key
AND base.ext_a   = dim.ext_b

2.4 热点数据单独处理/SkewJoin

  • 使用此方法通常也意味着被关联的维表数据大小较大,无法使用Mapjoin,只能走普通shuffle模式的join方案。此类场景最典型的案例就是双十一淘系交易大表去关联商家维表,此时的商家维表因记录数和数据大小都较大,所以无法放入到内存,此外部分商家的交易单量远超大盘平均,此时的数据倾斜就需要使用热点数据单独处理的方案。
  • 将热点数据提取出来单独处理,可以用Mapjoin的方式完成关联维表热点记录行,非热点则使用普通的shuffle模式的join完成关联。
  • 具体操作主要分为三个部分:基于主表统计获得Top热点的属性值:用热点属性值将关联维表拆成热点小表和非热点表,同时也将主表拆成热点主表和非热点主表;热点小表通过Mapjoin与热点主表join,非热点表与非热点主表join,最终两部分再union到一起,完成数据关联。

-- Step01:热点数据记录提取
INSERT OVERWRITE TABLE tmp_hot_list PARTITION (dt = '${bizdate}')
SELECT   dim_shop_id AS hot_id
FROM   main_table
WHERE   dt = '${bizdate}'
GROUP BY dim_shop_id
HAVING COUNT(1) > 10000;INSERT OVERWRITE TABLE final_result_table PARTITION (dt = '${bizdate}')
-- Step02:热点数据处理,使用MapJoin完成处理
SELECT   /*+MAPJOIN(a2,a3)*/ a1.trade_no    AS trade_no,a1.dim_shop_id AS shop_id,a3.shop_name   AS shop_name,a3.shop_type   AS shop_type
FROM (SELECT * FROM main_table WHERE dt = '${bizdate}') a1 -- Step02-1:主表用JOIN关联热点表进行热点记录筛选
JOIN (SELECT * FROM tmp_hot_list WHERE dt = '${bizdate}') a2 -- 热点数据清单
ON a1.dim_shop_id = a2.dim_shop_id
-- Step02-2:热点维度数据处理
LEFT OUTER JOIN (SELECT /*+MAPJOIN(b2)*/ b1.*FROM  (SELECT * FROM dim_table_info WHERE dt = '${bizdate}') b1JOIN  (SELECT * FROM tmp_hot_list   WHERE dt = '${bizdate}') b2 -- 热点数据清单ON    b1.dim_shop_id = b2.dim_shop_id
) a3
ON    a1.dim_shop_id = a3.dim_shop_id
UNION ALL 
-- Step03:非热点数据处理,使用普通Join完成处理,两张表均需要进行Shuffle
SELECT   /*+MAPJOIN(a12)*/ a11.trade_no    AS trade_no,a11.dim_shop_id AS shop_id,a13.shop_name   AS shop_name,a13.shop_type   AS shop_type
FROM (SELECT * FROM main_table WHERE dt = '${bizdate}') a11 
-- Step03-1:主表用ANTI JOIN关联热点表进行剔除
LEFT ANTI JOIN (SELECT * FROM tmp_hot_list WHERE dt = '${bizdate}') a12
ON a11.dim_shop_id = a12.dim_shop_id
-- Step03-2:非热点维度数据处理
LEFT OUTER JOIN (SELECT /*+MAPJOIN(b12)*/ b11.*FROM  (SELECT * FROM dim_table_info WHERE dt = '${bizdate}') b11LEFT ANTI JOIN  (SELECT * FROM tmp_hot_list WHERE dt = '${bizdate}') b12ON    b11.dim_shop_id = b12.dim_shop_id
) a13
ON a11.dim_shop_id = a13.dim_shop_id
  • 整个步骤稍有些复杂,这里也可以直接用平台的skewjoin参数完成倾斜处理, skew的核心思路就是上面提到的热点数据单独处理,只是做了平台级别的集成,方便用户一键解决数据倾斜问题。
INSERT OVERWRITE TABLE final_result_table PARTITION (dt = '${bizdate}')
SELECT  /*+SKEWJOIN(a1)*/ a1.trade_no    AS trade_no,a1.dim_shop_id AS shop_id,a2.shop_name   AS shop_name,a2.shop_type   AS shop_type
FROM (SELECT * FROM main_table   WHERE dt = '${bizdate}') a1 
LEFT JOIN (SELECT * FROM dim_table_info WHERE dt = '${bizdate}') a2 
ON  a1.dim_shop_id = a2.dim_shop_id;

2.5 方案总结

  总结,上面集中方案核心都是在围绕解决数据重分发(即为shuffle)导致的热点问题,一种是采用Mapjoin的方式避免热点数据重分发,一种是让数据充分发过程中尽可能的均匀。

三、Distmapjoin

3.1 核心思路

 数据倾斜的核心在于数据处理不均匀,而数据处理的不均匀往往又来自于数据重分发,也就是shuffle。因此如果能解决好shuffle不均匀问题,或者在不需要对大表进行shuffle的同时就能完成数据关联计算的操作,就能避免数据倾斜的问题。

   Mapjoin用于处理热点数据,将维表热点记录广播至大表所在计算节点;Distmapjoin用于处理非热点数据,用于通过构建远程分布式查询节点,实现大表在无需移动的情况下,完成数据关联操作。

https://help.aliyun.com/zh/maxcompute/user-guide/distributed-mapjoin?spm=a2c4g.11186623.0.i1#concept-2197457icon-default.png?t=N7T8https://help.aliyun.com/zh/maxcompute/user-guide/distributed-mapjoin?spm=a2c4g.11186623.0.i1#concept-2197457

3.2 代码实现

WITH 
-- STEP01:热点Key采集
tmp_hot_pid AS (SELECT dim_shop_id,'Y' AS is_hotFROM main_table_detailWHERE dt = '${bizdate}'GROUP BY dim_shop_idHAVING COUNT(1) > 100000
)
-- STEP02:维表热点数据打标
,tmp_dim_tbl AS (SELECT   /*+MAPJOIN(hot)*/ dim.*,COALESCE(hot.is_hot,'N') AS is_hotFROM (SELECT *FROM dim_table_infoWHERE dt = '${bizdate}') dimLEFT OUTER JOIN tmp_hot_pid hot ON dim.dim_shop_id = hot.dim_shop_id
)
-- STEP03:明细热点数据打标
,tmp_dwd_tbl AS (SELECT /*+MAPJOIN(hot)*/ base.*,COALESCE(hot.is_hot,'N') AS is_hotFROM (SELECT *FROM main_table_detailWHERE dt = '${bizdate}') base LEFT OUTER JOIN tmp_hot_pid hot ON base.dim_shop_id = hot.dim_shop_id
)-- STEP04:数据合并处理,热点数据用Mapjoin,非热点数据用DISTMAPJOIN
INSERT OVERWRITE TABLE final_result_table PARTITION (dt = '${bizdate}')
SELECT *
FROM (-- STEP04-1:非热点数据用DISTMAPJOINSELECT  /*+ DISTMAPJOIN(dim(shard_count=77)) */ dwd_tbl.trade_no   AS trade_no,dwd_tbl.trade_date AS trade_date,dwd_tbl.shop_id    AS shop_id,dim.shop_name      AS shop_name,dim.shop_type      AS shop_typeFROM (SELECT * FROM tmp_dwd_tbl WHERE is_hot = 'N') dwd_tblLEFT OUTER JOIN (SELECT * FROM tmp_dim_tbl WHERE is_hot = 'N') dim ON dwd_tbl.partner_id = dim.partner_idUNION ALL-- STEP04-1:热点数据用MapjoinSELECT /*+MAPJOIN(dim)*/ dwd_tbl.trade_no   AS trade_no,dwd_tbl.trade_date AS trade_date,dwd_tbl.shop_id    AS shop_id,dim.shop_name      AS shop_name,dim.shop_type      AS shop_typeFROM (SELECT *FROM tmp_dwd_tbl WHERE is_hot = 'Y') dwd_tblLEFT OUTER JOIN (SELECT *FROM tmp_dim_tbl WHERE is_hot = 'Y') dim ON dwd_tbl.partner_id = dim.partner_id
) base ;

3.3 真实效果

   当前新方案在支付宝核心支付数据链路上线,给相关可优化节点带来了平均40%的计算耗时缩减和平均30%的计算资源缩减。方案主要应用于支付交易join商家维表、支付交易join合约维表等场景,方案将原本需要手动拆分热点利用“Mapjoin+shuffle进行热点数据处理”的过程,改为利用Distmapjoin或Mapjoin+Distmapjoin的方案,让支付交易大表在计算全过程中均无需移动,在解决数据倾斜问题的同时,也实现了降低计算资源和提升产出时效。

四、方案总结

上面介绍了一种结合Mapjoin和Distmapjoin的数据倾斜处理方案,在有效解决数据倾斜问题的同时还可以避免大表的shuffle,提供了更优的性能表现。实际上如果数据倾斜情况不是特别严重(比如 热点数据行/平均单节点处理数据行 < 100),完全可以直接使用纯Distmapjoin的方案。

综合我们基于Distmapjoin提出的两种方案,我们结合各种方案的优劣势进行方案分级,然后根据具体场景进行更优的方案选择。

参考文章:

https://mp.weixin.qq.com/s/VGgT1faRKGnUuQ-HHQ3Q5g

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

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

相关文章

MUX VLAN

目录 原理概述 实验目的 实验内容 实验拓扑 1.基本配置 2.使用Hybrid端口实现网络需求 3.使用Mux VLAN实现网络需求 原理概述 在实际的企业网络环境中&#xff0c;往往需要所有的终端用户都能够访问某些特定的服务器&#xff0c;而用户之间的访问控制规则则比较复杂。在…

✌2024/4/3—力扣—字符串转换整数

代码实现&#xff1a; int myAtoi(char *str) {long ret 0;int flag 1; // 默认正数// 去除空格及判断符号位while (*str ) {str;}if (*str -) {flag -1;str;} else if (*str ) {str;}// 排除非数字的情况if (*str < 0 || *str > 9) {return 0;}while (*str > …

前端| 富文本显示不全的解决方法

背景 前置条件&#xff1a;编辑器wangEditor vue项目 在pc端进行了富文本操作&#xff0c; 将word内容复制到编辑器中&#xff0c; 进行发布&#xff0c; pc端正常&#xff0c; 在手机端展示的时候 显示不全 分析 根据h5端编辑器内容的数据展示&#xff0c; 看到有一些样式造…

大模型应用解决方案:基于ChatGPT和GPT-4等Transformer架构的自然语言处理

&#x1f482; 个人网站:【 摸鱼游戏】【神级代码资源网站】【工具大全】&#x1f91f; 一站式轻松构建小程序、Web网站、移动应用&#xff1a;&#x1f449;注册地址&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交…

性能优化 - 你知道webpack都可以帮我们做哪些性能优化吗

难度级别:中高级及以上 提问概率:75% webpack打包优化主要的思想就是合理利用浏览器缓存、减小代码体积以及减少HTTP请求数量。尽管我们在开发阶段已经做了大量的优化工作,但开发阶段难免存在疏忽,而且源代码也不能直接部署到服务器。可以说…

一起学习python——基础篇(7)

今天讲一下python的函数。 函数是什么&#xff1f;函数是一段独立的代码块&#xff0c;这块代码是为了实现一些功能&#xff0c;而这个代码块只有在被调用时才能运行。 在 Python 中&#xff0c;使用 def 关键字定义函数&#xff1a; 函数的固定结构就是 def(关键字)函数名字…

Spring 源码学习笔记(一)之搭建源码环境

前言 一直以来对 Spring 源码的理解不够全面&#xff0c;也不成条理&#xff0c;只是对其中的某小部分比较了解&#xff0c;所以从今天开始要重新系统学习 Spring 的源码了。 搭建源码环境 首先需要说明的是&#xff0c;源码环境并不是必须的&#xff0c;搭建源码环境唯一的好…

[STL-list]介绍、与vector的对比、模拟实现的迭代器问题

一、list使用介绍 list的底层是带头双向链表结构&#xff0c;双向链表中每个元素存储在互不相关的独立节点中&#xff0c;在节点中通过指针指向其前一个元素和后一个元素。与其他的序列式容器相比(array&#xff0c;vector&#xff0c;deque)&#xff0c;list通常在任意位置进行…

01.MySQL基础知识回顾

MySQL基础知识回顾 1.为什么要使用数据库 问题 如果把数据存储到内存中&#xff0c;那么重启后就消失了&#xff0c;我们希望一个数据被保存后永久存在于一个地方&#xff0c;也就是需要把数据持久化 什么是持久化 把数据保存到可掉电式存储设备中以供之后使用。大多数情况…

Linux安装最新版Docker完整教程

参考官网地址&#xff1a;Install Docker Engine on CentOS | Docker Docs 一、安装前准备工作 1.1 查看服务器系统版本以及内核版本 cat /etc/redhat-release1.2 查看服务器内核版本 uname -r这里我们使用的是CentOS 7.6 系统&#xff0c;内核版本为3.10 1.3 安装依赖包 …

MySQL如何创建存储过程

工作中有时候需要自己去创建存储过程&#xff0c;然后调用存储去获得一些数据等&#xff0c;接下来就给大家介绍下MySQL如何创建存储过程。 语法&#xff1a; CREATE PROCEDURE 存储程名([[IN|OUT|INOUT] 参数名 数据类型[,[IN|OUT|INOUT] 参数名 数据类型…]]) [特性 …] 过…

区块链技术与数字身份:解析Web3的身份验证系统

在数字化时代&#xff0c;随着个人数据的日益增多和网络安全的日益关注&#xff0c;传统的身份验证系统面临着越来越多的挑战和限制。在这种背景下&#xff0c;区块链技术的出现为解决这一问题提供了全新的思路和解决方案。Web3作为一个去中心化的互联网模式&#xff0c;其身份…

在线JSON工具

功能支持 ctrls json格式化游览器本地保存ctrla ctrlc 自动检测选中范围是否是全选&#xff0c;然后按照格式化方式添加到粘贴板中json 粘贴JSON自动格式化json可视化修改json压缩复制json层级折叠json关键key 搜索(自动提示高亮)满足某些近视的可以自行调整字体大小, 并且会游…

【Spring】SpringBoot整合MybatisPlusGernerator,MybatisPlus逆向工程

&#x1f4dd;个人主页&#xff1a;哈__ 期待您的关注 在我们写项目的时候&#xff0c;我们时常会因为需要创建很多的项目结构而头疼。项目中的表很多的时候&#xff0c;我们连实体类都创建不完&#xff0c;这时候就需要我们的逆向工程来帮助我们生成我们的框架结构。这些结构…

centos安装使用elasticsearch

1.首先可以在 Elasticsearch 官网 Download Elasticsearch | Elastic 下载安装包 2. 在指定的位置(我的是/opt/zhong/)解压安装包 tar -zxvf elasticsearch-7.12.1-linux-x86_64.tar.gz 3.启动es-这种方式启动会将日志全部打印在当前页面&#xff0c;一旦使用 ctrlc退出就会导…

自动驾驶硬件系统- Inertial Measurement Unit (IMU)

自动驾驶硬件系统- Inertial Measurement Unit (IMU) 附赠自动驾驶学习资料和量产经验&#xff1a;链接 惯性测量单元(Inertial measurement unit&#xff0c;简称 IMU)&#xff0c;是测量物体三轴姿态角及加速度的装置。一般IMU包括三轴陀螺仪及三轴加速度计&#xff0c;部分…

小米汽车:搅动市场的鲶鱼or价格战砧板上的鱼肉?

3月28日晚&#xff0c;备受关注的小米汽车上市发布会召开&#xff0c;小米集团董事长雷军宣布小米SU7正式发布。小米汽车在带飞股价的同时&#xff0c;二轮订购迅速售尽。 图一&#xff1a;小米集团股价 雷军口中“小米汽车迈出的第一步&#xff0c;也是人生最后一战的开篇”&a…

蓝桥杯 经验技巧篇

1. 注意事项 &#x1f468;‍&#x1f3eb; 官方通知 &#x1f468;‍&#x1f3eb; 资料文档 时间&#xff1a;4月13日 9:00~13:00 &#xff08;时长 4小时&#xff09;物品 准考证&#xff08;赛前一周开放下载&#xff0c;自行打印&#xff09;学生证身份证笔、水、外套&a…

知识推理技术解析与实战

目录 一、引言二、知识推理基础知识表示方法本体论语义网络图形数据库 推理机制概述演绎推理归纳推理类比推理 实践代码示例 三、知识推理的核心技术自动推理系统规则引擎推理算法 知识图谱的运用构建知识图谱知识推理与查询 推理算法深度分析转导推理逻辑推理概率推理 实践代码…

关键节点组挖掘(附Python实现)

一、实验内容简介 该实验主要利用基于度的排序和基于投票策略的排序分别挖掘出一组重要节点作为种子节点&#xff0c;然后在给定的网络中传播&#xff0c;一直到稳态&#xff0c;然后统计感染的规模NR。最后通过比较两种方法的感染规模给出相应的评价&#xff0c;给出不同感染…