图存储及图计算

图结构

图是一种较线性表和树更为复杂的数据结构,线性表和树分别表现的是一对一和一对多的关系,而图则表达的是多对多的关系。

概念:顶点、边、度(Degree):与顶点关联的边数量、出度(有向图顶点出边数量)、入度(有向图顶点入边数量)、有向图(边有方向)、无向图(边无方向)、连通图(多个顶点组成的图中任意两个顶点相连)、强联通(多个顶点组成的图中任意两个顶点 Vm、Vn 且 m ≠ n,从 Vm 到 Vn 以及从 Vn 到 Vm 之间都存在通路)、路径(任意两个顶点之间若存在通路)、回路或环(路径第一个顶点和最后一个顶点相同)

图存储

邻接矩阵:表示顶点之间相邻关系的矩阵,若图有 n 个顶点,则矩阵大小为 n * n。其中矩阵的行标为起点,列标为终点。(占用存储过大)

邻接表:表示图的一种链式存储结构,每个顶点建立一个单链表,每个单链表中保存了所有依附于该顶点的边,每个单链表中的结点由三个域组成:邻接点域、链域和数据域。对有向图入度计算需要遍历整个图,可以通过建立一个逆邻接表解决。(对于无向图来说,当同一条边(Vm、Vn)存在于第 m 个链表与第 n 个链表中时,修改图并不是特别方便)

邻接多重表:分为两个表:顶点表和边表。边表:mark 为标志域,可以用来标记该条边是否被搜索过;ivex 和 jvex 为该条边的起点和终点,ilink 指向下一条顶点 ivex 的出边;jlink 指向下一条以顶点 jvex 的入边,info 保存和边相关的信息。顶点表:data 域保存了和该顶点相关的信息,firstedge 域指向该顶点的第一条出边。(Neo4j 采用该结构存储数据)

十字链表:将邻接表和逆邻接表结合起来的数据结构。分为顶点表和边表。边表:tailvex 和 headvex 为边的起点和终点,hlink 指向下一条顶点 tailvex 的出边;tlink 指向下一条以headvex为顶点的入边。顶点表:data 域保存了和该顶点相关的信息,firstIn 和 firstOut 是两个指针域,分别指向该顶点的第一条入边和第一条出边。(同邻接多重表的不同在于顶点表多了表示第一条入边的指针域)

边集数组:利用一维数组存储图中所有边的图表示方法,该数组中每个元素都用来存储一条边的起点、终点和边属性。边集数组通常包括一个边数组和一个顶点数组。这种方式非常适合将数据进行分区,所以 GraphX 以及很多图数据库都采取这种方式存储数据。

图计算场景及产品及技术

OLTP(事务场景):通常由图数据库负责。图数据库包括:Neo4j(Cypher语言)、TigerGraph、Nebula(nGQL)、JanusGraph(Gremlin)

        Apache TinkerPop与 Gremlin:TinkerPop 是一个开源的、面向集成的图计算框架,它包含一系列的组件,分别是:Blueprints、Pipes、Frames、Furnace、Rexster 和 Gremlin。Gremlin是 TinkerPop 的图查询语言。基于TinkerPop使用 NoSQL 数据库作为存储引擎的产品有 Titan、JanusGraph。

OLAP(分析场景):离线处理,通常由计算框架处理。

Pregel:Google 于 2010 年在 SIGMOD 会议上发表的《Pregel: A System for Large-Scale Graph Processing》论文中提到的海量并行图挖掘的抽象框架,Pregel 与 Dremel 一样,是 Google 新三驾马车之一,它基于 BSP 模型(Bulk Synchronous Parallel,整体同步并行计算模型),将计算分为若干个超步(super step),在超步内,通过消息来传播顶点之间的状态

NetworkX:用 Python 语言开发的图论与复杂网络建模工具,内置了常用的图与复杂网络分析算法,可以很方便地进行复杂网络数据分析、仿真建模等工作。(处理的数据规模通常在百万顶点以内)

GraphX:处理的数据量可以随着计算能力的增加而线性增长,十亿百亿顶点规模的图对于 GraphX 来说不在话下。NetwrokX 对算法的封装程度很高,开箱即用,GraphX则更加底层。

GraphFrame:由Databricks、UC Berkeley以及MIT联合为Apache Spark开发了一款图处理类库,名为GraphFrames。该类库构建在DataFrame之上,既能利用DataFrame良好的扩展性和强大的性能,同时也为Scala、Java和Python提供了统一的图处理API。

GraphX

GraphX核心数据结构:用属性图的方式表示图,顶点有属性,边有属性。存储结构采用的是边集数组的形式,即一个顶点表,一个边表。

GraphX图分区:分区对于 RDD 来说是一个很重要的概念。它体现了并行的理念,是分布式计算的基础。两种方式:边切割与顶点切割。在边切割中,边有冗余;在顶点切割中,顶点有冗余。与边切割相比,顶点切割可以减少通信与存储开销。在 Graph 中的边表其实就是顶点切割的实现。所以在 GraphX 中采取的是顶点切割的方式对图进行分区。

GraphX 提供了 4 种分区策略:

EdgePartition1D:保证了同一个顶点的出边一定在同一个分区中。

EdgePartition 2D:将边表看成一个邻接矩阵,行标是边起点ID,列标是终点ID,分区是对该矩阵进行分块。

RandomVertexCut:对边表进行随机分区,这种方式可以实现边的完全负载均衡,但是对于度分布为幂律分布的图来说,很容易出现数据倾斜的问题。

CanonicalRandomVertexCut:同RandomVertexCut类似,但它能保证两点之间的边在同一个分区。

GraphX 可以认为是 Pregel 的开源实现。

GraphFrame

GraphFrames是类似于Spark的GraphX库,支持图处理。但GraphFrames建立在Spark DataFrame之上:

  • 支持Scala,Java 和Python AP:GraphFrames提供统一的三种编程语言APIs,

  • 方便、简单的图查询:GraphFrames允许用户使用Spark SQL和DataFrame的API查询。

  • 23
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

larry_seven

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值