使用graphx构建的图形无法正确播放

时间:2016-06-07 08:04:28

标签: scala apache-spark spark-graphx

我使用graphx创建了一个图形,现在我需要从原始图形中提取子图形。 users_graph是一个RDD,它有一个索引给用户的子图。问题是这些子图没有得到计算。当我尝试操作这些子图时,我得到了一个java.lang.NullPointerException异常。

class VertexProperty(val id:Long) extends Serializable
case class User(val userId:Long, var offset:Int, val userCode:String, val Name:String, val Surname:String, val organizational_unit:String, val UME:String, val person_type:String, val SOD_HIGH:String, val SOD_MEDIUM:String, val SOD_LOW:String, val Under_mitigated:String) extends VertexProperty(userId)
case class Account(val accountId:Long, var offset:Int, val userCode:String, val userId:String, val account_creation_date:String, var disabled:String, var forcechangepwd:String, var pwdlife:String, var numberloginerror:String, var lastchangepwd:String, var lastlogin:String, var lastwronglogin:String, var state:String, var expire:String, var last_cert_time:String, var creation_date:String, var creation_user:String,var challenge_counter:String, var challenge_failed_attempt:String) extends VertexProperty(accountId) //Check if userCode is actually the code in this example.
case class Application(var applicationId:Long, var offset:Int, var Name:String, var Description:String, var Target:String, var Owner:String, var Ownercode:String, var Creation_date:String, var Creation_user:String) extends VertexProperty(applicationId)
case class Entitlement(val entitlementId:Long, var offset:Int, val Name:String, var Code:String, var Description:String, var Type:String, var Application:String, var Administrative:String, var Parent_ID:String, var Owner_code:String, var Scope_type:String, var Business_name:String, var Business_policy:String, var SOD_high:String, var SOD_medium:String, var SOD_low:String) extends VertexProperty(entitlementId)

/*
Some code for computing vertexRDD and edges
*/    

val graph: Graph[VertexProperty,String] = Graph(vertexRDD, edges, new VertexProperty(-1))
val triplets = graph.triplets
val temp = triplets.map(t => t.attr)
val distinct_users = temp.distinct.filter(t => t != "NULL")

var bcast_graph = sc.broadcast(graph)
val users_graph = distinct_users.map(du => du -> bcast_graph.value.subgraph(epred = t => t.attr == du))

1 个答案:

答案 0 :(得分:2)

长话短说,你不能broadcast Graph因为它包含RDD(实际上是其中几个)。并且您无法在Graph上的map函数中使用RDD,因为它由RDDs组成。

就像我说的,这是一个很长的故事,为什么你不能做其中任何一个 - 而且他们真的是同一枚硬币的两面。无论哪种方式,你都面临同样的问题。

Spark基于主/从概念。它位于主存储器空间中RDDs,并定义了与它们相关的元操作。但是代码 - ...里面map(...) - 在从属服务器上执行(称为执行程序)。当您以任何方式引用其他RDD时,您的地图代码无法在执行程序内运行 - broadcast永远不会有帮助,因为RDD引用只能存在于主数据库中

你能做什么呢?您有两种选择:

  1. 使用collect()broadcast数据收集您需要的数据,或者只在map代码中引用它。 collect()将所有数据提取到主数据库中,但最重要的是,对于您的问题,这意味着您现在可以在不使用RDD引用的情况下引用数据,因此您可以将收集的数据发送给执行程序 - 使用broadcast或仅在map(...)代码中引用它们(Spark会将数据副本发送给执行者)。以下哪项有效 - 或者是否有 - 取决于您的数据大小,速度预期等等。
  2. 使用RDD.join()RDD.cogroup()同时处理两个Graphs
  3. 由于您正在处理更高阶的结构 - GraphX Graph,因此这两者都很复杂。您将需要单独处理单独的Graph.verticesGraph.edges RDDs,执行collect()join(),然后重新构建最终Graph 1}}通过将适当的RDDs拼接在一起。