Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala Spark新手,使用graphx图形进行映射-NullPointerException_Scala_Apache Spark_Rdd_Spark Graphx_Map Function - Fatal编程技术网

Scala Spark新手,使用graphx图形进行映射-NullPointerException

Scala Spark新手,使用graphx图形进行映射-NullPointerException,scala,apache-spark,rdd,spark-graphx,map-function,Scala,Apache Spark,Rdd,Spark Graphx,Map Function,我的目标是从一个普通的完整图中计算多个子图中的三角形。子图由一组常量节点+RDD[Long]中的一个节点定义。我是spark/graphx新手,因此这可能是对map的不当使用我共享的代码将重现我的错误。 首先,我声明了一个完整图的子图,如下所示 import org.apache.spark.rdd._ import org.apache.spark.graphx._ val nodes: RDD[(VertexId, String)] = sc.parallelize(Array((3L, "

我的目标是从一个普通的完整图中计算多个子图中的三角形。子图由一组常量节点+RDD[Long]中的一个节点定义。我是spark/graphx新手,因此这可能是对map的不当使用我共享的代码将重现我的错误。

首先,我声明了一个完整图的子图,如下所示

import org.apache.spark.rdd._
import org.apache.spark.graphx._
val nodes: RDD[(VertexId, String)] = sc.parallelize(Array((3L, "3"), (7L, "7"), (5L, "5"), (2L, "2"),(4L,"4")))
val vertices: RDD[Edge[String]] = sc.parallelize(Array(Edge(3L, 7L, "a"), Edge(3L, 5L, "b"), Edge(2L, 5L, "c"), Edge(5L, 7L, "d"), Edge(2L, 7L, "e"),Edge(4L,5L,"f")))
val graph: Graph[String,String] = Graph(nodes, vertices, "z")

val baseNodes: Array[Long] = Array(2L,5L,7L)    
val subgraph = graph.subgraph(vpred = (vid,attr)=> baseNodes contains vid)
然后我从图中声明其他节点的RDD[Long]

val testNodes: RDD[Long] = sc.parallelize(Array(3L,4L))
我想将每个testNode添加到子图中,并计算testNode中存在的三角形

val triangles: RDD[(Long,Int)] = testNodes.map{ newNode =>
  val newNodes: Array[Long] = baseNodes :+ newNode
  val newSubgraph = graph.subgraph(vpred = (vid,attr)=> newNodes contains vid)
  (newNode,findTriangles(7L,newSubgraph))
}
triangles.foreach(x=>x.toString)
如果我在map函数之外调用findTriangles,它就可以正常工作

def findTriangles(id:Long,subgraph:Graph[String,String]): Int = {
  val triCounts = subgraph.triangleCount().vertices
  val count:Int = triCounts.filter{case(item,count)=> {item.toInt == id}}.map{case(item,count)=>count}.first
  count
}
val triangles = findTriangles(7L,subgraph) //1

但是当我运行map函数来计算三角形时,我得到了一个NullPointerException。我认为问题在于在映射函数中使用graph val。这就是问题所在吗?有办法解决这个问题吗?

我认为问题应该是baseNodes变量。本地声明的变量(例如示例中的baseNodes)仅在Spark驱动程序中可见,而在实际执行转换和操作的执行器中不可见。为了避免NullPointerException,您需要并行化在执行器上执行的转换(如map)中所需的任何变量。或者,如果您拥有的变量是只读的,则可以使用Spark中的广播构造将该变量广播给执行器。在您的例子中,baseNodes似乎没有在映射操作中得到修改,因此它是广播而不是并行化的一个很好的候选对象。

您不能在另一个
RDD中处理
'RDD
。这不仅限于
GraphX
——这是对
RDD
s的限制,因为
GraphX
是建立在
RDD
上的,这是您的问题。长话短说——执行者对您的其他
RDD
s一无所知,因此出现了
NPE
。一般来说,解决这一问题的方法是加入——我还没有深入了解您试图做什么,但这是总体思路。谢谢您的回复!在你的回答和大卫·格里芬的评论之间,我能够找出我的问题。广播解决了非RDD变量的问题,但由于GraphX中的图形是基于RDD构建的,因此无法在另一个map函数中访问它们。graphx似乎是为了在内存中的单个大型图上进行缩放而构建的,而不是将同一个图的副本分发给多个执行器。因为我的图形并不是非常大,所以我抛弃了graphx,将图形存储为数组和贴图,并实现了我自己的三角形计数,允许我广播图形