您好,登錄后才能下訂單哦!
這篇文章主要介紹“基于spark的GraphX如何使用”,在日常操作中,相信很多人在基于spark的GraphX如何使用問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”基于spark的GraphX如何使用”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
基于Spark的GraphX.pptx
1. Property Graph:用戶定義的有向圖,圖中的每個頂點和每條邊都附加一個用戶定義的對象,允許在兩個頂點之間并行存在多條邊。每個頂點都具有一個64位的唯一標識(VertexID),GraphX并不強制VertexID有序。每條邊則由起始和終止VertexID標識。
Graph具有兩個參數化的類型:Vertex(VD)和Edge(ED),分別對應附加在頂點和邊上的對象。當VD和ED為基本的數據類型時,Graph將把它們保存在數組中。
Graph和RDD一樣(spark的基本數據類型,Resilient Distributed Dataset),創建之后不可再改變,分布式存儲在集群上,并且具有容錯能力。對圖中結構和值的改變,都將需要產生一個新的Graph對象,新的Graph將與之前的Graph共享大部分數據結構。Graph通過頂點分割方法,分割在不同的機器上。任何數據分片所在機器的失敗都將引發該數據分片在其它機器上重新創建。
邏輯上Graph包含VertexRDD和EdgeRDD,即:
class Graph[VD,ED] {
val vertices: VertexRDD[VD]
val edges: EdgeRDD[ED,VD]
}
其中,VertexRDD[VD]和EdgeRDD[ED,VD]分別是RDD[VertexID,VD]和RDD[Edge[ED]]經過優化(extends)后的版本,提供了圖計算相關功能,并做了內部優化。
2. Graph類的成員變量
class Graph[VD, ED] { //Graph的基本信息:邊數,頂點數,入度,出度,度 val numEdges: Long val numVertices: Long val inDegrees: VertexRDD[Int] val outDegrees: VertexRDD[Int] val degrees: VertexRDD[Int] //Graph的頂點RDD,邊RDD,以及三元組RDD val vertices: VertexRDD[VD] val edges: EdgeRDD[ED, VD] val triplets: RDD[EdgeTriplet[VD, ED]] }
class Graph[VD, ED] { def mapVertices[VD2](map: (VertexId, VD) => VD2): Graph[VD2, ED] def mapEdges[ED2](map: Edge[ED] => ED2): Graph[VD, ED2] def mapTriplets[ED2](map: EdgeTriplet[VD, ED] => ED2): Graph[VD, ED2] } 上面的每個操作都將改變Graph中vertex和edge特性,并產生一個新的Graph
class Graph[VD, ED] { def reverse: Graph[VD, ED] def subgraph(epred: EdgeTriplet[VD,ED] => Boolean, vpred: (VertexId, VD) => Boolean): Graph[VD, ED] def mask[VD2, ED2](other: Graph[VD2, ED2]): Graph[VD, ED] def groupEdges(merge: (ED, ED) => ED): Graph[VD,ED] }
reverse操作返回一個愿圖中邊的方向反轉的新圖。由于該操作沒有改變頂點和邊的特性,所以不需要數據的移動
subgraph操作返回連接的點和邊滿足vpred和epred構成的子圖
mask操作返回兩個圖相交的子圖,groupEdges操作合并重復的邊
5. 連接操作
class Graph[VD, ED] { def joinVertices[U](table: RDD[(VertexId, U)])(map: (VertexId, VD, U) => VD) : Graph[VD, ED] def outerJoinVertices[U, VD2](table: RDD[(VertexId, U)])(map: (VertexId, VD, Option[U]) => VD2) : Graph[VD2, ED]}
joinVertices操作,連接頂點和輸入的RDD,然后對連接得到的頂點,應用用戶定義的map函數,若在RDD中沒有匹配連接的頂點,則保持頂點原有的值不變
outerjoinVertices類似于joinVertices,只是用戶定義的map函數應用于所有的頂點,且可以改變頂點的類型
其中f(a)(b)的寫法類似于f(a,b),只是參數b的類型取決于a
6. 鄰域聚合
GraphX中,經過深度優化的核心聚合操作是mapReduceTriplets
class Graph[VD, ED] { def mapReduceTriplets[A]( map: EdgeTriplet[VD, ED] => Iterator[(VertexId, A)], reduce: (A, A) => A) : VertexRDD[A]}
mapReduceTriplets接收一個用戶定義的map函數,應用于Graph的每一個三元組,產生消息(message)給三元組中的任意頂點。為了便于預先聚合優化,暫時只支持給其中一個頂點發送消息。隨后,用戶定義的reduce函數結合發送給每一個頂點的消息。最終返回VertexRDD[A],沒有收到消息的頂點不包含在該結果之中
mapRedeceTriplets還包含一個可選的參數:activeSetOpt,指定執行map操作的頂點集合
7. 在spark中,RDD默認是不會一直保存在內存中的,為了避免重復計算,需要顯式的指定:Graph.cache(),顯式指定保存在內存中的RDD只有在系統內存不足時,才會強制采用LRU(least recently uesd)方式調出內存。然而,對于迭代計算則應該uncaching迭代產生的中間數據,因此,在進行圖的迭代計算時,推薦采用Pregel API,它會自動的unpersist不需要的中間結果。
8. GraphX Pregel API
圖天然就是一個遞歸的數據結構,圖中頂點的特性取決于它們鄰域頂點的特性,反過來又影響其鄰域頂點的特性。因此,很多重要的圖算法都需要迭代計算每個頂點的特性,直到收斂。GraphX提供類似于Pregel的操作,其是Google Pregel和GraphLab框架抽象的結合。
class GraphOps[VD, ED] { def pregel[A] (initialMsg: A, //初始消息,最大迭代次數,消息傳遞方向 maxIter: Int = Int.MaxValue, activeDir: EdgeDirection = EdgeDirection.Out) (vprog: (VertexId, VD, A) => VD, sendMsg: EdgeTriplet[VD, ED] => Iterator[(VertexId, A)], mergeMsg: (A, A) => A) : Graph[VD, ED] = { var g = mapVertices( (vid, vdata) => vprog(vid, vdata, initialMsg) ).cache() var messages = g.mapReduceTriplets(sendMsg, mergeMsg) var activeMessages = messages.count() var i = 0 while (activeMessages > 0 && i < maxIterations) { val newVerts = g.vertices.innerJoin(messages)(vprog).cache() g = g.outerJoinVertices(newVerts) { (vid, old, newOpt) => newOpt.getOrElse(old) }.cache() messages = g.mapReduceTriplets(sendMsg, mergeMsg, Some((newVerts, activeDir))).cache() activeMessages = messages.count() i += 1 } g } }
9. 創建Graph
GraphX提供了根據頂點和邊RDD或者從磁盤上創建圖的方法。默認情況下,圖構建器不會重新分割圖的邊,即邊將留在它們起始分片所在機器。然而,Graph.groupEdges要求將圖重新分片,因為該操作假設相同的邊處在相同的分片中。所以需先調用Graph.partitionBy操作。
GraphLoader.edgeListFile操作,從磁盤加載圖,解析sourceVD destinationVD,跳過#開始的注釋行,頂點值默認為1
10.VertexRDD和EdgeRDD
GraphX提供Graph的VertexRDD和EdgeRDD,由于GraphX對頂點和邊的數據結構進行了優化,因此還提供一些額外的功能。Vertex[A]繼承自RDD[VertexID,A],并且約束VertexID只能出現一次,采用哈希表的方式存儲頂點屬性A。EdgeRDD繼承自RDD[Edge[ED]]依據策略PartitionStrategy,將邊保存在分塊中。在每個分塊中,邊的結構和屬性保存在不同的結構中。
到此,關于“基于spark的GraphX如何使用”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。