引言

  在了解GraphX之前,需要先了解关于通用的分布式图计算框架的两个常见问题:图存储模式和图计算模式。

图存储模式

  巨型图的存储总体上有边分割和点分割两种存储方式。2013年,GraphLab2.0将其存储方式由边分割变为点分割,在性能上取得重大提升,目前基本上被业界广泛接受并使用。

边分割(Edge-Cut)

  每个顶点都存储一次,但有的边会被打断分到两台机器上。这样做的好处是节省存储空间;坏处是对图进行基于边的计算时,对于一条两个顶点被分到不同机器上的边来说,要跨机器通信传输数据,内网通信流量大。

点分割(Vertex-Cut)

  每条边只存储一次,都只会出现在一台机器上。邻居多的点会被复制到多台机器上,增加了存储开销,同时会引发数据同步问题。好处是可以大幅减少内网通信量。

对比

  虽然两种方法互有利弊,但现在是点分割占上风,各种分布式图计算框架都将自己底层的存储形式变成了点分割。主要原因有以下两个。

  磁盘价格下降,存储空间不再是问题,而内网的通信资源没有突破性进展,集群计算时内网带宽是宝贵的,时间比磁盘更珍贵。这点就类似于常见的空间换时间的策略。

  在当前的应用场景中,绝大多数网络都是“无尺度网络”,遵循幂律分布,不同点的邻居数量相差非常悬殊。而边分割会使那些多邻居的点所相连的边大多数被分到不同的机器上,这样的数据分布会使得内网带宽更加捉襟见肘,于是边分割存储方式被渐渐抛弃了。

图计算模式

  目前的图计算框架基本上都遵循BSP(Bulk Synchronous Parallell)计算模式。Bulk Synchronous Parallell,即整体同步并行,它将计算分成一系列的超步(superstep)的迭代(iteration)。从纵向上看,它是一个串行模型,而从横向上看,它是一个并行的模型,每两个superstep之间设置一个栅栏(barrier),即整体同步点,确定所有并行的计算都完成后再启动下一轮superstep。

超步

  每一个超步(superstep)包含三部分内容:

  1. 计算compute,每一个processor利用上一个superstep传过来的消息和本地的数据进行本地计算;
  2. 消息传递,每一个processor计算完毕后,将消息传递个与之关联的其它processors;
  3. 整体同步点,用于整体同步,确定所有的计算和消息传递都进行完毕后,进入下一个superstep。

Pregel模型——像顶点一样思考

  Pregel借鉴MapReduce的思想,采用消息在点之间传递数据的方式,提出了“像顶点一样思考”(Think Like A Vertex)的图计算模式,采用消息在点之间传递数据的方式,让用户无需考虑并行分布式计算的细节,只需要实现一个顶点更新函数,让框架在遍历顶点时进行调用即可。

常见的代码模板如下:

上图简要地描述了Pregel的计算模型:

  1. master将图进行分区,然后将一个或多个partition分给worker;
  2. worker为每一个partition启动一个线程,该线程轮询partition中的顶点,为每一个active状态的顶点调用compute方法;
  3. compute完成后,按照edge的信息将计算结果通过消息传递方式传给其它顶点;
  4. 完成同步后,重复执行2,3操作,直到没有active状态顶点或者迭代次数到达指定数目。

这个模型虽然简洁,但很容易发现它的缺陷。对于邻居数很多的顶点,它需要处理的消息非常庞大,而且在这个模式下,它们是无法被并发处理的。所以对于符合幂律分布的自然图,这种计算模型下很容易发生假死或者崩溃。

作为第一个通用的大规模图处理系统,pregel已经为分布式图处理迈进了不小的一步,这点不容置疑,但是pregel在一些地方也不尽如人意:

  1. 在图的划分上,采用的是简单的hash方式,这样固然能够满足负载均衡,但是hash方式并不能根据图的连通特性进行划分,导致超步之间的消息传递开销可能会是影响性能的最大隐患。
  2. 简单的checkpoint机制只能向后式地将状态恢复到当前S超步的几个超步之前,要到达S还需要重复计算,这其实也浪费了很多时间,因此如何设计checkpoint,使得只需重复计算故障worker的partition的计算节省计算甚至可以通过checkpoint直接到达故障发生前一超步S,也是一个很需要研究的地方。
  3. BSP模型本身有其局限性,整体同步并行对于计算快的worker长期等待的问题无法解决。
  4. 由于pregel目前的计算状态都是常驻内存的,对于规模继续增大的图处理可能会导致内存不足,如何解决尚待研究。

GAS模型——邻居更新模型

相比Pregel模型的消息通信范式,GraphLab的GAS模型更偏向共享内存风格。它允许用户的自定义函数访问当前顶点的整个邻域,可抽象成Gather、Apply和Scatter三个阶段,简称为GAS。相对应,用户需要实现三个独立的函数gather、apply和scatter。常见的代码模板如下所示:

由于gather/scatter函数是以单条边为操作粒度,所以对于一个顶点的众多邻边,可以分别由相应的worker独立调用gather/scatter函数。这一设计主要是为了适应点分割的图存储模式,从而避免Pregel模型会遇到的问题。

  1. Gather阶段
    工作顶点的边(可能是所有边,也有可能是入边或者出边)从领接顶点和自身收集数据,记为gather_data_i,各个边的数据graphlab会求和,记为sum_data。这一阶段对工作顶点、边都是只读的。
  2. Apply阶段
    Mirror将gather计算的结果sum_data发送给master顶点,master进行汇总为total。Master利用total和上一步的顶点数据,按照业务需求进行进一步的计算,然后更新master的顶点数据,并同步mirror。Apply阶段中,工作顶点可修改,边不可修改。
  3. Scatter阶段
    工作顶点更新完成之后,更新边上的数据,并通知对其有依赖的邻结顶点更新状态。这scatter过程中,工作顶点只读,边上数据可写。

在执行模型中,graphlab通过控制三个阶段的读写权限来达到互斥的目的。在gather阶段只读,apply对顶点只写,scatter对边只写。并行计算的同步通过master和mirror来实现,mirror相当于每个顶点对外的一个接口人,将复杂的数据通信抽象成顶点的行为。

Spark学习之路 (二十八)分布式图计算系统[转]的更多相关文章

  1. Spark学习之路 (十八)SparkSQL简单使用

    一.SparkSQL的进化之路 1.0以前: Shark 1.1.x开始: SparkSQL(只是测试性的)  SQL 1.3.x: SparkSQL(正式版本)+Dataframe 1.5.x: S ...

  2. Spark学习之路 (十八)SparkSQL简单使用[转]

    SparkSQL的进化之路 1.0以前: Shark 1.1.x开始: SparkSQL(只是测试性的) SQL 1.3.x: SparkSQL(正式版本)+Dataframe 1.5.x: Spar ...

  3. FastAPI 学习之路(十八)表单与文件

    系列文章: FastAPI 学习之路(一)fastapi--高性能web开发框架 FastAPI 学习之路(二) FastAPI 学习之路(三) FastAPI 学习之路(四) FastAPI 学习之 ...

  4. Dynamic CRM 2013学习笔记(二十八)用JS动态设置字段的change事件、必填、禁用以及可见

    我们知道通过界面设置字段的change事件,是否是必填,是否可见非常容易.但有时我们需要动态地根据某些条件来设置,这时有需要通过js来动态地控制了. 下面分别介绍如何用js来动态设置.   一.动态设 ...

  5. Spark学习之路 (十六)SparkCore的源码解读(二)spark-submit提交脚本

    一.概述 上一篇主要是介绍了spark启动的一些脚本,这篇主要分析一下Spark源码中提交任务脚本的处理逻辑,从spark-submit一步步深入进去看看任务提交的整体流程,首先看一下整体的流程概要图 ...

  6. Spark学习之路 (十二)SparkCore的调优之资源调优

    摘抄自:https://tech.meituan.com/spark-tuning-basic.html 一.概述 在开发完Spark作业之后,就该为作业配置合适的资源了.Spark的资源参数,基本都 ...

  7. Spark学习之路(十二)—— Spark SQL JOIN操作

    一. 数据准备 本文主要介绍Spark SQL的多表连接,需要预先准备测试数据.分别创建员工和部门的Datafame,并注册为临时视图,代码如下: val spark = SparkSession.b ...

  8. Spark学习之路 (十二)SparkCore的调优之资源调优[转]

    概述 在开发完Spark作业之后,就该为作业配置合适的资源了.Spark的资源参数,基本都可以在spark-submit命令中作为参数设置.很多Spark初学者,通常不知道该设置哪些必要的参数,以及如 ...

  9. Spark学习之路 (十)SparkCore的调优之Shuffle调优

    摘抄自https://tech.meituan.com/spark-tuning-pro.html 一.概述 大多数Spark作业的性能主要就是消耗在了shuffle环节,因为该环节包含了大量的磁盘I ...

  10. Spark学习之路(十五)—— Spark Streaming 整合 Flume

    一.简介 Apache Flume是一个分布式,高可用的数据收集系统,可以从不同的数据源收集数据,经过聚合后发送到分布式计算框架或者存储系统中.Spark Straming提供了以下两种方式用于Flu ...

随机推荐

  1. JVM性能优化系列-(4) 编写高效Java程序

    4. 编写高效Java程序 4.1 面向对象 构造器参数太多怎么办? 正常情况下,如果构造器参数过多,可能会考虑重写多个不同参数的构造函数,如下面的例子所示: public class FoodNor ...

  2. Python 调用 Shell命令

    python程序中调用shell命令,是件很酷且常用的事情今天来总结一下   1.使用os模块 的  system         此函数会启动子进程,在子进程中执行command,并返回comman ...

  3. 我说我了解集合类,面试官竟然问我为啥HashMap的负载因子不设置成1!?

    在Java基础中,集合类是很关键的一块知识点,也是日常开发的时候经常会用到的.比如List.Map这些在代码中也是很常见的. 个人认为,关于HashMap的实现,JDK的工程师其实是做了很多优化的,要 ...

  4. 杭电-------2032杨辉三角(C语言写)

    #include<stdio.h> ][] = { }; void init() { int i, j; ; i < ; i++) { a[i][] = ; a[i][i] = ; ...

  5. pymongo(看后转载,在原基础上添加了类连接和简单调用)

    一.MongoDB 数据库操作 1. 连接数据库 import pymongo conn = pymongo.Connection() # 连接本机数据库 # conn = pymongo.Conne ...

  6. 微信小程序仿朋友圈功能开发(发布、点赞、评论等功能)

    微信小程序仿朋友圈功能开发(发布.点赞.评论等功能) 1.项目分析 项目整体分为三个部分 发布 展示 详情页 graph LR 朋友圈发布 --内容发布--> 内容展示 内容展示 --点击展示卡 ...

  7. django 中 cookie与session 相关的知识

    cookie :它是一个字典  

  8. c语言标准I/O

    头文件 <stdio.h> 打开/关闭文件 FILE *fopen(char *filename, char *mode); 如果正常打开返回FILE指针,否则返回NULL mode常用值 ...

  9. Javascript 基础学习(四)js 的语句

    由于程序都是自上向下的顺序执行的,所以通过流程控制语句可以改变程序执行的顺序,或者反复的执行某一段的程序. 语句的分类 条件判断语句 条件分支语句 循环语句 条件判断语句 条件判断语句也称为if语句 ...

  10. 非常简洁简单的tcp socket库 XKSocket

    一个非常简洁简单的异步tcp socket库,主要就是分包的问题,处理组包,粘包等问题 非常适合新手:) 项目中带有使用示例. http://git.oschina.net/dreamzgj/XKSo ...