当前位置: 首页 > 知识库问答 >
问题:

太多的map键导致内存溢出异常

岳高明
2023-03-14

我有一个形式为RDD[(Vector[(Int, Byte)], Vector[(Int, Byte)]]的RDD'inRDD',它是一个PairRDD(key, value)其中key是Vector[(Int, Byte)],value是Vector[(Int, Byte)]

对于键向量字段中的每个元素(Int,Byte),以及值向量字段中的每个元素(Int,Byte),我想在输出RDD中获得一个新的(键,值)对,作为(Int,Int),(Byte,Byte)

这应该会给我一个RDD,它的形式是RDD[((Int,Int),(Byte,Byte))]

例如,inRDD内容可能是这样的,

(Vector((3,2)),Vector((4,2))), (Vector((2,3), (3,3)),Vector((3,1))), (Vector((1,3)),Vector((2,1))), (Vector((1,2)),Vector((2,2), (1,2)))

这将成为

((3,4),(2,2)), ((2,3),(3,1)), ((3,3),(3,1)), ((1,2),(3,1)), ((1,2),(2,2)), ((1,1),(2,2))

我有下面的代码。

val outRDD = inRDD.flatMap {                                        
    case (left, right) =>
    for ((ll, li) <- left; (rl, ri) <- right) yield {
        (ll,rl) -> (li,ri)
    }
}

inRDD中的向量很小时,它就起作用。但是当向量中有很多元素时,我会得到内存不足异常。增加spark的可用内存只能解决较小的输入,而对于更大的输入,错误再次出现。看起来我正试图在内存中组装一个巨大的结构。我无法以任何其他方式重写此代码。

我用hadoop中的java实现了类似的逻辑,如下所示。

for (String fromValue : fromAssetVals) {
    fromEntity = fromValue.split(":")[0];
    fromAttr = fromValue.split(":")[1];
    for (String toValue : toAssetVals) {
        toEntity = toValue.split(":")[0];
        toAttr = toValue.split(":")[1];
        oKey = new Text(fromEntity.trim() + ":" + toEntity.trim());
        oValue = new Text(fromAttr + ":" + toAttr);
        outputCollector.collect(oKey, oValue);
    }
}

但是,当我尝试在火花类似的东西,我得到嵌套rdd异常。

使用scala的spark如何有效地做到这一点?


共有1个答案

步炯
2023-03-14

如果笛卡尔积是唯一的选择,你至少可以让它更懒一点:

inRDD.flatMap { case (xs, ys) =>
  xs.toIterator.flatMap(x => ys.toIterator.map(y => (x, y)))
}

你也可以在Spark级别处理这个问题

import org.apache.spark.RangePartitioner

val indexed = inRDD.zipWithUniqueId.map(_.swap)
val partitioner = new RangePartitioner(indexed.partitions.size, indexed)
val partitioned = indexed.partitionBy(partitioner)

val lefts = partitioned.flatMapValues(_._1)
val rights = partitioned.flatMapValues(_._2)

lefts.join(rights).values
 类似资料:
  • 本文向大家介绍解决Tensorflow sess.run导致的内存溢出问题,包括了解决Tensorflow sess.run导致的内存溢出问题的使用技巧和注意事项,需要的朋友参考一下 下面是调用模型进行批量测试的代码(出现溢出),开始以为导致溢出的原因是数据读入方式问题引起的,用了tf , PIL和cv等方式读入图片数据,发现越来越慢,内存占用飙升,调试时发现是sess.run这里出了问题(随着f

  • JNIEXPORT jint JNICALL Java_nc_mes_pub_hardware_PCI1761_readChanel(JNIEnv*,jobject,jint channel){ }

  • 问题内容: 这有效:http : //play.golang.org/p/-Kv3xAguDR。 这导致堆栈溢出:http : //play.golang.org/p/1-AsHFj51O。 我不明白为什么。在这种情况下,使用接口的正确方法是什么? 问题答案: 这个 将呼叫您的,依次呼叫,等等。如果您需要解组JSON然后对其进行处理,那么一种巧妙的技术是声明一个本地类型,将数据解组到其中,然后转换

  • 我想格式化和写入一个大的(1.785.530条目)的内容到一个文本文件。大约85%的条目被处理后,它变得非常慢,然后我得到一个。 即使我: 在我的

  • 内存溢出 内存泄漏指由于疏忽或错误造成程序未能释放已经不再使用的内存。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,导致在释放该段内存之前就失去了对该段内存的控制,从而造成了内存的浪费。 内存泄漏通常情况下只能由获得程序源代码的程序员才能分析出来, 也是一个比较难以排查的问题。所有需要在开发前知道一些规范 内存溢出一直向一个 属性/变量 写数据 , 写入超过内存最大限

  • 本文向大家介绍一个JSP页面导致的tomcat内存溢出的解决方法,包括了一个JSP页面导致的tomcat内存溢出的解决方法的使用技巧和注意事项,需要的朋友参考一下 今天新能测试组的同事找我看一个奇怪的现象。一个tomcat应用,里面只有一个单纯的jsp页面,而且这个jsp页面没有任何java代码(想用这个jsp页面测试在她的服务器上的一个tomcat的最大QPS)。但是用loadrunner压测了