Spark之数据倾斜

本文介绍了Spark中的数据倾斜问题,包括其定义和对性能的影响。针对数据源倾斜,建议通过调整partition大小来规避;对于Reduce数据倾斜,可通过增加并行度分散task;自定义partitioner也是解决数据倾斜的有效手段。文章提供了几种常用缓解数据倾斜的方法,并欢迎读者交流讨论。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

对于一个算法工程师来说,Spark是一个非常常用的工具。对于使用过Spark的同学,对于数据倾斜的问题一定不会陌生。
本文讲主要介绍Spark中的数据倾斜以及一些处理方案。

啥是数据倾斜?

这一切可能要从分布式计算系统说起,用最通俗的话来说,现在我们有一个任务,在一台电脑上跑要100个小时,于是我们灵光一现,我们整一百台不就行了?
于是,我们得到 任务处理时间 = 100小时/100台电脑 = 1小时
以上,就是一个理想的分布式系统。

然而,在现实中,我们需要考虑一个问题,我们这个100小时的任务能否被完美的分成100个1小时的任务?
现实中的问题很复杂,这次,有一个2小时的任务不能被分解,所以,我们这一百台电脑的运行时间变成了2小时,比理想状况增加了一倍的时间。

其实,刚刚在前面描述的问题和数据倾斜很相似,数据倾斜是指在分布式系统中,机器之间任务分配不均匀,导致大部分机器完成任务后等待个别机器的现象,这种现象造成的时间性能和计算资源的浪费,所以,我们要想方设法的缓解和消除数据倾斜。

那咋消除数据倾斜呢?

关于数据源倾斜

如果我们Spark任务的数据源发生了倾斜,这种时候我们可以通过调整partition的大小来规避数据倾斜。
在读取输入文件时,我们使用textFile(path, minPartitions)来读文件,下面的代码说明了一个Partition分区大小是如何计算的。
其中,minSize默认为1B,goalSize = 总文件大小/minPartitions,blockSize为HDFS默认的分片大小。

protected long computeSplitSize(long goalSize, long minSize, long blockSize) {
    return Math.max(minSize, Math.min(goalSize, blockSize));
}

当数据源是可以切分的时候,我们可以通过调整minPartitions来控制读入分片大小,从而消除数据倾斜。

关于Reduce数据倾斜

在Reduce侧,如果并行度设置的不均衡,可能会导致task分配不均,这种情况可以增加并行度,分散之前task集中的reduce。

关于自定义partitioner

我们可以通过自定义partitioner,按照我们的需求把数据均匀的分配到不同的机器上,以解决数据倾斜。

.groupByKey(new Partitioner() {
  @Override
  public int numPartitions() {
    return 14;
  }

  @Override
  public int getPartition(Object key) {
    int id = Integer.parseInt(key.toString());
    if(id >= 9500000 && id <= 9500084 && ((id - 9500000) % 14) == 0) {
      return (id - 9500000) / 14;
    } else {
      return id % 14;
    }
  }
})

最后

本文总结了几种常用的缓解数据倾斜的方法,由于本身不是专门做数据方面的同学,可能有一些疏忽和纰漏,欢迎大家指点和交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值