Java 在Spark+中序列化/广播大型地图;斯卡拉

Java 在Spark+中序列化/广播大型地图;斯卡拉,java,scala,apache-spark,spark-streaming,distributed-computing,Java,Scala,Apache Spark,Spark Streaming,Distributed Computing,我的数据集由5000个元素数组(双倍)组成的数据点组成,每个数据点都分配了一个clusterId 为了解决我要解决的问题,我需要对每个簇ID聚合这些数组(元素),然后在每个数据点及其各自的聚合簇数组之间进行点积计算 我正在处理的数据点总数为4.8mm,它们被分为~50k个簇 我使用“reduceByKey”获得每个clusterId的聚合数组(这是我的关键)-使用此数据集,我有两个不同的选项: 将聚合(clusterId、aggregateVector)对连接到原始数据集,以便每个分区都可以使

我的数据集由5000个元素数组(双倍)组成的数据点组成,每个数据点都分配了一个clusterId

为了解决我要解决的问题,我需要对每个簇ID聚合这些数组(元素),然后在每个数据点及其各自的聚合簇数组之间进行点积计算

我正在处理的数据点总数为4.8mm,它们被分为~50k个簇

我使用“reduceByKey”获得每个clusterId的聚合数组(这是我的关键)-使用此数据集,我有两个不同的选项:

  • 将聚合(clusterId、aggregateVector)对连接到原始数据集,以便每个分区都可以使用每个aggregateVector
  • 在本地收集(clusterId,aggregateVector)的rdd并将其序列化回我的执行者——同样,这样我就可以使aggregateVector对每个分区可用
我的理解是,连接会导致基于连接键的重新分区,因此在我的例子中,我的键的唯一值是~50k,这将非常慢

我尝试的是第二种方法—我设法在本地收集RDD—并将其转换为clusterId作为键和5000元素数组[Double]作为值的映射

但是,当我尝试将此变量广播/序列化到闭包中时,我得到一个“java.lang.OutOfMemoryError:请求的数组大小超过VM限制”

我的问题是——考虑到我的问题的性质,我需要向每个执行者提供聚合数据,考虑到聚合数据集(在我的例子中是50k x 5000)可能相当大,那么最好的方法是什么


谢谢

我强烈推荐加入。5000个值x 50000个元素x 8个字节/值已经是2GB了,这是可以管理的,但它肯定是在“严重减慢速度,可能会破坏一些东西”的范围内

你是对的,重新划分有时会很慢,但我认为你更关心它,而不是必要的。它仍然是一个完全并行/分布式的操作,这使得它本质上可以无限扩展。把东西收集到司机手里不是一件容易的事