目前,原生Spark的GraphX只有Scala接口,如果想要用Python,可以使用GraphFames。
1、安装GraphFrames
首先根据Spark版本到SparkPackages下载合适的版本,因为我使用的是Spark 2.2,所以我这里下载的是graphframes-0.6.0-spark2.2-s_2.11.jar。
可以使用Maven来下载该包以及依赖包。
新建pom.xml文件,从SparkPackages里复制模板并修改版本为你需要的版本:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>test</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- list of dependencies -->
<dependency>
<groupId>graphframes</groupId>
<artifactId>graphframes</artifactId>
<version>0.6.0-spark2.2-s_2.11</version>
</dependency>
</dependencies>
<repositories>
<!-- list of other repositories -->
<repository>
<id>SparkPackagesRepo</id>
<url>https://repos.spark-packages.org/</url>
</repository>
</repositories>
</project>
然后运行命令:
mvn -f pom.xml dependency:copy-dependencies
依赖库下载完成之后,会保存在当前路径的target目录里。
Maven下载依赖时,默认从中央仓库下载,在国内会很慢甚至超时,可以修改为阿里镜像,打开settings.xml文件,增加镜像仓库:
<mirrors>
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
把target目录以及目录上传到Driver服务器,新建一个src文件夹:
mkdir src
cp graphframes-0.6.0-spark2.2-s_2.11.jar src
cd src
jar -xf graphframes-0.6.0-spark2.2-s_2.11.jar
cd graphframes
zip graphframes.zip -r *
2、简单入门
在target目录下,启动PySpark:
$ export PYTHONPATH=$PYTHONPATH:src/graphframes/graphframes.zip:.
$ pyspark --queue gld --jars graphframes-0.6.0-spark2.2-s_2.11.jar,scala-logging-api_2.11-2.1.2.jar,scala-logging-slf4j_2.11-2.1.2.jar
import sys
print(sys.path) # 验证GraphFrames是否已经包含在Python路径里了
import graphframe as gf
# 顶点
v = spark.createDataFrame([("a", "Alice", 34),
("b", "Bob", 36),
("c", "Charlie", 30),
("d", "David", 29),
("e", "Esther", 32),
("f", "Fanny", 36),
("g", "Gabby", 60)],
["id", "name", "age"])
# 边
e = spark.createDataFrame([("a", "b", "friend"),
("b", "c", "follow"),
("c", "b", "follow"),
("f", "c", "follow"),
("e", "f", "follow"),
("e", "d", "friend"),
("d", "a", "friend"),
("a", "e", "friend")],
["src", "dst", "relationship"])
# 创建图
g = gf.GraphFrame(v, e)
# 设置Checkpoint目录
sc.setCheckpointDir('graphframes_cps')
## 查看GraphFrame
g.vertices.show()
g.edges.show()
## 计算每个顶点的度
g.degrees.show()
+---+------+
| id|degree|
+---+------+
| f| 2|
| e| 3|
| d| 2|
| c| 3|
| b| 3|
| a| 3|
+---+------+
2.1 连通分量(Connected Components)
g.connectedComponents().show()
+---+-------+---+------------+
| id| name|age| component|
+---+-------+---+------------+
| a| Alice| 34|412316860416|
| b| Bob| 36|412316860416|
| c|Charlie| 30|412316860416|
| d| David| 29|412316860416|
| e| Esther| 32|412316860416|
| f| Fanny| 36|412316860416|
| g| Gabby| 60|146028888064|
+---+-------+---+------------+
其中,component那一列表示ID,相同ID的就是属于同一连通分量。可以看到{a,b,c,d,e,f}组成一个连通分量,{g}一个连通分量。
2.2 强连通分量(Strongly Connected Components)
在有向图 G G G中,如果两个顶点 u u u, v v v间有一条从 u u u到 v v v的有向路径,同时还有一条从 v v v到 u u u的有向路径,则称两个顶点强连通。如果有向图 G G G的每两个顶点都强连通,称 G G G是一个强连通图。有向非强连通图的极大强连通子图,称为强连通分量。
g.stronglyConnectedComponents(maxIter=10).show()
+---+-------+---+-------------+
| id| name|age| component|
+---+-------+---+-------------+
| g| Gabby| 60| 146028888064|
| b| Bob| 36|1047972020224|
| e| Esther| 32| 670014898176|
| a| Alice| 34| 670014898176|
| f| Fanny| 36| 412316860416|
| d| David| 29| 670014898176|
| c|Charlie| 30|1047972020224|
+---+-------+---+-------------+
可以看到{a,d,e}组成一个强连通分量,{b,c}一个强连通分量。
2.3 三角计数
统计每个顶点所在的三角形个数。
g.triangleCount().show()
+-----+---+-------+---+
|count| id| name|age|
+-----+---+-------+---+
| 0| g| Gabby| 60|
| 0| f| Fanny| 36|
| 1| e| Esther| 32|
| 1| d| David| 29|
| 0| c|Charlie| 30|
| 0| b| Bob| 36|
| 1| a| Alice| 34|
+-----+---+-------+---+
2.4 标签传播
算法的基本思想是:你的邻居属于哪个Label最多,你就属于哪个Label。
算法具体步骤:
1)初始时,给每个节点一个唯一的标签;
2)每个节点使用其邻居节点的标签中最多的标签来更新自身的标签;
3)反复执行步骤2,直到每个节点的标签都不再发生变化为止。
g.labelPropagation(maxIter=50).orderBy('label').show()
+---+-------+---+-------------+
| id| name|age| label|
+---+-------+---+-------------+
| g| Gabby| 60| 146028888064|
| e| Esther| 32|1047972020224|
| a| Alice| 34|1047972020224|
| c|Charlie| 30|1047972020224|
| f| Fanny| 36|1382979469312|
| d| David| 29|1382979469312|
| b| Bob| 36|1382979469312|
+---+-------+---+-------------+