1、Graphlab 并行集群安装教程 GraphLab 是 CMU(卡耐基梅隆大学)开发的一个以 vertex 为计算单元的大规模图处理系统,是继 google 的 Pregel 之后的第一个开源的大规模图处理系统,它解决了传统 mapreduce框架对于机器学习应用的处理中最突出的两个问题(频繁迭代计算和大量节点通信)引起的计算效率的问题,与 Haloop,Twister 等基于 mapreduce 批量处理不同的是,它采用 Pregel的以 vertex 为计算单元,并将机器学习抽象成 GAS(gather,apply,scatter)三个步骤,然后按该抽象模型设计实现算法,事实已经证明该框
2、架对于机器学习这一类跟图处理关系紧密的应用有很好的效果。最近这几天在实验室集群上搭建了 GraphLab 分布式计算环境。这篇文章主要总结一下搭建过程和碰到的问题。1)介绍一下实验室集群的环境。集群中总共有 9 台机器,每台机器有 CPU 核 4 个,内存 8G。每台机器上都安装了 64 位Ubuntu 12.04 Desktop 版操作系统。注意,根据 GraphLab 官方安装指南(We require a 64-bit operating system.),要安装 GraphLab,操作系统必须是 64位的。2)为每台机器安装 GraphLab 的依赖库。在每台机器上运行如下的命令:su
3、do apt-get install gcc g+ build-essential libopenmpi-dev openmpi-bin default-jdk cmake zlib1g-dev git3) 从 GitHub 上下载 GraphLab。选取集群中的一台机器,进入要安装 GraphLab 的目录,使用如下的 git 命令下载 GraphLab。cd # 我将GraphLab 安装在了主目录下git clone https:/ GraphLab 项目比较大,下载需要花费一定的时间。下载完成之后,会在当前目录下看到一个名为 graphlab 的文件夹。4) 编译 GraphLab。进
4、入 graphlab 文件夹,使用 graphlab 自带的 configure 脚本配置编译环境:cd graphlab./configure配置成功后会在 graphlab 文件夹内生成 release 和 debug 两个新的目录。这两个目录分别对应不同项目的发行版和测试版,在这两个目录中都可以编译 GraphLab 的所有 Toolkit,分别对应发行版和测试版。编译后发行版与测试版的不同是,发行版在编译过程中程序都做了优化,运行速度更快。因此,我的编译选择在 release 目录中进行。还有一点需要特别指出,GraphLab 不仅提供了分布式大规模图计算模型,而且基于该模型实现了很多
5、实用的工具集,这些工具集可以分成六类:主题建模、图分析、聚类、协同过滤、图模型和计算机视觉。可以根据自己的需要只编译其中的某一类或几类。如果全部编译,第一次编译时会下载很多的库文件,耗费很长时间。我只对其中的图分析工具集比较感兴趣,所以只编译了这一个。同时我也编译了 apps 目录中的相应样例代码。编译 release 目录下的 apps 子目录:cd release/appsmake -j 3第二行中的参数-j 3 是利用了 make 的并行编译特性,3 指的是同时进行三个编译任务。该数字越大,并行性越高,编译速度越快,但是占用内存也越多。如果该数字过大,会因内存不够用而使编译过程卡住。编译
6、 release 目录下的 toolkits 中的 graph_analytics:cd release/toolkits/graph_analyticsmake -j 3如果希望编译整个 GraphLab,那么可以在 release 目录下运行如下命令:cd releasemake -j 35) 配置 SSH。GraphLab 要求集群中任意两台机器之间能够实现 SSH 无密码登录。首先要确保每台机器上都已经安装了 openssh-server:sudo apt-get install openssh-server接着在每台机器上生成公钥和私钥对,一路回车即可:ssh-keygen -t r
7、sa最后是配置任意两台机器间的无密码 ssh 登录。比如 A 和 B 两台机器,若要在 A 上能够无密码 ssh 登录到 B,可以在 A 上运行如下命令:ssh-copy-id hostname-of-B其中 hostname-of-B 指的是 B 的主机名。如果集群中机器数量很多,任意两台机器都配置一遍显然太麻烦了。一种简单的策略是,先配置其中一台机器到集群中所有机器的(包括 ssh 到自己的),然后将该台机器中$HOME/.ssh/authorized_keys 文件拷贝到集群中所有其他结点上。( !这种策略经验证并不可行,还是需要手动配。!)6)创建 machines 文件并分发到集群中
8、的所有机器上。在集群中的某一台机器上创建一个名称为 machines 的文件,该文件中列出了参与计算的所有机器的主机名(或者 IP 地址),每个主机名占一行。将 machines 文件拷贝到集群中的所有机器上,注意 machines 文件的位置在所有机器上都要确保一致,而且必须是用户的$HOME主目录。接下来在使用 GraphLab 提供的脚本分发编译好的可执行文件到集群中各个机器上时,该脚本默认 machines 文件位于用户主目录下。scp /machines hostnamex:/其中 hostnamex 是集群中其他机器的主机名。以上步骤完成后,可以在任意一台机器上使用如下命令测试配置
9、是否正确:mpiexec -hostfile /machines hostname如果上面的命令能够返回你在 machines 文件里面列出的所有主机名,那么说明配置正确。7)分发 GraphLab 二进制可执行文件和相关库文件到集群中的所有机器上。GraphLab 提供了脚本用于分发编译好的二进制可执行文件到集群中的所有其他机器上。在你下载并编译了 GraphLab 的那台机器上,使用下面的命令来分发二进制可执行文件和相关库文件:cd /graphlab/release/apps; /graphlab/scripts/mpirsync #分发 appscd /graphlab/release
10、/toolkits; /graphlab/scripts/mpirsync #分发 toolkitscd /graphlab/deps/local; /graphlab/scripts/mpirsync #分发库文件8)单机模式下,使用模拟图运行测试 PageRank 程序。在每一台机器上,运行如下的命令来测试分发到每台机器上的二进制可执行程序能否正确运行:cd /graphlab/release/toolkits/graph_analytics/./pagerank -powerlaw=10000如果上述命令在每台机器上都能正确无误运行,GraphLab 的集群安装配置就算完成了。接下来可以
11、测试分布式模式下能否成功运行。9)分布式模式下,使用模拟图运行测试 PageRank 程序。在任意一台机器上,运行如下命令:cd mpiexec -n 2 -hostfile machines graphlab/release/toolkits/graph_analytics/pagerank -powerlaw=100000改变-n 参数的值,多试几次,以确保安装正确无误。如果上述命令能够正确无误执行,那么 GraphLab 分布式集群运算环境搭建就算完成了。碰到的问题(目前该问题已经解决):我在安装 GraphLab 后遇到的问题是:在单机模式下每台机器上 PageRank 都能够成功执行
12、,但是换到分布式模式下,运行命令后程序立即卡住,没有任何错误提示信息。这一问题让我焦虑了很多天,因为没有 log,没有任何提示,根本无法定位问题所在。目前该问题仍然无法解决,与 GraphLab 的作者联系并交流,作者也无法定位问题所在。我猜测机器型号可能导致该问题:运行 GraphLab 的集群,每台机器的型号一定要完全一致。因为 GraphLab 使用 C+开发,相比 Java 的一处编译多处运行,C+并不具有这种特性。要想让在一台机器上编译的代码能够在其他机器上正确运行,一定要确保所有机器型号一致。我碰到的现象很奇怪,虽然我集群中的机器有几台型号不一致,但是我在一台机器上编译后生成的可执
13、行程序在型号不一样的机器上也能正常运行。但是分布式模式下,就会卡住。具体是什么原因,我也不清楚。有人可能会问,不同型号的机器,自己编译自己的可以吗?答案是不行,分布式模式下程序运行前要检查校验码,确保所有可执行程序是在同一台机器上编译的,如果校验码不一致,程序无法运行。但是真实情况又否定了我的这一猜测。我的集群里有三种不同型号的机器,当两台能同时运行时,这两台的型号不一样。当四台能同时运行时,其中的四台有三种型号。问题解决方法:通过邮件与 GraphLab 作者交流,作者对我碰到的问题也很费解,试了各种可能的方法,都无法解决我碰到的问题。一个偶然的机会,实验室的一位学弟解决了我的问题。我安装G
14、raphLab 使用的是 OpenMPI, 学弟将 OpenMPI 换成 MPICH 后,问题解决了。关于安装MPICH 的过程可以参考:http:/ MPI 并行计算环境搭建以及集群测试MPI 作为一种通过消息传递进行并行计算的框架,在很多科学计算上有很重要的应用,这次因为GraphLab 环境搭建时的需要,花了三个来小时的时间进行了初步的搭建摸索,感觉很有意思! 首先是单机 MPI 安装1.安装之前因为是集群测试,所以跟 hadoop 一样先要设置 ssh 无密钥登录(可以参考这里) ,我这里用的是一个服务器节点和一台虚拟机。上面给出的链接里对 ssh 无密钥登录设置说的很清楚。2.开始安
15、装源码下载地址,这里我用的是 1.0.8(mpich 命名很怪气,明明是 v2,它却命名是 1,无力吐槽)mpich2-1.0.8.tar.gz单机安装很简单#tar -zxvf mpich2-1.0.8.tar.gz#./configure (我让它默认安装到/usr/local/bin 下,不需要设置安装路径)#make#make install注意:对于集群的每一个机器都要安装,当然你如果用 NFS 挂载也可以,我没这样用。安装完成之后最重要的一步有人说是设置环境变量,其实你默认安装路径的话,这个变量设置与否无所谓的。因此最重要的一步是创建配置文件(mpd.conf) 。#touch /
16、etc/mpd.conf#chmod 600 /etc/mpd.conf#echo secretword=myword /etc/mpd.conf到此为止,单机安装就算完成了,可以进行单机测试# mpd use hashlib insteadfrom md5 import new as md5new原因:python 版本太高了,python2.6 开始都不支持 popen2 模块,转而用 subprocess 模块代替,因此会出现这个错误。解决办法是降低 python 的版本,转到 python2.5 之后就可以了。 (源码下载)问题 2#ssh node2ssh: node2: Tempo
17、rary failure in name resolution#ssh 192.168.169.2 则成功原因:/etc/hosts 中配置不完全解决办法:两端都需要配置如下:192.168.168.9 node9192.168.169.2 node2问题 3rootnode9 source# mpdboot -n 2 -f /root/mpd.hosts mpdboot_node9 (handle_mpd_output 401): failed to connect to mpd on node2原因:防火墙的问题,node2 中防火墙禁止 node9 进行 mpd 连接解决办法:我直接将
18、node2 中端口关掉了rootnode2 .ssh# iptables -Frootnode2 .ssh# iptables -LChain INPUT (policy ACCEPT)target prot opt source destination Chain FORWARD (policy ACCEPT)target prot opt source destination Chain OUTPUT (policy ACCEPT)target prot opt source destination 或者你可以参考这里,这个连接的第二个问题就是教你如何解决防火墙禁止 mpd 访问的。问题 4 mpiexec_node9 (mpiexec 392): no msg recvd from mpd when expecting ack of request原因:当前的环境设置不能满足其性能的需求,需要对环境变量的设置进行改变。