Apache spark 导致Spark Map调用中OOM错误的本地Java数据结构

Apache spark 导致Spark Map调用中OOM错误的本地Java数据结构,apache-spark,Apache Spark,我正试图在大约150万个条目的javapairdd上运行mapToPair函数。在调用之外,我有一个本地定义的JavaMap。如果访问mapToPair功能中的Map,则我的程序内存不足。如果我没有访问映射,那么即使我访问了代码主循环中的映射,它也会成功执行。有没有想过为什么会发生这种情况?我的假设是,在匿名函数中访问映射会导致Spark多次复制它 我在本地模式下运行Spark,有16个线程。这个问题发生在16到4000个数据分区之间 代码示例: 工作代码: JavaPairRDD<Int

我正试图在大约150万个条目的
javapairdd
上运行
mapToPair
函数。在调用之外,我有一个本地定义的Java
Map
。如果访问
mapToPair
功能中的
Map
,则我的程序内存不足。如果我没有访问
映射
,那么即使我访问了代码主循环中的映射,它也会成功执行。有没有想过为什么会发生这种情况?我的假设是,在匿名函数中访问
映射
会导致Spark多次复制它

我在本地模式下运行Spark,有16个线程。这个问题发生在16到4000个数据分区之间

代码示例:

工作代码

JavaPairRDD<Integer, CustomObject> pairRDD = createRDD();
while(loop_condition = true) {
    Map<Integer, CustomObject> bigLocalMap = createMap();
    System.out.println(bigLocalMap.size());
    pairRDD = pairRDD.mapToPair(pair -> {
        return pair;
    }
}
javapairdd pairdd=createRDD();
while(循环条件=true){
Map bigLocalMap=createMap();
System.out.println(bigLocalMap.size());
pairRDD=pairRDD.mapToPair(对->{
返回对;
}
}
不工作代码

JavaPairRDD<Integer, CustomObject> pairRDD = createRDD();
while(loop_condition = true) {
    Map<Integer, CustomObject> bigLocalMap = createMap();
    pairRDD = pairRDD.mapToPair(pair -> {
        System.out.println(bigLocalMap.size());
        return pair;
    }
}
javapairdd pairdd=createRDD();
while(循环条件=true){
Map bigLocalMap=createMap();
pairRDD=pairRDD.mapToPair(对->{
System.out.println(bigLocalMap.size());
返回对;
}
}

bigLocalMap有多大?
bigLocalMap
?引用它的方式(通过闭包)要求它序列化并发送给每个核心的每个执行器。相反,应该将它作为广播变量传递

一般的想法是,您可以在所有执行器上注册您希望访问的数据,spark将确保有效地传输数据,并且每个执行器只存储一次数据。如果您将执行器配置为具有多个核心,那么使用闭包方法,您将得到重复的数据

参考:

如果您的内存仍然不足,我将查看您的内存设置。解决此问题的一些候选方法是:

  • 减少每个执行器的内核数(减少使用内存的并发任务)
  • 通过设置
    spark.default.parallelism
    spark.sql.shuffle.partitions
    (仅在第一次洗牌后生效)或显式调用重新分区来增加分区数。较小的任务将具有较小的内存压力
  • 如果您有足够的资源,请使用
    spark.executor.memory
    设置增加您提供给执行器的RAM量

谢谢Ryan!我将其切换为广播变量,这似乎解决了OOM问题。在本地模式下运行时,是否有避免spark复制本地变量的一般方法?我使用的一些spark默认方法/类现在由于
bigLocalMap
的大小而崩溃,但我无法深入到它们的内部,以使其不可用HEM广播本地变量,而不是在任务中复制它们。我不确定没有看到有问题的代码。一般来说,我会说,如果您仍然存在上述建议的内存问题,那么您可能需要考虑将<代码> BigLoalPalm < /代码>加载为数据文件或RDD,而使用内置的DIST。按您认为合适的方式将其连接到数据的分布式操作。就性能而言,您通常最好使用数据帧。