spark 分区 java_spark 自定义partitioner分区 java版

本文介绍了在Spark中遇到数据倾斜问题时,如何通过自定义分区器解决。讨论了默认的HashPartitioner的工作原理,以及其可能导致相同key落在不同分区的情况。提出了使用自定义分区器CuxGroupPartitioner的实现方式,确保相同name的记录在同一分区,以优化处理效率。并展示了检查分区分布的工具类和调用示例。
摘要由CSDN通过智能技术生成

在遍历spark dataset的时候,通常会使用 forpartition 在每个分区内进行遍历,而在默认分区(由生成dataset时的分区决定)可能因数据分布原因导致datasetc处理时的数据倾斜,造成整个dataset处理缓慢,发挥不了spark多executor(jvm 进程)多partition(线程)的并行处理能力,因此,普遍的做法是在dataset遍历之前使用repartition进行重新分区,让数据按照指定的key进行分区,充分发挥spark的并行处理能力,例如:

dataset.repartition(9,new Column("name")).foreachPartition(it -> {

while (it.hasNext()) {

Row row = it.next();

....

}

});

先看一下准备的原始数据集:

3151677413eb9df77cd7dbb88442daa3.png

按照上面的代码,预想的结果应该是,相同名字在记录在同个partition(分区),不同名字在不同的partition,并且一个partition里面不会有不同名字的记录,而实际分区却是这样的

36f9efbe9f00883628d5a47d8ce215d7.png

(查看分区分布情况的代码在之前一篇文章 spark sql 在mysql的应用实践 有说明,如果调用reparation时未指定分区数量9,则默认为200,使用 spark.default.parallelism 配置的数量为分区数,在partitioner.scala 的 partition object 定义可以看到)

这个很囧...乍看一下,压根看不出什么情况,翻看源码发现,rdd 的partition 分区器有两种 HashPartitioner & RangePartitioner,默认情况下使用 HashPartitioner,从 repartition 源码开始入手

/**

* Dataset.scala

* Returns a new Dataset partitioned by the given partitioning expressions into

* `numPartitions`. The resulting Dataset is hash partitioned.

*

* This is the same operation as "DISTRIBUTE BY" in SQL (Hive QL).

*

* @group typedrel

* @since 2.0.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值