通讯录数据,一直是各个app平台的重要数据来源。通讯录组成的图谱关系分析是大数据部门必做的一件事,因为他可以为推荐算法工程师提供更好的数据支持。
图数据存储有很多种方式:
基本的一种方式就是存储到关系型数据仓储中。这种存储方式的优点是,数据仓储模型简单易于实现且对于一度关系查询也很方便。但是对于二度关系则需要自join一次,三度好友分析则需要自join两次,对于多度分析十分消耗性能。
另外一种是基于开源框架neo4j等图数据实现图数据的存储,不进能够实现多度快速查询,还能对图进行渲染。但是neo4j社区版本仅能够支持千万级别的点,商业版本收费太高
对于数据量很大,但是又不想使用付费版本的图数据,但又想要实现图数据的快速索引。现提供一种方案,sparkGraphx+hbase+hive实现的图数据预计算平台。原始数据存储增量存储在hive中,批次使用graphx将hive中图数据做一度,二度...n度预处理计算,结果存储到hbase/solr中已达到实时查询图数据的目的。
以下是基于sparkGraphx实现图数据的一度全向索引,二度(正正,反反,正反,反正)索引的计算方案。
【注】:
searchByPatch方法是路径索引,eg:传入1就是一度正向,-1,1二度正向反向索引,-1,1,1三度路径的反向正向正向索引
数据格式:
1 2
2 1
3 1
第一行表示用户1存储了用户2的联系方式
package mob import org.apache.spark.graphx.{Edge, Graph, VertexId} import org.apache.spark.rdd.RDD import org.apache.spark.storage.StorageLevel import org.apache.spark.{SparkConf, SparkContext} object OperatorFun { def transforEdge(edgeString: String): List[Edge[String]] = { val edges = edgeString.trim.replaceAll(" +", " ") val vertexs = edges.toString.split(" ") if (vertexs.length == 2 && vertexs(0) != vertexs(1)) { return List(Edge(vertexs(0).toLong, vertexs(1).toLong, "")); } return List[Edge[String]]() } } object FriendSearch { /** * 构建图 * * @param edgeFilePath * @return */ def loadGraph(edgeFilePath: String): Graph[String, String] = { val conf = new SparkConf().setAppName("graph").setMaster("local") val sc = new SparkContext(conf) val edgeRDD = sc.textFile(edgeFilePath).flatMap(OperatorFun.transforEdge(_)).distinct() val graph: Graph[Long,