HPC大规模集群下的Hadoop2.5+Zookeeper3.4+Giraph1.2的配置、安装与应用

因为实验室项目需求需要进行上亿规模的图文件计算,还好学校HPC(高性能计算机中心)有100多台机器可以用,不用花高价买阿里云服务了,不过。。因为HPC的机器都是用来跑mpi程序的,很少进行分布式计算,更坑爹的是里面装的Hadoop2.7.4版本和Giraph不兼容,所以只有全部纯手动进行安装配置了... 在安装的过程中遇到了非常非常多的坑,下面进行学习总结,以防重蹈覆辙。

一、项目需求

首先简单介绍一下需求,就是目前有几个非常大的图文件(注:数据结构的graph,即:G(V,E)这种,而不是image!)需要进行一些图计算操作(比如求PageRank、单源最短路径、三角形...),传统的做法是用Hadoop/Spark等分布式框架先进行分布式数据读取,再进行分布式计算操作,最后合并结果,但由于图这种数据结构存在着顶点与边相连的关联性,在分布式读取数据时贸然进行切割操作分区间会造成极大的通信开销,但是要是最大程度保持不破坏图结构进行切割,势必会造成分区间的负载不均衡,从而造成水桶效应,因此,大规模图划分问题是一个同时要达到最小化通信开销和保持负载均衡的多目标优化问题,而目前要做的事就是为了验证我们当前设计的图划分算法的性能比别人(Spinner算法)的好,因此需要进行对比实验,而Spinner用的是Giraph图处理框架,Giraph是Pregel的开源实现,内部依赖于Hadoop和Zookeeper,因此,要顺利运行Giraph,就得先配置好Hadoop和Zookeeper,在介绍如何配置之前,先交代一下软硬件环境。

二、软硬件环境

西安电子科大集群系统由2 个管理节点xdhpc01\xdhpc02 、2 个登陆节点 xdhpc03\xdhpc04,6 个lustre 节点,136 个刀片计算节点,7 个gpu 节点(14 个gpu 卡),3个mic节点(6个mic卡),153TB存储组成,节点间通过InfiniBand网络互连。集群系统理论峰值浮点计算性能达到85.52TFlops。单节点配置为:刀片计算节点均采用2个 Intel Xeon E5-2692v2,12核处理器(2.60GHz), 共24计算核心1.8Tsas硬盘,配置64GB内存。每个节点都是一个多核SMP服务器,计算节点用于运行串行和并行计算任务,支持MPI、OpenMP及MPI/OpenMP混合并行编程模式。作业管理系统以CPU核作为并行作业的资源分配单位,实现并行作业的调度运行。每个计算节点为24核的SMP服务器,可以最大支持146* 24 = 3504核并行作业的计算。IO存储系统由AS1000g6光纤存储+扩展柜与6个IO节点构成lustre文件系统,提供集群系统的全局并行文件系统,可提供153TB的可用存储容量,所有用户目录直接建立在该文件系统下边。

西安电子科大集群系统所有节点均采用RedHat Enterprise Linux 6.4x86_64版本,遵循POSIX,LSB等标准,提供了64位程序开发与运行环境。

软件共享目录/opt/soft,通过NFS模式挂载软件管理节点xdhpc01上所有软件资源。 作业提交脚本参考目录/opt/pbs_script。用户目录/ home/用户名:所有节点通过lustre客户端的模式共享用户目录存储空间。

三、相关软件安装与配置

0.前期准备

(1) 首先执行java -version命令确认是否已安装JDK,若未安装,则先需要安装并配好环境变量JAVA_HOME
(2) 确保已有hadoop和zookeeper压缩包,若没有,需要去相应网站下载

1.Hadoop

home路径下解压Hadoop后,开始进行配置:

(1) 配置ssh免密登录,这样hadoop才能让每个节点都能启动

$ ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa
$ cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys
(2) 配置环境变量

/etc/profile文件配置hadoop环境变量

#JAVA
JAVA_HOME=你的jre路径
CLASS_PATH=$JAVA_HOME/lib
PATH=$JAVA_HOME/bin:$PATH
export PATH JAVA_HOME CLASS_PATH 

#HADOOP
export HADOOP_INSTALL=/home/用户名/hadoop-2.5.1
export PATH=$PATH:$HADOOP_INSTALL/bin
export PATH=$PATH:$HADOOP_INSTALL/sbin
export HADOOP_MAPRED_HOME=$HADOOP_INSTALL
export HADOOP_COMMON_HOME=$HADOOP_INSTALL
export HADOOP_HDFS_HOME=$HADOOP_INSTALL
export YARN_HOME=$HADOOP_INSTALL
export HADOOP_COMMON_LIB_NATIVE_DIR=$HADOOP_INSTALL/lib/native
export HADOOP_OPTS="-Djava.library.path=$HADOOP_INSTALL/lib"

(3) 在home/用户名/hadoop-2.5.1/etc/hadoop/路径下进行文件配置:
core-site.xml

<configuration>
           <property>
                <name>fs.defaultFS</name>
                <value>hdfs://masterIP地址:9000</value>
           </property>
		   <property>
		     <name>io.file.buffer.size</name>
		     <value>131702</value>
		   </property>

                   <property>
                     <name>giraph.zkList</name>       <!--配置giraph的zookeeper关联,若后面不装giraph,可以不加此配置-->
                     <value>masterIP地址:2181</value>
                   </property>
    </configuration>

maperd-site.xml
<configuration>
    <property>
          <name>mapred.job.tracker</name>
          <value>masterIP地址:9001</value>
    </property>
    <property>
          <name>mapreduce.framework.name</name>
          <value>yarn</value>
     </property>
     <property>
          <name>mapreduce.jobhistory.address</name>
          <value>masterIP地址:10020</value>
     </property>
     <property>
          <name>mapreduce.jobhistory.webapp.address</name>
          <value>masterIP地址:19888</value>
      </property>
      <property>
          <name>yarn.log.server.url</name>
          <value>http://masterIP地址:19888/jobhistory/logs</value>
      </property>
      <property>
          <name>mapreduce.job.counters.limit</name>
          <value>200000</value>
      </property>

	<property>
		<name>mapred.map.child.java.opts</name> 
		<value>-Xmx8192m</value>
	</property>
        <property>
               <name>mapreduce.map.memory.mb</name> 
             <value>8192</value>
        </property>       

</configuration>

yarn-site.xml

<configuration>
  <property>
          <name>yarn.resourcemanager.hostname</name>
          <value>master Host名称</value>
  </property>
   <property>
          <name>yarn.nodemanager.aux-services</name>
          <value>mapreduce_shuffle</value>
   </property>
   <property>
   		<name>yarn.nodemanager.aux-services.mapreduce.shuffle.class</name>
   		<value>org.apache.hadoop.mapred.ShuffleHandler</value>
   </property>
   <property>
           <name>yarn.resourcemanager.address</name>
           <value>masterIP地址:8032</value>
    </property>
    <property>
           <name>yarn.resourcemanager.scheduler.address</name>
           <value>masterIP地址:8030</value>
    </property>
    <property>
            <name>yarn.resourcemanager.resource-tracker.address</name>
            <value>masterIP地址:8031</value>
    </property>
    <property>
            <name>yarn.resourcemanager.admin.address</name>
            <value>masterIP地址:8033</value>
    </property>
     <property>
            <name>yarn.resourcemanager.webapp.address</name>
            <value>masterIP地址:8088</value>
    </property>

    <property>
            <name>yarn.nm.liveness-monitor.expiry-interval-ms</name>
            <value>3000</value>
    </property>
    <property>
            <name>yarn.log-aggregation-enable</name>
            <value>false</value>
    </property>
    <property>
            <name>yarn.log.server.url</name>
            <value>http://masterIP地址:19888/jobhistory/logs</value>
    </property>
    <property>
            <name>yarn.nodemanager.resource.memory-mb</name>
            <value>20480</value>
    </property>
    <property>
          <name>yarn.scheduler.maximum-allocation-mb</name>
          <value>20480</value>
    </property>
    <property>
          <name>yarn.scheduler.minimum-allocation-mb</name>
          <value>10240</value>
    </property>         
    <property>
	    <name>yarn.nodemanager.resource.cpu-vcores</name>
	    <value>24</value>
   </property>

</configuration>

【参数配置介绍】

参考自:http://blog.csdn.net/wisgood/article/details/44001209

1、yarn-site.xml 设置
1.1 RM设置
RM的内存资源配置,主要是通过下面的两个参数进行的(这两个值是Yarn平台特性,应在yarn-sit.xml中配置好): 
yarn.scheduler.minimum-allocation-mb 
yarn.scheduler.maximum-allocation-mb
说明:单个容器可申请的最小与最大内存,应用在运行申请内存时不能超过最大值,小于最小值则分配最小值,从这个角度看,最小值有点想操作系统中的页。最小值还有另外一种用途,计算一个节点的最大container数目注:这两个值一经设定不能动态改变(此处所说的动态改变是指应用运行时)。
1.2 NM设置
NM的内存资源配置,主要是通过下面两个参数进行的(这两个值是Yarn平台特性,应在yarn-sit.xml中配置) :
yarn.nodemanager.resource.memory-mb
yarn.nodemanager.vmem-pmem-ratio
说明:每个节点可用的最大内存,RM中的两个值不应该超过此值。此数值可以用于计算container最大数目,即:用此值除以RM中的最小容器内存。虚拟内存率,是占task所用内存的百分比,默认值为2.1倍;注意:第一个参数是不可修改的,一旦设置,整个运行过程中不可动态修改,且该值的默认大小是8G,即使计算机内存不足8G也会按着8G内存来使用。
2、map-site.xml 设置
2.1 AM设置
AM内存配置相关参数,此处以MapReduce为例进行说明(这两个值是AM特性,应在mapred-site.xml中配置),如下:
mapreduce.map.memory.mb
mapreduce.reduce.memory.mb
说明:这两个参数指定用于MapReduce的两个任务(Map and Reduce task)的内存大小,其值应该在RM中的最大最小container之间。如果没有配置则通过如下简单公式获得:
max(MIN_CONTAINER_SIZE, (Total Available RAM) / containers))
一般的reduce应该是map的2倍。注:这两个值可以在应用启动时通过参数改变;
2.2 AM JVM设置
AM中其它与内存相关的参数,还有JVM相关的参数,这些参数可以通过,如下选项配置:
mapreduce.map.java.opts
mapreduce.reduce.java.opts
说明:这两个参主要是为需要运行JVM程序(java、scala等)准备的,通过这两个设置可以向JVM中传递参数的,与内存有关的是,-Xmx,-Xms等选项。此数值大小,应该在AM中的map.mb和reduce.mb之间。
3、所有参数
YARN相关
yarn.scheduler.minimum-allocation-mb
yarn.scheduler.maximum-allocation-mb
yarn.nodemanager.vmem-pmem-ratio
yarn.nodemanager.resource.memory.mb
Map相关参数
mapreduce.map.java.opts
mapreduce.map.memory.mb
Reduce相关参数
mapreduce.reduce.java.opts
mapreduce.reduce.memory.mb
注意
在hadoop2及以上版本中,map和reduce task 是运行在container中的。mapreduce.{map|reduce}.memory.mb被yarn用来设置container的内存大小。如果container的内存超限,会被yarn杀死。在container中,为了执行map和reduce task,yarn会在contaner中启动一个jvm来执行task任务。mapreduce.{map|reduce}.java.opts用来设置container启动的jvm参数,通过设置Xmx来设置map 或者reduce task的最大堆内存。理论上,{map|reduce}.java.opts设置的最大堆内存要比{map|reduce}.memory.mb小。例如:
hadoop jar <jarName> -Dmapreduce.reduce.memory.mb=4096 -Dmapreduce.map.java.opts=-Xmx3276
4、举例说明
如下图。默认情况下,yarn.nodemanager.vmem-pmem-ratio被设置为2.1,这意味着,每个map或者task任务只能使用2.1倍("mapreduce.reduce.memory.mb") or ("mapreduce.map.memory.mb") 大小的虚拟内存,否则,会被nm杀掉。
例如下面的的报错信息:
Current usage: 2.1gb of 2.0gb physical memory used; 1.6gb of 3.15gb virtual memory used. Killing container.


map container的内存("mapreduce.map.memory.mb")被设置为1536mb 。am为其申请了2048m的内存,因为am的最小分配(yarn.scheduler.minimum-allocation-mb)是1024.如果map task对内存超过了2048m,nm会kill掉该task。reduce类似。When a mapreduce job completes you will see several counters dumped at the end of the job.The three

memory counters below show how much physical memory was allocated vs virtual memory.


hdfs-site.xml
<configuration>
       <property>
            <name>dfs.namenode.name.dir</name>
            <value>/本地路径/namenode/data</value>
       </property>
       <property>
            <name>dfs.datanode.data.dir</name>
            <value>/本地路径/datanode/data</value>
        </property>
        <property>
			<name>dfs.replication</name>
			<value>2</value>
		</property>
		<property>
			<name>dfs.webhdfs.enabled</name>
			<value>true</value>              
		</property>
		<property>
			<name>dfs.namenode.secondary.http-address</name>
			<value>masterIP地址:9001</value>
		</property>
</configuration>
注意:namenode和datanode一定要配置成本地路径,不能配置nfs共享路径!

hadoop-env.xml

export HADOOP_CONF_DIR=/home/用户名/hadoop-2.5.1/etc/hadoop
...
yarn-env.xml

export JAVA_HOME=你的jre路径
...
slaves

把所有worker的hostname都配置进来,例如:

ibnode101
ibnode102
ibnode103
ibnode104
ibnode105
ibnode107
ibnode108
ibnode109
ibnode110
ibnode111
ibnode112
ibnode113
ibnode114
...

至此hadoop就配置好了。由于home路径下采用的是nfs挂载,所有节点都能访问到该路径,因此不需要再将hadoop分发到每个节点,这也是大规模集群的优势所在!下面开始启动和验证hadoop。

(4) 启动与验证

首先需要格式化namenode:

hadoop namenode -format  

注意:要是修改slaves列表后,必须再次格式化namenode并且删除datanode所在目录(/本地路径/datanode/data)下的所有内容,否则会出现因为clusterID不同而无法启动datanode的问题。要是namenode处于安全模式,需要解除安全模式,只需在hadoop的bin目录下输入:

hadoop dfsadmin -safemode leave

在sbin路径下执行hadoop启动脚本:start-all.sh
检查是否启动成功:master节点执行jps命令,显示:

NameNode
SecondaryNameNode
ResourceManager

worker节点执行jps,显示:

DataNode
NodeManager

若jps进程显示不完整,可以在 /hadoop-2.5.1/logs/ 下查看日志,查看namenode datanode等启动日志便可知道错误原因

下面进行验证:
首先在hdfs创建目录
hadoop fs -mkdir -p input 
新建word.txt文档(随便写一个就行)

hadoop
hadooop
hadoop
fs
fs fs
hdfs

然后把本地word.txt文件放入hdfs目录

hadoop fs -put word.txt input
运行wordcount程序

/hadoop-2.5.1$bin/hadoop jar share/hadoop/mapreduce/sources/hadoop-mapreduce-examples-2.5.1-sources.jar org.apache.hadoop.examples.WordCount input output
查看运行结果

hadoop -cat output/*

可以在 /hadoop-2.5.1/logs/ userlogs目录下查看相应的application任务运行状态,当然,也可以通过webUI可以显示当前启动状态以及任务状态:

浏览器打开 http://masterIP地址:50070/,会看到hdfs管理页面
浏览器打开 http://masterIP地址:8088/,会看到hadoop进程管理页面
浏览器打开 http://masterIP地址:8088/cluster 查看cluster情况

2.Zookeeper

(1) 配置Zookeeper
首先在 home/用户名/ 路径下解压Zookeeper,然后 在conf路径下修改zoo.cfg

一般情况下,zookeeper节点数是小于hadoop节点数的,且为奇数,例如hadoop要启动50个节点,那么zookeeper只需启动5个就够了,在这里我们配置15个:

tickTime=2000
dataDir=数据存储目录(本地目录)
dataLogDir=日志存储目录(本地目录)
clientPort=2181
initLimit=5
syncLimit=2
server.1=ibnode101:2888:3888
server.2=ibnode102:2888:3888
server.3=ibnode103:2888:3888
server.4=ibnode104:2888:3888
server.5=ibnode105:2888:3888     #后面省略...

tickTime :基本事件单元,以毫秒为单位。它用来控制心跳和超时,默认情况下最小的会话超时时间为两倍的 tickTime
dataDir是存放内存数据库快照的位置
dataLogDir 是事务日志目录
clientPort是client连接的端口
initLimit:这个配置项是用来配置 Zookeeper 接受客户端(这里所说的客户端不是用户连接 Zookeeper 服务器的客户端,而是 Zookeeper 服务器集群中连接到 Leader 的 Follower 服务器初始化连接时最长能忍受多少个心跳时间间隔数。当已经超过5个心跳的时间(也就是 tickTime)长度后 Zookeeper服务器还没有收到客户端的返回信息,那么表明这个客户端连接失败。总的时间长度就是 5*2000=10 秒 
syncLimit:这个配置项标识 Leader 与 Follower 之间发送消息,请求和应答时间长度,最长不能超过多少个 tickTime 的时间长度,总的时间长度就是 2*2000=4 秒 
server.A=B:C:D:其中 A 是一个数字,表示这个是第几号服务器;B 是这个服务器的 ip 地址;C 表示的是这个服务器与集群中的 Leader 服务器交换信息的端口;D 表示的是万一集群中的 Leader 服务器挂了,需要一个端口来重新进行选举,选出一个新的 Leader,而这个端口就是用来执行选举时服务器相互通信的端口。如果是伪集群的配置方式,由于 B 都是一样,所以不同的 Zookeeper 实例通信端口号不能一样,所以要给它们分配不同的端口号。 

除了修改 zoo.cfg 配置文件,集群模式下还要配置一个文件 myid,这个文件在 dataDir 目录下,这个文件里面就有一个数据就是 A 的值,Zookeeper 启动时会读取这个文件,拿到里面的数据与 zoo.cfg 里面的配置信息比较从而判断到底是那个 server。

注意dataDir和dataLogDir都必须是本地目录!

 下面在dataDir所定义的目录下新建myid文件,填入各主机之ID。如ibnode101机器的myid文件内容为1。 

(2) 启动与验证

Giraph需要在每个节点分别启动,即每个节点都要进入/home/用户名/zookeeper-3.4.6/bin/目录去执行命令:

zkServer.sh start

要是节点过多,可以写一个sh脚本!

然后验证是否启动成功:

zkServer.sh status

成功启动后Zookeeper会显示leader或follower状态,zookeeper是根据投票算法选取leader的,执行启动命令后,每个节点都会进行投票,当一个节点票数过半后便选举为leader,因此zookeeper节点是奇数个,同时,我们发现这里的leader和follower角色与hadoop的master和work节点无关,leader和follower可能是master,也可能是worker。

当执行jps命令时,会多一个zookeeper进程:

QuorumPeerMain

3.Giraph

(1) 安装与配置

首先,Giraph需要下载对应Hadoop版本的压缩包,有两种方式进行安装:
1) 通过Giraph官网下载已打包好的文件:http://giraph.apache.org/releases.html

目前官网仅提供0.3.2、1.0.0和1.1.0

2) 通过github下载Giraph trunk文件 通过maven下载打包,此方法能下载到Giraph最新的版本

若通过maven打包,首先执行mvn -version命令查看是否已安装maven,安装命令如下:

apt-get install git
apt-get install maven
然后获取代码:

mkdir giraph
cd giraph
git clone https://github.com/apache/giraph.git

用maven进行打包,hadoop版本不同,打包命令也不同(可查看 https://github.com/apache/giraph 的README文件),这里仅给出我们当前版本的打包命令:

mvn -Phadoop_2 -Dhadoop.version=2.5.1 -DskipTests clean install
这也是我推荐的一个较新且较为稳定的版本,因为Giraph默认支持hadoop2的版本就是hadoop2.5.1,之前我们试过用hadoop2.7.4搭建,但在构建Giraph项目时是在会出现各种问题,主要还是hadoop与Giraph版本不兼容造成的!!

在等待大概半小时后(取决于你的网速),Giraph就构建成功啦,此时会出现这样一个文件:

giraph-dist-1.2.0-hadoop2-bin.tar
我们解压它,得到:

giraph-1.2.0-hadoop2-for-hadoop-2.5.1
在etc/profile中追加giraph环境变量

export GIRAPH_HOME=/home/用户名/giraph/giraph-1.2.0-hadoop2-for-hadoop-2.5.1

在 $GIRAPH_HOME/bin/ 里面修改一下giraph-env里面的一个配置:

把HADOOP_CONF_DIR=$HADOOP_HOME/conf修改为HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop,前者为老版本的hadoop,若不修改运行时会报错:No HADOOP_CONF_DIR set, using $HADOOP_HOME/conf

为了能更好发挥Giraph性能,需要在$GIRAPH_HOME/conf目录的giraph-site.xml里面添加以下属性:

<configuration>
<property>
<name>giraph.useOutOfCoreGraph</name>
<value>true</value>
</property>
<name>giraph.maxPartitionsInMemory</name>
<value>15</value>
</property>
<name>giraph.useOutOfCoreMessages</name>
<value>true</value>
</property>
<name>giraph.maxMessagesInMemory</name>
<value>2000000</value>
</property>
<property>
<name>giraph.useSuperstepCounters</name>
<value>false</value>
</property>
</configuration>
                      

至此,Giraph就配置好了!

(2) 验证

下面进行验证:

首先还是在本地input目录下创建一个文件,这里我们进行一个图的最短路径计算,先建一个tiny_graph.txt

[0,0,[[1,1],[3,3]]] 
[1,0,[[0,1],[2,2],[3,1]]] 
[2,0,[[1,2],[4,4]]] 
[3,0,[[0,3],[1,1],[4,4]]] 
[4,0,[[3,4],[2,4]]]
这是Giraph指定的其中一种输出格式 [source_id,source_value,[[dest_id, edge_value],...]] 

然后还是将其放入hdfs上
hadoop fs -put tiny_graph.txt input
最后执行运行命令:
hadoop jar $GIRAPH_HOME/giraph-examples-1.2.0-hadoop2.jar org.apache.giraph.GiraphRunner org.apache.giraph.examples.SimpleShortestPathsComputation -vif org.apache.giraph.io.formats.JsonLongDoubleFloatDoubleVertexInputFormat -vip /input/tiny_graph.txt -vof org.apache.giraph.io.formats.IdWithValueTextOutputFormat -op /output/shortestpaths -w 2
  其中:$GIRAPH_HOME/giraph-examples-1.2.0-hadoop2.jar org.apache.giraph.GiraphRunner 是为了指定jar包和程序入口,Giraph的main方法在此类里面,org.apache.giraph.examples.SimpleShortestPathsComputation是为了指定Giraph的计算类,Giraph的图计算方法主要都是由此类实现的,-vif xxx 是指定图的输入格式,-vip xxx 是指定输入文件路径 -vof xx是指定图的输出格式 -op xxx是指定输出文件路径 -w xx 是指定要运行的work数

执行完毕后,查看输出结果:
hadoop dfs -cat /output/shortestpaths/p* | less

四、应用

光能运行示例程序是不行的,我们的目的是将我们的算法移植到Giraph并运行!因此,得先在eclipse进行编程,并打包。这里我们以okapi项目为例,进行本地化导入:
okapi ( http://grafos.ml/okapi.html)是一个基于Giraph的机器学习框架,里面封装了许多好的算法,其中便有图划分算法Spinner,其成果已发表在2017年的ICDE会议上。通过官网我们能找到其放在github的源码( https://github.com/grafos-ml/okapi)。下载下来后,将其导入eclipse工程后,右键Configure->Convert to Maven Project。稍等片刻,相关的jar包就下载完毕了!

查看okapi的目录结构,在下面找到spinner:

里面的Spinner.java便是图划分运行主类了!我们要做的就是按照这个框架,把别人的算法修改为自己的算法就大功告成了!

细心的朋友可能已经发现,这个项目似乎找不到main方法,无法在eclipse运行,所以,我们自己创建一个Test类:
public class Test implements Tool {

	private Configuration conf;
	public static String filePath = "Amazon0312.txt";
	public static String outPath = "spinner_out";
	
	//Gowalla_edges.txt
	//facebook_combined.txt

	public static void main(String[] args) throws Exception {
			ToolRunner.run(new Test(), args);
		
	}
	

	public Configuration getConf() {
		// TODO Auto-generated method stub
		return conf;
	}

	public void setConf(Configuration conf) {
		// TODO Auto-generated method stub
		this.conf = conf;
	}

	public int run(String[] args) throws Exception {

		// 初始化config
		GiraphConfiguration giraphConf = new GiraphConfiguration(getConf());

		// 配置计算类
		giraphConf.setComputationClass(ConverterPropagate.class);
		giraphConf.setMasterComputeClass(PartitionerMasterCompute.class);

		// 配置输入文件及输入数据格式
		giraphConf
				.setEdgeInputFormatClass(SpinnerEdgeInputFormat.class);
		GiraphFileInputFormat.addEdgeInputPath(giraphConf,
				new Path(filePath));

//		// //配置输出格式
		 //giraphConf.setVertexOutputFormatClass(SpinnerVertexValueOutputFormat.class);

		// 配置单机模式
		giraphConf.setLocalTestMode(true);
		giraphConf.setWorkerConfiguration(1, 1, 100);
		giraphConf.SPLIT_MASTER_WORKER.set(giraphConf, false);
		
		giraphConf.setOutEdgesClass(OpenHashMapEdges.class);
		// 配置输出路径并开启job
	 //InMemoryVertexOutputFormat. initializeOutputGraph(giraphConf);
		GiraphJob giraphJob = new GiraphJob(giraphConf, getClass().getName());
	      //FileOutputFormat.setOutputPath(giraphJob. getInternalJob(), new Path(outputPath));
		giraphJob.run(true);
		return 0;
	}

}
我把与输出相关的代码全注释了,这样就不用每次运行完都删一次输出文件了,要是想看输出的朋友可以取消注释。
Spinner的图文件格式是自定义的,格式非常简单,每行都为:id1 id2,这两个id构成了一条边,详情可看SpinnerEdgeInputFormat类,输出格式为:id part_id,即表示每个顶点都在哪个编号的分区,详情可看SpinnerVertexValueOutputFormat类,这样,我们就可以运行这个程序,进行本地调试啦!得意

最后,我们要做一件过河拆桥的事情,那就是把跟图划分不想关的包全删掉,这样就清爽多了!偷笑

当然,这是一种比较懒的方法,你可以自己建一个maven工程,在pom里写上配置,进行Giraph编程,但我一来就上手okapi的原因是里面的信息非常丰富,Giraph的官网demo信息太少,很难在短时间内上手编程,所以给大家推荐用okapi作为上手程序,再结合这本书:Large-Scale Graph Processing Using Apache Giraph以及官方API:http://giraph.apache.org/apidocs/index.html 相信你学起来一定不会那么吃力!

好,最后一步!通过eclipse的export进行打包后,我们也可以在Giraph集群进行运行了,我们以Spinner为例,创建一个shell脚本:run_spinner.sh
GRAPH_NAME=soc-LiveJournal1.txt #图文件名
HADOOP_CLIENT_OPTS="-Xmx20480M" #配置hadoop运行时最大占用内存

export HADOOP_CLASSPATH=$GIRAPH_HOME/okapi-giraph-mr2-0.3.5.jar
hadoop jar okapi-giraph-mr2-0.3.5.jar org.apache.giraph.GiraphRunner   -libjars okapi-giraph-mr2-0.3.5.jar   ml.grafos.okapi.spinner.Spinner\$ConverterPropagate   -mc ml.grafos.okapi.spinner.Spinner\$PartitionerMasterCompute   -eif ml.grafos.okapi.spinner.Spinner\$SpinnerEdgeInputFormat   -eip /input/$GRAPH_NAME  -vof ml.grafos.okapi.spinner.Spinner\$SpinnerVertexValueOutputFormat  -op /graph_data/output -w 14 -ca giraph.outEdgesClass=ml.grafos.okapi.spinner.OpenHashMapEdges -ca spinner.numberOfPartitions=2 -ca spinner.maxIterations=290
注意-ca后面的是程序的自定义参数,你可以在Spinner.java中找到他们,当然,你也可以根据需求设置更多的自定义参数。‘

最后,记录实验结果,任务就圆满完成啦!~ 吐舌头

五、总结

 做图划分项目算下来也一年多了,体会到了做一个科研任务真的是非常非常非常非常的不容易,尤其是在这个领域的资料相对较少的情况下,就得付出更多的努力才有回报,在这里感谢我的导师、组员以及超算中心赵老师对我的帮助,最后,希望这篇博客能对正在做相同问题且遇到障碍的同学提供帮助!

文章撰写仓促,若有缺陷,请及时指出,谢谢!













猜你喜欢

转载自blog.csdn.net/u011545382/article/details/79111704