数据倾斜产生
根本原因是上游task经过shuffle发往下游task的某一个或多个key的数量
量特别大, 导致下游一个task需要处理的数据远远大于其他task;
一. 定位倾斜算子:
1. 在spark UI(8080)中找到这个application的job那些耗时明显过长的stage,定位倾斜算子;
2. 使用spark的sample()算子随机抽样,定位倾斜key;
二. 处理数据倾斜
1. 提高shuffle并行度
reducebykey中的shuffle read task的默认值为200,也就是同时用200个task来处理任务, 调大参数;
2. 聚合类数据倾斜
采用两阶段聚合(局部聚合+全局聚合)
首先定位倾斜key, 给倾斜key打上10以内的随机前缀(加盐操作),
再进行聚合, 后用map切割一下封装成元组再做聚合, 可以提高数倍效率;
3. join类数据倾斜
reduce端join 转 map端join
如果两表数据量都很小, 不管他们是大大表还是大小表join, 倾斜都不用处理;
大小表join:
小表的数据量不大,比如1G之内,
将小表数据拉倒driver端广播出去, 这样每一个executor中都有这个小表的cache
下游reduce不会产生数据的分发, 从而避免了数据倾斜;
大大表join;
采样倾斜key并拆分join操作
通过sample()算子抽样定位倾斜key,
将这些倾斜key对应的数据拆分开来形成单独的RDD
需要join的另一个RDD中的对应key也拆分出来,
如果拆分出倾斜key的两个RDD中有一个是小表,则采用map端join, 广播出去,
否则给倾斜key对用的数据加盐操作,打上n以内的随机数,将需要join的另一个RDD的每条数据膨胀成n条数据,打上0~n的前缀,
剩下的两个非倾斜key的RDD做join,不会有数据倾斜,
最后将结果union, 就解决了数据倾斜;
注意spark-sql中有一个自动大小表join的参数, 默认是10M以内会自动广播小表; RDD中需手动广播;
hive底层使用MR, 也有参数会自动将common join(reduce) 转为 map join 默认为false, 需手动开启, 默认大小是25M以内会cache;
对于MR, 也是类似的原理, 对于hive就更不用说了, 因为它底层执行引擎不是MR就是SPARK
宽依赖: 父RDD的每个分区都可能被子RDD的多个分区使用
窄依赖: 指父RDD的每个分区只被子RDD的一个分区所使用
spark-on-yarn_client: Driver是在SparkSubmit进程中
spark-on-yarn_cluster: Driver是在Worker节点上运行
spark-standalone: 使用spark自己的资源调度集群
spark-on-yarn: yarn资源调度系统统一为spark等其他运算框架(比如flink,MR)调度集群资源分配, 实现负载均衡;