最近在做文本处理知识的梳理,关注了CMU提出的GraphLab开源分布式计算系统

这是关于GraphLab的PPT:Distributed GraphLab『

http://cheng-qihang-shenzhen.oss-cn-shenzhen.aliyuncs.com/thesis%2ftest_processing%2fdistributed%20graphlab.pdf

这是CMU的Select实验室发布的一片相关论文:GraphLab A Distributed Framework forMachine Learning in the Cloud『

http://cheng-qihang-shenzhen.oss-cn-shenzhen.aliyuncs.com/thesis%2ftest_processing%2fgraphlab%20a%20distributed%20framework%20formachine%20learning%20in%20the%20cloud.pdf

1.1 GraphLab简介

在海量数据盛行的今天,大规模并行计算已经随处可见,尤其是MapReduce框架的出现,促进了并行计算在互联网海量数据处理中的广泛应用。而针对海量数据的机器学习对并行计算的性能、开发复杂度等提出了新的挑战。

机器学习的算法具有下面两个特点:数据依赖性强,运算过程各个机器之间要进行频繁的数据交换;流处理复杂,整个处理过程需要多次迭代,数据的处理条件分支多。

而MapReduce是典型的SIMD模型,Map阶段集群的各台机器各自完成负载较重的计算过程,数据并行度高,适合完成类似矩阵运算、数据统计等数据独立性强的计算,而对于机器学习类算法并行性能不高。

另一个并行实现方案就是采用纯MPI(Native MPI)的方式。纯MPI实现通过精细的设计将并行任务按照MPI协议分配到集群机器上,并根据具体应用,在计算过程中进行机器间的数据通信和同步。纯MPI的优点是,可以针对具体的应用,进行深度优化,从而达到很高的并行性能。但纯MPI存在的问题是,针对不同的机器学习算法,需要重写其数据分配、通信等实现细节,代码重用率低,机器拓展性能差,对编程开发人员的要求高,而且优化和调试成本高。因而,纯MPI不适合敏捷的互联网应用。

为解决机器学习的流处理,Google提出了Pregel框架,Pregel是严格的BSP模型,采用“计算-通信-同步”的模式完成机器学习的数据同步和算法迭代。Goolge曾称其80%的程序使用MapReduce完成,20%的程序使用Pregel实现。因而,Pregel是很成熟的机器学习流处理框架,但Google一直没有将Pregel的具体实现开源,外界对Pregel的模仿实现在性能和稳定性方面都未能达到工业级应用的标准。

2010年,CMU的Select实验室提出了GraphLab框架,GraphLab是面向机器学习的流处理并行框架[1]。同年, GraphLab基于最初的并行概念实现了1.0版本,在机器学习的流处理并行性能方面得到很大的提升,并引起业界的广泛关注,在2012年GraphLab升级到2.1版本,进一步优化了其并行模型,尤其对自然图的并行性能得到显著改进。

在本章的余下章节,将详细介绍GraphLab的并行框架和具体的源码实现。

1.2 GraphLab并行框架

GraphLab将数据抽象成Graph结构,将算法的执行过程抽象成Gather、Apply、Scatter三个步骤。其并行的核心思想是对顶点的切分,以下面的例子作为一个说明。

1. Graph对并行思想

示例中,需要完成对V0邻接顶点的求和计算,串行实现中,V0对其所有的邻接点进行遍历,累加求和。而GraphLab中,将顶点V0进行切分,将V0的边关系以及对应的邻接点部署在两台处理器上,各台机器上并行进行部分求和运算,然后通过master顶点和mirror顶点的通信完成最终的计算。

1.2.1 数据模型:GRAPH

顶点是其最小并行粒度和通信粒度,边是机器学习算法中数据依赖性的表现方式。

对于某个顶点,其被部署到多台机器,一台机器作为master顶点,其余机器上作为mirror。Master作为所有mirror的管理者,负责给mirror安排具体计算任务;mirror作为该顶点在各台机器上的代理执行者,与master数据的保持同步。

对于某条边,GraphLab将其唯一部署在某一台机器上,而对边关联的顶点进行多份存储,解了边数据量大的问题。

同一台机器上的所有edge和vertex构成local graph,在每台机器上,存在本地id到全局id的映射表。vertex是一个进程上所有线程共享的,在并行计算过程中,各个线程分摊进程中所有顶点的gather->apply->scatter操作。

下面这个例子说明,GraphLab是怎么构建Graph的。

图2 Graph的构建形式

1.2.2 执行模型:GATHER-APPLY-SCATTER

每个顶点每一轮迭代经过gather->apple->scatter三个阶段。

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相当于每个顶点对外的一个接口人,将复杂的数据通信抽象成顶点的行为。

下面这个例子说明GraphLab的执行模型:

图3. Gather-Apply-Scatter

1.3 GraphLab的源码实现

Graphlab的实现可以分为四层:基础组件层,抽象层,引擎层,应用层。

4. GraphLab源码结构

1.3.1 基础组件层

提供Graphlab数据传输、多线程管理等基础并行结构的组件模块,下面将主要介绍其通信、数据序列化、数据交换、多线程管理四个功能模块。

1)       通信(dc_tcp_comm.cpp)

Graphlab基于TCP协议的长连接在机器之间进行数据通信。在Graphlab初始化阶段,所有机器建立连接,将socket数据存储在std::vector<socket_info> sock 结构中。

Graphlab使用单独的线程来接收和发送数据,其中接收或发送都可以配置多个线程,默认每个线程中负责与64台机器进行通信。在接收连接中,tcp_comm基于libevent采用epoll的方式获取连接到达的通知,效率高。将这部分抽象成以下伪代码:

listen();

for(size_t i = 0;i < nprocs; ++i)

connect(i);

while{

wait_for_connect();

}

in_thread_num=machine_num / proc_per_thread;

  • out_thread_num= machine_num / proc_per_thread;

for(每一个线程)

{

event_add();

}

for(每一个线程)

{

event_add();

}

for(每一个线程)

{

In_thread.launch(receive_loop);

}

for(每一个线程)

{

In_thread.launch(send_loop)

}

需要补充的是,Graphlab在数据通信中,并没有采用MPI的接口,但在源码中封装了MPI_tools,其用途是在distributed_control::init时,获取系统参数(包括机器IP和端口)提供两种方式,一种是系统配置中初始化,一种是通过MPI接口实现(dc_init_from_mpi::init_param_from_mpi)。

2)       数据序列化(oarchive & iarchive)

Oarchive通过重载操作符>>将对象序列化后写入ostream中,在Graphlab中对于POD( Plain Old Data)和非POD数据区分对待, POD类型的数据直接转为为char*写入ostream, 而非POD数据需要用户实现save方法,否则将抛出异常。iarchive的过程与oarchive的过程相反。

所有通过rpc传输的数据都通过oarchive和iarchive转化为stream,比如vertex_program, vertex_data。

图5. 数据序列化

3)       数据传输流(buffered_stream_send2.cpp)

Oarchive,iarchive是数据序列化的工具, 在实际的传输过程中,数据并没有立即发送出去,而是缓存在buffered_stream_send。

4)       Pthread_tools:

Thread类封装了lpthread的方法

提供thread_group管理线程队列

封装了锁、信号量、条件变量等同步方法。

1.3.2 抽象层

1)      dc_dist_object是GraphLab对所有分布式对象的一个抽象,其目标是将分布式处理的数据对象对用户抽象成普通对象,以希望在使用的时候不需要关心其分布式细节。

2)      buffer_exchange是基于dc_dist_object对需要在顶点间交换的数据提供一个容器。

3)      distribute_controller是基于dc_dist_object实现的一个整个分布式系统的控制器,提供了机器数据、顶点关系等全局信息。

1.3.3引擎层

1.3.3.1同步引擎

图6. 同步引擎

1) Excange message阶段,master接受来⾃自mirror的消息;

2) Receive Message阶段,master接收上一轮Scatter发送的消息和mirror发送的消息,将有message的master激活, 对于激活的顶点,master通知mirror激活,并将vectex_program同步到mirrors;

3) Gather阶段,多线程并行gather, 谁先完成,多线程并行localgraph中的顶点,mirror将gather的结果到master;

4) Apply阶段,master执行apply(apply()),并将apply的结果同步到mirror (sync_vertex_data()).

5)Scatter阶段,master和mirror基于新的顶点数据,更新边上数据,并以signal的形式通知相邻顶点。

下面这个例子形象地说明了同步引擎的工作过程:

图7. 顶点2的GraphLab执行过程

1.3.3.2异步引擎

8. mastermirror状态转移过程

异步引擎中,每个顶点是消息驱动的状态机。

1) 在每一轮执行开始时,Master从全局的调度器(Sceduler)获取消息,获取消息后,master获得锁,并进入Locking状态。同时,master通知mirror获取锁,进入Locking状态。

2) master和mirror分别进行Gathering操作,mirror将gathering结果汇报给master,由master完成汇总。

3) master完成applying之后,将结果同步到mirror上。

4) master和mirror独立的执行scattering,执行完成之后释放锁进入None状态,等待新的任务到来。

5) mirror在scattering状态时,可能再次接收到来自master的locking请求,这种情况下,mirror在完成scattering之后将不会释放锁,而直接进入下一轮任务中。

GraphLab面向机器学习的并行框架『针对图数据处理模型』的更多相关文章

  1. GraphLab:新的面向机器学习的并行框架

    大规模图数据计算引起了许多知名公司的关注,微软提出了用于图数据匹配的Horton - Querying Large Distributed Graphs(Link:http://research.mi ...

  2. 深度神经网络DNN的多GPU数据并行框架 及其在语音识别的应用

    深度神经网络(Deep Neural Networks, 简称DNN)是近年来机器学习领域中的研究热点,产生了广泛的应用.DNN具有深层结构.数千万参数需要学习,导致训练非常耗时.GPU有强大的计算能 ...

  3. 【深度学习系列2】Mariana DNN多GPU数据并行框架

    [深度学习系列2]Mariana DNN多GPU数据并行框架  本文是腾讯深度学习系列文章的第二篇,聚焦于腾讯深度学习平台Mariana中深度神经网络DNN的多GPU数据并行框架.   深度神经网络( ...

  4. Asp.net 面向接口可扩展框架之数据处理模块及EntityFramework扩展和Dapper扩展(含干货)

    接口数据处理模块是什么意思呢?实际上很简单,就是使用面向接口的思想和方式来做数据处理. 还提到EntityFramework和Dapper,EntityFramework和Dapper是.net环境下 ...

  5. Asp.net 面向接口可扩展框架之消息队列组件

    消息队列对大多数人应该比较陌生.但是要提到MQ听说过的人会多很多.MQ就是英文单词"Message queue"的缩写,翻译成中文就是消息队列(我英语差,翻译错了请告知). PS: ...

  6. NHibernate框架与BLL+DAL+Model+Controller+UI 多层架构十分相似--『Spring.NET+NHibernate+泛型』概述、知识准备及介绍(一)

    原文://http://blog.csdn.net/wb09100310/article/details/47271555 1. 概述 搭建了Spring.NET+NHibernate的一个数据查询系 ...

  7. Asp.net 面向接口可扩展框架之业务规则引擎扩展组件

    随着面向接口可扩展框架的继续开发,有些功能开发出现了"瓶颈",有太多的东西要写死才好做.但写死的代码扩展性是非常的不好,迷茫中寻找出入... 进而想到我以前开发的好几个项目,都已有 ...

  8. Asp.net 面向接口可扩展框架之使用“类型转化基础服务”测试四种Mapper(AutoMapper、EmitMapper、NLiteMapper及TinyMapper)

    Asp.net 面向接口可扩展框架的“类型转化基础服务”是我认为除了“核心容器”之外最为重要的组成部分 但是前面博文一出,争议很多,为此我再写一篇类型转化基础服务和各种Mapper结合的例子,顺便对各 ...

  9. Asp.net 面向接口可扩展框架之核心容器(含测试代码下载)

    新框架的容器部分终于调通了!容器实在太重要了,所以有用了一个名词叫“核心容器”. 容器为什么那么重要呢?这个有必要好好说道说道. 1.首先我们从框架名称面向接口编程说起,什么是面向接口编程?(这个度娘 ...

随机推荐

  1. jboss7访问日志功能及使用goaccess工具分析

    网络上虽然很多文章分别讲到jboss7的访问日志如何配置,goaccess工具怎么分析nginx/tomcat等日志.但将两者放在一起即“通过goaccess分析jboss访问日志”的倒是没搜索到. ...

  2. oracle 索引失效原因

    转自  http://www.cnblogs.com/orientsun/archive/2012/07/05/2577351.html Oracle 索引的目标是避免全表扫描,提高查询效率,但有些时 ...

  3. APP发布Xcode7

    一.准备工作 1>准备3.5寸.4寸.4.7寸.5.5寸的程序截图至少个1张,如果支持iPad,那么iPad截图也要有.这些截图尽量截取页面漂亮的,因为这些截图是要放在AppStore中展示的. ...

  4. 'UIShell.OSGi.MvcWebExtension.BundleRuntimeControllerFactory' did not return a controller for the name 'Home'.

    在使用osgi.net 框架的时候,有时会遇到这样的错误: 解决办法: 1. 检查项目文件夹下的 log 日志文件,因 osgi.net 在运行时(包括异常和操作)都会在项目的目录下生成 日志文件,并 ...

  5. js实现自动登陆的按钮

    自动按钮,只要实现当移入是提示用户不要在公共地方使用自动登陆 主要用onmouseover函数,本来提示div隐藏,当移入时div显示. <style type="text/css&q ...

  6. Android网络编程之Socket

    Socket(套接字)是一种通信机制,可以实现单机或跨网络进行通信,其创建需要明确的区分C(客户端)/S(服务器端),支持多个客户端连接到同一个服务器.有两种传输模式: 1).面向连接的传输:基于TC ...

  7. linx 实用操作命令二

    pcre相关操作pcretest -C #查看pcre是否支持utf8 rpm -q -a #查看软件包列表rpm -ql pcre-7.8-6.el6.x86_64 #查看包安装的位置rpm -e ...

  8. UTC格式转换 & 十六进制换算为十进制

    UTC格式转换成北京时间格式: /// <summary> /// UTC格式与datatime的转换 /// </summary> /// <param name=&q ...

  9. 使用fiddler2抓取手机发出的请求信息

    fiddler2 简介:抓包软件,可以替换服务器js,从而实现本地调试 初始化设置: 1.工具——fiddler选项——常规——允许远程计算机连接(打钩)     2.按下图设置   3.设置连接,如 ...

  10. UML的9种图例解析

    摘自: http://blog.csdn.net/fatherican/article/details/44966891 UML图中类之间的关系:依赖,泛化,关联,聚合,组合,实现 类与类图 1) 类 ...