1.グラフ集約操作aggregateMessages:
1.1 集計操作:
aggregateMessages:多くのグラフ分析タスクの重要なステップは、各頂点の近傍情報を集約することです。
GraphXのコア集約操作はaggregateMessagesです。その主な機能は、メッセージをネイバーに送信し、ネイバーが受信したメッセージをマージすることです。
。1.2 SENDMSG とmergeMsg :
sendMsg:
sendMsg
関数はEdgeContextを入力パラメーター
とし
、戻り値はありません。
EdgeContextは2つのメッセージ送信機能を提供します
sendToSrc:メッセージタイプメッセージをソース頂点に送信します
sendToDst:メッセージタイプメッセージをターゲット頂点に送信します
mergeMsg
:
各頂点によって受信されたすべてのメッセージは集約され、
mergeMsg
関数に渡され
ます
mergeMsg関数は、頂点が受信したすべてのメッセージを必要な結果に変換する方法を定義します
3. 図の集計操作のデモ:
package aggregate
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.graphx.{Edge, EdgeContext, Graph}
object aggreTest2 {
def sendMsg(ec:EdgeContext[Int,String,Int]):Unit = {
ec.sendToDst( ec.srcAttr +1)
}
def mergeMsg(a: Int , b:Int) :Int = {
math.max(a,b)
}
def sumEdgeCount( g:Graph[Int,String]):Graph[Int,String] = {
val verts = g.aggregateMessages[Int]( sendMsg , mergeMsg)
//verts.collect.foreach(println(_))
val g2 = Graph(verts ,g.edges)
//(4,(1,0))
println( "*************************************")
//g2.vertices.join(g.vertices).map( x => x._2._1 - x._2._2).reduce(_+_).collect.foreach(println(_))
val check = g2.vertices.join(g.vertices).map( x => x._2._1 - x._2._2).reduce(_+_)
println(check)
println( "*************************************")
if(check > 0)
sumEdgeCount(g2)
else
g
}
def main(args: Array[String]): Unit = {
//设置运行环境
val conf = new SparkConf().setAppName("SimpleGraphX").setMaster("local")
val sc = new SparkContext(conf)
sc.setLogLevel("WARN")
// 构建图
val myVertices = sc.parallelize(Array((1L, "张三"), (2L, "李四"), (3L, "王五"), (4L, "钱六"),
(5L, "领导")))
val myEdges = sc.makeRDD(Array( Edge(1L,2L,"朋友"),
Edge(2L,3L,"朋友") , Edge(3L,4L,"朋友"),
Edge(4L,5L,"上下级"),Edge(3L,5L,"上下级")
))
val myGraph = Graph(myVertices,myEdges)
val initGraph = myGraph.mapVertices((_,_)=>0)
sumEdgeCount(initGraph).vertices.collect.foreach(println(_))
}
}
2.Pregel API:
2.1 PregelとPregel API:
プレゲル
:
Hadoopの台頭後、Googleは3つの研究論文を発表し、それぞれカフェイン、プレゲル、ドレメルの3つの技術を詳しく説明しました。これら3つの技術は、Googleの新しい「トロイカ」にもなりました。大規模な分散グラフコンピューティングフレームワークに使用されます。図は、主トラバース(BFS)のため、
最短経路(SSSP
)、
PageRankの計算は等算出されます
。
Pregel API
:
頂点の属性はそれらの近傍の属性に依存し、それが次にそれらの近傍の属性に依存するため、グラフは本質的に再帰的なデータ構造です。したがって、多くの重要なグラフアルゴリズムは、固定小数点条件に到達するまで各頂点の属性を繰り返し再計算します。これらの反復アルゴリズムを表現するために、一連のグラフィカルな並列抽象化が提案されています。GraphX
は、Googleのアイデアに従って独自の
Pregel APIを実装し
ます
2 .2 バルク同期並列BSP。
メッセージを生成し、次のスーパーステップに渡します。現在のスーパーステップとメッセージのすべてが終了するまで、 スーパーの後に次のステップに渡され、次のステップは、スーパースタートになります。これが同期の障壁です。
2.3 Pregel APIは、スーパーステップの内部の詳細を完了します。
2.4 プレゲル機能:
2. 5 p regelのactiveDirectionパラメーター:
エッジの2つの頂点srcIdおよびdstId:
EdgeDirection。Out-srcIdが前の反復からメッセージを受信すると、sendMsgを呼び出します。つまり、このエッジはsrcIdの「アウトエッジ」と見なされます。
EdgeDirection。In-dstIdが前の反復からメッセージを受信すると、sendMsgを呼び出します。つまり、このエッジはdstIdの「着信エッジ」と見なされます。
EdgeDirection。いずれか-srcIdまたはdstIdが前の反復からメッセージを受信する限り、sendMsgが呼び出されます。
EdgeDirection:srcIdとdstIdの両方が前の反復からメッセージを受信した場合にのみ、sendMsgが呼び出されます。
2.6プレゲルケース:
package pregel
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.graphx.{Edge, Graph, VertexId}
import org.apache.spark.graphx.util.GraphGenerators
object GraphXTest1 {
def main(args: Array[String]): Unit = {
//设置运行环境
val conf = new SparkConf().setAppName("Pregel API GraphX").setMaster("local")
val sc = new SparkContext(conf)
sc.setLogLevel("WARN")
// 构建图
val myVertices = sc.parallelize(Array((1L, 0), (2L, 0), (3L, 0), (4L, 0),
(5L, 0)))
val myEdges = sc.makeRDD(Array( Edge(1L,2L,2.5),
Edge(2L,3L,3.6) , Edge(3L,4L,4.5),
Edge(4L,5L,0.1),Edge(3L,5L,5.2)
))
val myGraph = Graph(myVertices,myEdges)
val sourceId: VertexId = 1L // The ultimate source
// Initialize the graph such that all vertices except the root have distance infinity.
val initialGraph = myGraph.mapVertices((id, _) =>
if (id == sourceId) 0.0 else Double.PositiveInfinity)
val sssp: Graph[Double, Double] = initialGraph.pregel(Double.PositiveInfinity)(
(id, dist, newDist) => math.min(dist, newDist), // Vertex Program
triplet => { // Send Message
if (triplet.srcAttr + triplet.attr < triplet.dstAttr) {
Iterator((triplet.dstId, triplet.srcAttr + triplet.attr))
} else {
Iterator.empty
}
},
(a, b) => math.min(a, b) // Merge Message
)
sssp.vertices.collect.foreach(println(_))
}
}