spark调优篇-数据倾斜(汇总)
数据倾斜
为什么会数据倾斜
spark 中的数据倾斜并不是说原始数据存在倾斜,原始数据都是一个一个的 block,大小都一样,不存在数据倾斜;
而是指 shuffle 过程中产生的数据倾斜,由于不同的 key 对应的数据量不同导致不同 task 处理的数据量不同
注意:数据倾斜与数据过量不同,数据倾斜是某几个 task 处理的数据量很大,数据过量是所有 task 处理的数据量都很大
数据倾斜的表现
大部分 task 都快速执行完毕,少数 task 执行缓慢,甚至报错 OOM,即使最终运行完毕,也叫数据倾斜
数据倾斜的后果
1. 程序执行缓慢
2. 报错 OOM
定位数据倾斜问题
1. 经验:查看代码中的 shuffle 算子,如 reduceByKey、countByKey、groupByKey、join 等,根据代码逻辑判断是否会出现数据倾斜
2. spark log 文件:log 记录错误发生在代码的哪一行,从而再根据自己的理解定位哪个 shuffle 算子
3. spark web UI:
解决方案
聚合原数据
避免 shuffle
1. 既然数据倾斜是 shuffle 产生的,那没有 shuffle 肯定就没有数据倾斜了;
2. 没有 shuffle 意味着在 原数据层面已经进行了 “shuffle”
这种方法适合 原数据方便实现大量数据合并操作 的数据源,确切的说就是 Hive;
比如在 Hive 中按照 key 进行分组,把每个 key 的 value 拼成一个 字符串(当然也可以是其他操作,根据需求定),那么这种数据进入 spark 后,无需 shuffle 了,直接 map 即可
缩小 key 粒度
比如把按 月 统计变成按 周 统计;
key 的粒度缩小,每个 key 对应的数据量降低,task 处理的数据量减少;
这样可以保证程序顺利执行,减少 OOM,但是可能引起更大的数据倾斜
增大 key 粒度
比如把按 周 统计变成按 月 统计;
key 的粒度增大,每个 key 对应的数据量增大,task 处理的数据量增大;
这样可以降低数据倾斜的可能,但是 可能引起 OOM
过滤导致倾斜的 key
极端方法,扔掉导致倾斜的 key,不建议
提高 shuffle 操作的 reduce 并行度
增加 reduce 并行度其实就是增加 reduce 端 task 的数量, 这样每个 task 处理的数据量减少,避免 oom
reduce 端并行度设置
1. 在很多 shuffle 算子中可直接指定并行度,如 reduceByKey(lambda x, y: x+y, 10)
// 注意如果并行度大于 executor 数 x executor core 数,以小为准
2. 在 sparkSQL 中 groupBy、join 等 shuffle 操作,需要设定 spark 参数:spark.sql.shuffle.partitions
// 该参数默认为 200
这样做是有缺陷的
map 端不断地写入数据,reduce task 不断地从指定位置读取数据,如果 task 很多,读取的速度增加,但是每个 key 对应的 reduce 处理的总量没变,
所以它并没有从根本上解决数据倾斜的问题,只是尽量去减少 reduce task 的数据量,适用于 较多 key 对应的数据量都很大的问题;
试想,如果只有 1 个 key 数据量较大,那么其他 key 高并行就是资源的浪费;
使用随机 key 进行双重聚合
双重聚合,就是聚合多次,大致思路为:
由于一个 key 对应的数据量太大,我先给这个 key 加个随机数,num_key,强行把一个 key 变成 多个 key,这样每个 key 的数据量减小,然后按 num_key 进行聚合,聚合之后,把 num_key 再转回 key,然后对 key 再次聚合;
把一次聚合变成多次聚合,如图
这种方法适合于 reduceByKey、groupByKey 等算子,不适合 join 算子
将 reduce join 变成 map join
正常情况下,join 会产生 shuffle 过程,而且是 reduce join,即先将相同 key 对应的 value 汇聚到一个 reduce task 中,再进行 join,如下图
如果其中有一个 RDD 很小,就可以采用 广播小 RDD + map 大 RDD 实现 join 功能,
此时没有 shuffle 操作,自然不会有数据倾斜
注意:RDD 是不能广播的,只有将 RDD 通过 collect 拉取到 Driver 内存中才能进行广播
如果是两个 RDD 都很大,则不适合这种方法
sample 采样对倾斜 key 单独进行 join
思考一个问题,如果 RDD 中只有一个 key,shuffle 如何做?
在 spark 中,如果只有一个 key,shuffle 过程会将 所有 value 打散,分配到不同的 reduce task 中;
那么如果某个 RDD 中因为单个 key 导致数据倾斜,我们可以把这个 key 拿出来形成一个新的 RDD1,其他 key 形成一个 RDD2,然后用 RDD1 再与目标 RDD 进行 join 操作,根据 spark 运行机制,他会把 RDD1 打散分配到多个 task 中进行 join 操作;
这样可以避免因 这个 key 对应的数据量太大导致数据倾斜,甚至 OOM
如果一个 RDD 中有多个 key 导致数据倾斜,则此法不适用
使用随机数以及扩容进行 join
如果有多个 key 导致数据倾斜,无法通过采样确定哪个 key 数据量大,只能把多个 key 都提出来,这样效率貌似不太高;
此时我们只有一种解决方案:对一个 RDD 扩容,对另一个 RDD 稀释,再进行 join
具体做法如图
注意:如果 RDD 过大,进行 随机数扩容后,可能产生 OOM
repartition
这个也是较常用的方法,它的本质就是减少 task 处理的数据量,一般发生在 shuffle 之前,当然它本身也是个 shuffle 操作
总结
数据倾斜 是 某些 task 处理了大量数据,所以数据倾斜很可能引起 OOM,数据倾斜和 OOM 的某些解决办法可以通用;
解决数据倾斜的大致思路为:
1. 避免 shuffle,可在数据输入 spark 之前进行 shuffle,或者 用 map 等替代 shuffle
// 聚合原始数据、广播小 RDD
2. 如果避免不了 shuffle,就减少 reduce task 的数据量
// 缩小 key 粒度、增加 reduce task 数量
// 通过随机数多次聚合,减少每次聚合的数据量,针对 reduceByKey、groupByKey 等
3. 其他情况,单个 key 数据量大,多个 key 数据量大,针对 join
spark调优篇-数据倾斜(汇总)的更多相关文章
- 【Spark调优】数据倾斜及排查
[数据倾斜及调优概述] 大数据分布式计算中一个常见的棘手问题——数据倾斜: 在进行shuffle的时候,必须将各个节点上相同的key拉取到某个节点上的一个task来进行处理,比如按照key进行聚合或j ...
- spark调优篇-oom 优化(汇总)
spark 之所以需要调优,一是代码执行效率低,二是经常 OOM 内存溢出 内存溢出无非两点: 1. Driver 内存不够 2. Executor 内存不够 Driver 内存不够无非两点: 1. ...
- Spark 调优之数据倾斜
什么是数据倾斜? Spark 的计算抽象如下 数据倾斜指的是:并行处理的数据集中,某一部分(如 Spark 或 Kafka 的一个 Partition)的数据显著多于其它部分,从而使得该部分的处理速度 ...
- spark调优篇-Spark ON Yarn 内存管理(汇总)
本文旨在解析 spark on Yarn 的内存管理,使得 spark 调优思路更加清晰 内存相关参数 spark 是基于内存的计算,spark 调优大部分是针对内存的,了解 spark 内存参数有也 ...
- Spark学习之路 (九)SparkCore的调优之数据倾斜调优
摘抄自:https://tech.meituan.com/spark-tuning-pro.html 数据倾斜调优 调优概述 有的时候,我们可能会遇到大数据计算中一个最棘手的问题——数据倾斜,此时Sp ...
- Spark学习之路 (九)SparkCore的调优之数据倾斜调优[转]
调优概述 有的时候,我们可能会遇到大数据计算中一个最棘手的问题--数据倾斜,此时Spark作业的性能会比期望差很多.数据倾斜调优,就是使用各种技术方案解决不同类型的数据倾斜问题,以保证Spark作业的 ...
- 【Hive】Hive笔记:Hive调优总结——数据倾斜,join表连接优化
数据倾斜即为数据在节点上分布不均,是常见的优化过程中常见的需要解决的问题.常见的Hive调优的方法:列剪裁.Map Join操作. Group By操作.合并小文件. 一.表现 1.任务进度长度为99 ...
- 【Spark调优】数据本地化与参数调优
数据本地化对于Spark Job性能有着巨大的影响,如果数据以及要计算它的代码是在一起的,那么性能当然会非常高.但是,如果数据和计算它的代码是分开的,那么其中之一必须到另外一方的机器上.移动代码到其匹 ...
- spark调优篇-spark on yarn web UI
spark on yarn 的执行过程在 yarn RM 上无法直接查看,即 http://192.168.10.10:8088,这对于调试程序很不方便,所以需要手动配置 配置方法 1. 配置 spa ...
随机推荐
- 运维自动化之ansible
Ansible简介 Ansible是一个简单的自动化运维管理工具,基于Python语言实现,由Paramiko和PyYAML两个关键模块构建,可用于自动化部署应用.配置.编排task(持续交付.无宕机 ...
- HTTP之缓存
1. 保持副本的新鲜 HTTP 有一些简单的机制可以在不要求服务器记住有哪些缓存拥有其文档副本的情况下,保持已缓存数据与服务器数据之间充分一致.HTTP 将这些简单的机制称为文档过期(document ...
- 性能调优 | 如何通过性能调优突破 MySQL 数据库性能瓶颈?
本文出自头条号老王谈运维,转载请说明出处. MySQL 数据库瓶颈对 DBA 程序员而言,是非常棘手的问题.要正确的优化SQL,我们需要快速定位能性的瓶颈点,也就是说快速找到我们SQL主要的开销在哪里 ...
- MapReduce On Yarn的配置详解和日常维护
MapReduce On Yarn的配置详解和日常维护 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.MapReduce运维概述 MapReduce on YARN的运维主要是 ...
- export default {} 和new Vue()区别?
export default 的用法:相当于提供一个接口给外界,让其他文件通过 import 来引入使用. 而对于 new Vue({})部分, 只是创建一个Vue的实例 就是相当于创建一个根组件 h ...
- C之交换数据案例
//值传递 void swap(int i,int j){ printf("交换后:\n "); int tmp; tmp = i; i = j; j = tmp; } //引用传 ...
- PLSQL Developer配置OCI连接远程数据库
转: PLSQL Developer配置OCI连接远程数据库 当前环境: 本机系统:Win7 32位 PLSQL版本:9.06 数据库版本:10.2 32位 下面开始具体操作. 1.在Oracle官网 ...
- Visual Studio Code 上java开发环境搭建
在把一些开源的SDK中java代码转成C#代码时经常需要写点java代码来实验下功能,装个Eclipse或IDEAs吧,好像也不太值当,所以用vs code搭个环境偶尔来实验下.以下: 1.下载并装好 ...
- Qt编写数据可视化大屏界面电子看板4-布局另存
一.前言 布局另存是数据可视化大屏界面电子看板系统中的额外功能之一,主要用于有时候用户需要在现有布局上做个微调,然后直接将该布局另存为一个布局配置文件使用,可以省略重新新建布局重新来一次大的调整的工作 ...
- python用户评论标签匹配的解决方法
python用户评论标签匹配的解决方法 这篇文章主要为大家详细介绍了python用户评论标签匹配的解决方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 我们观察用户评论发现:属性词往往和情感词伴 ...