我正在使用Spark Graphframe处理较大的(?)图(6000万个顶点和95亿条边)。基础数据并不大-顶点在磁盘上大约需要500mb,而边缘大约需要40gb。由于Java堆内存不足问题,我的容器经常关闭,但我认为潜在的问题是graphframe不断在对数据进行混排(我看到混排读取/写入的数据高达150gb)。有没有一种方法可以有效地划分Graphframe或基础边缘/顶点以减少混洗?

最佳答案

TL; DR 无法有效地分区Graphframe
Graphframe算法可以分为两类:

  • 将处理委托(delegate)给GraphX对应对象的方法。 GraphX支持多种分区方法,但是这些方法不会通过Graphframe API公开。如果使用其中之一,则最好直接使用GraphX

    不幸的是,在过去的两年中,GraphX的开发几乎完全停止了,仅进行了一些小小的修正,并且与核心库和out-of-core libraries相比,总体性能令人失望。
  • 使用Spark Datasets native 实现的方法,考虑到有限的编程模型和仅单个分区模式,这些方法非常不适合复杂的图形处理。

    虽然关系列存储可以用于有效的图形处理,但是join所采用的幼稚迭代Graphframes方法只是不扩展(但是对于一两个跃点的浅层遍历是可以的)。

    您可以尝试分别通过verticesedges重新划分DataFramesid src:
    val nPart: Int = ???
    
    GraphFrame(v.repartition(nPart, v("id")), e.repartition(e(nPart, "src")))
    

    在某些情况下应该有什么帮助。

  • 总体而言,在当前(2016年12月)状态下,Spark不是进行密集图形分析的理想选择。

    关于apache-spark - 使用Spark Graphframe进行分区,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41351802/

    10-12 22:57