Spark GraphX Scala代码中numVertices始终返回0的问题咨询
Spark GraphX中numVertices返回0的问题解决
我尝试实现一段Spark GraphX的Scala示例代码,执行后numVertices始终返回0,但预期结果应为6,代码如下:
import org.apache.spark._ import org.apache.spark.graphx._ val conf = new SparkConf().setAppName("GraphX Example") val sc = new SparkContext(conf) // 创建顶点RDD val verticesRDD = sc.parallelize(Seq((-1L, "nowhere"), (1L, "yahou"), (2L, "sanae"), (3L, "hanane"), (4L, "said"), (5L, "halima"))) // 创建边RDD val edgesRDD = sc.parallelize(Seq(Edge(1L, 3L, "commenter"), Edge(1L, 3L, "suivre"), Edge(2L, 3L, "commenter"), Edge(2L, 5L, "connecter"), Edge(4L, 2L, "connecter"))) // 使用默认顶点创建图 val graph = Graph(verticesRDD, edgesRDD, "nowhere") graph.vertices.collect.foreach(println) graph.edges.collect.foreach(println) val numVertices = graph.numVertices val numEdges = graph.numEdges println(s"Number of vertices: $numVertices") println(s"Number of edges: $numEdges")
问题原因
numVertices是GraphX中的延迟计算属性,它依赖Spark Job触发来统计顶点数量。虽然代码中调用了graph.vertices.collect,但默认情况下RDD不会自动缓存,后续计算numVertices时会重新执行顶点RDD的计算流程,在部分环境或Spark版本下可能出现计算异常,导致返回0。
解决方法
有两种可靠的修复方式:
- 直接使用行动操作替代延迟属性:用
graph.vertices.count()替代graph.numVertices,count()是Spark的行动操作,会立即触发计算并返回准确的顶点数量。 - 缓存顶点RDD避免重复计算:在调用
graph.numVertices前执行graph.vertices.cache(),后续计算会复用缓存结果,避免重复计算带来的异常。
修改后的代码示例:
import org.apache.spark._ import org.apache.spark.graphx._ val conf = new SparkConf().setAppName("GraphX Example") val sc = new SparkContext(conf) // 创建顶点RDD val verticesRDD = sc.parallelize(Seq((-1L, "nowhere"), (1L, "yahou"), (2L, "sanae"), (3L, "hanane"), (4L, "said"), (5L, "halima"))) // 创建边RDD val edgesRDD = sc.parallelize(Seq(Edge(1L, 3L, "commenter"), Edge(1L, 3L, "suivre"), Edge(2L, 3L, "commenter"), Edge(2L, 5L, "connecter"), Edge(4L, 2L, "connecter"))) // 使用默认顶点创建图 val graph = Graph(verticesRDD, edgesRDD, "nowhere") graph.vertices.collect.foreach(println) graph.edges.collect.foreach(println) // 方法1:用count()替代numVertices(推荐) val numVertices = graph.vertices.count() val numEdges = graph.edges.count() // 方法2:先缓存再获取numVertices // graph.vertices.cache() // val numVertices = graph.numVertices // val numEdges = graph.numEdges println(s"Number of vertices: $numVertices") println(s"Number of edges: $numEdges")
修改后即可得到预期的6个顶点、5条边的结果。
内容的提问来源于stack exchange,提问作者EL MEHDI EL JAOUHARI
相关产品推荐
相关产品推荐

