graphx是spark用於圖形平行計算的新元件。在較高的層次上,graphx通過引入乙個新的graph抽象來擴充套件spark rdd:乙個定向的多圖,其屬性附加到每個定點和邊。為了支援圖計算,graphx公開了一組基本的操作符(子圖,joinvertices和aggregatemessages),以及上述優化的變體api。此外,graphx包括越來越多的圖形演算法和構建器集合,以簡化圖形分析任務。
graphx的屬性曲線圖是乙個有向多重圖與連線到每個頂點邊緣的使用者定義物件。其可能有多個平行邊共享相同的源和目標頂點。支援平行邊的能力簡化了在相同頂點之間存在多個關係的建模場景(例如:即使朋友又是同事)。每個頂點都是由唯一的64位長識別符號【vertexid】
設定秘鑰。graphx不對頂點識別符號施加任何排序約束。同樣,邊具有相應的源和目標頂點識別符號。
在頂點【vd】和邊【ed】型別上對屬性圖進行了引數化。這些分別是與每個頂點和邊關聯的物件的型別。
當頂點和邊型別是原始資料型別【例如:int, double等】時,graphx可以優化它們的表示形式,方法是將它們儲存在專用陣列中,從而減少了記憶體佔用量。
在某些情況下,可能希望同一圖形中具有不同屬性型別的頂點。這可以通過繼承來實現。例如,要將使用者和產品建模為二部圖,可以執行以下操作:
與rdd一樣,屬性圖是不可變,分布式和容錯的。通過生成具有所需更改的新圖來完成對圖的值或結構的修改。原始圖形的大部分(未影響的結構,屬性和索引)在新圖中被重用,從而降低了此固有功能資料結構的成本。使用一系列頂點分割槽試探法在執行程式之間劃分圖。與rdd一樣,發生故障時,可以在不同的計算機上重新建立圖形的每個分割槽。邏輯上,屬性圖對應於一對型別化集合【rdd】,它們對每個頂點和邊的屬性進行編碼。結果,圖類包含訪問圖的頂點和邊的成員的類vertexrdd[vd]和edgerdd[ed]的延伸,並且被分別優化為rdd[(vertexid, vd)]和rdd[edge[ed]]。
分別使用graph.vertices和graph.edges成員將**析成相應的頂點和邊檢視。graph.vertices返回乙個vertexrdd[(string, string)]擴充套件的rdd[(vertexid, (string, string))],graph.edges返回乙個edgerdd,其包含edge[string]的物件。
除了屬性圖的頂點和邊檢視外,graphx還公開了乙個三元組檢視。三元組檢視在邏輯上將頂點和邊屬性結合起來,從而產生乙個rdd[edgetriplet[vd, ed]]包含edgetriplet類的例項。其圖形化為:
edgetriplet類擴edge通過新增類srcattr和dstattr分別包含源和目標屬性成員。可以使用圖形的三元組檢視來呈現描述使用者之間關係的字串集合。
正如rdds有基本操作map,filter和reducebykey等一樣,圖也有類似的函式,產生具有轉化特性和結構的新圖。已定義的具有優化實現的核心運算子如下:
這些運算子中的每乙個都生成乙個新圖形,其頂點或邊緣的屬性由使用者定義的map函式修改。
注意:在每種情況下,圖形的結構都不會改變,這是這些運算子的關鍵特徵,它允許結果圖重用原始圖的結構索引!
class函式reverse將返回逆轉所有邊緣方向的新圖。當嘗試計算反向pagerank時,這可能會很有用。由於反向操作不會修改頂點或邊緣屬性或更改邊數,因此可以有效的實現,而無需資料移動或複製。graph[vd, ed]
在許多情況下,有必要將外部資料(rdd)與圖形關聯起來。
1內連線(joinvertices)運算子連線輸入rdd並返回通過使用者定義關係關聯的新圖形。rdd中沒有匹配的頂點保留原始值。class
graph[vd, ed]
外連線(outerjoinvertices)運算子:因為並非所有的頂點在輸入rdd中都具有匹配值,所以在不確定的時候可以採用該型別。
許多圖形分析任務中的關鍵步驟是彙總有關每個頂點鄰域的資訊。例如:我們可能想知道每個使用者擁有的關注者數量或每個使用者的關注者的平均年齡。許多迭代演算法【例如:pagerank,最短路徑和連線的元件】反覆聚合相鄰頂點的屬性。為了提高效能,主要聚合運算子從graph.mapreducetriplets更改為graph.aggregatemessage。
graphx中的核心聚合操作為aggregatemessage,該運算子將使用者定義的sendmsg函式應用於圖形的每個邊三元組,然後使用該mergemsg 函式在其目標頂點處聚合這些訊息。
使用者定義的sendmsg函式採用edgecontext,將公開源和目標屬性以及邊緣屬性和函式,以將訊息傳送到源和目標屬性。可以將sendmsg視為mapreduce中的map函式。使用者定義的mergemsg函式接受兩條發往同一頂點的訊息,並產生一條訊息。可以認為是mapreduce中的reduce函式。使用aggregatemessages返回乙個vertexrdd[msg]物件,該物件包含該聚合訊息並將訊息發往各個頂點。未收到訊息的頂點不包含在返回的vertexrdd中。另外,aggregatemessage採用乙個可選引數tripletsfields,該引數指示訪問了哪些資料的edgecontext,選項在tripletsfields中定義,tripletsfields預設值為tripletsfields.all,指示使用者定義的sendmsg函式可以訪問任何edgecontext。tripletsfields引數可以設定只通知graphx的一部分,edgecontext從而允許graphx選擇優化的連線策略。例如:如果只需要源頂點資料,可以設定tripletsfields.src表示我們僅需要源頂點資訊。
在graphx的早期版本中,使用位元組碼檢查來推斷tripletsfields,但是我們發現位元組碼檢查稍微不靠譜,因而選擇了更明確的使用者控制。
**實戰例子參考:
spark預設情況下rdd不保留在記憶體中。為避免重新計算,可以在多次使用時顯式快取。graphx中的圖也是一樣。多次使用圖時,確保先呼叫graph.cache()。
在迭代計算中,為了獲得最佳效能,也可能需要取消快取。預設情況下,快取的rdd和圖儲存在記憶體中,直到記憶體壓力迫使它們按照lru【最近最少使用頁面交換演算法】逐漸從記憶體中移除。對於迭代計算,先前的中間結果將填滿記憶體。經過它們最終被移除記憶體,但儲存在記憶體中的不必要資料將減慢垃圾**速度。因此,一旦不再需要中間結果,取消快取中間結果將更加有效。這涉及在每次迭代中實現快取圖或rdd,取消快取其他所有資料集,並僅在以後的迭代中使用實現的資料集。但是,由於圖是有多個rdd組成的,因此很難正確地取消持久化。對於迭代計算,建議使用pregel api,它可以正確地保留中間結果。
圖是固有的遞迴資料結構,因為定點的屬性取決於其自身的屬性,又取決於其相鄰節點的屬性。這導致許多圖形演算法會迭代重新計算每個頂點的屬性,直到到達指定條件為止。其中,graphx實現了基於pregel api的變體。在較高層次上,graphx中的pregel運算子是受圖拓撲約束的大量同步並行訊息傳遞的抽象。tregel運算子在一系列超級步驟中執行,其中定點從上乙個超級步驟接收入棧訊息的總和,計算頂點屬性的新值,然後在下乙個超級步驟中將訊息傳送到相鄰的頂點。與pregel不同,訊息是根據邊三元組平行計算的,並且訊息計算可以訪問源頂點和目標頂點屬性。在超級步驟中會跳過未收到訊息的頂點。當沒有訊息剩餘時,pregel運算子終止迭代並返回最終結果圖。
注意,與標準的pregel實現不同,graphx中的頂點只能將訊息傳送到相鄰的頂點,並且使用使用者定義的訊息傳遞功能並行完成訊息的構造。這些限制允許在graphx中進行其它優化。pregel使用了兩個引數列表,第乙個引數列表包含配置引數,包含初始訊息,最大迭代次數以及傳送訊息的邊方向。第二個引數列表包含使用者定義的函式,這些函式用於接收訊息【頂點程式vprog】、計算訊息【sendmsg】以及組合訊息【mergemsg】。
spark graphx文章整理
graphx看到的比較有參考價值的文章 1.官方文件中文版 2.快刀初試 spark graphx在 的實踐 apache spark原始碼走讀之14 graphx實現剖析 8.graphx pregel api an example 9.spark入門實戰系列9.spark graphx介紹及例項...
Spark Graphx航班分析
提取碼 erd9 package flyfenxi import org.apache.spark.sparkcontext import org.apache.spark.graphx.import org.apache.spark.rdd.rdd import org.apache.spark....
Flask入門二 快速入門
from flask import flask 路由裝飾器 defhello world 檢視函式 return hello world 返回乙個字串 if name main 把程式儲存為hello.py 用python直譯器執行 python hello.py running on訪問 會看見 ...