基于MapReduce編程模型的圖計算框架

來自: http://git.oschina.net/wdfnst/GraphMapReduce

GraphMapReduce: 基于MapReduce編程模型的圖計算框架

(名詞約束: 頂點Vertex-圖中頂點;節點Process-計算單元節點),目錄說明:

代碼主要包含四個文件: gmr.cpp gmr.h algorithms.h graph.h

|__graph/---------#此目錄包含測試用的圖例數據

|__include/-------#此目錄包含所使用到的第三方庫的頭文件(目前只用到了ParMetis,去掉了GKlib)

|__lib/------------#包含了使用到的第三方庫

|__gmr.cpp------#程序的main函數入口和迭代循環

|__gmr.h---------#包含主要的計算過程函數computing()和計算結果更新函數updateGraph()

|__algorithm.h---#常用圖算法的MapReduce實現

|__graph.h-------#定義了圖數據結果和常用的集中圖操作函數

</div>

一. 框架的基礎

1. MPI:

結算節點之間通信通過MPI實現;

2. MapReduce編程模型

3. 圖劃分:

為了將整圖的不同部分放到不同的計算節點進行并行計算,需要將整劃分為若干子圖。本框架中每個子圖包含三個部分{inners, borders, neighbors}, inners表示子圖內與其他子圖沒有連接的頂點;borders表示子圖內與其他子圖又連接的頂點;neighbors表示子圖外與本子圖連接的頂點。

二、迭代計算過程

1. 數據交換:

第一步,先遍歷自己計算的子圖graph與其他子圖的鄰居情況,并收集需要向其他節點發送的字節數,并申請發送緩沖區;

第二步,通過MPI_Alltoall()與其他節點交換其他節點需要接受的字節數,每個節點收到信息后,各自計算和申請接受數據需要的空間。

第三步,再次遍歷自己計算的子圖graph,并將需要發往其他節點的頂點信心拷貝到發送緩存char *sb;

第四部,調用MPI_Alltoallv(),將發送緩存中的數據發往各節點.

2. 計算1th/2:map

將子圖graph和接受緩沖區中的數據實例化為頂點Vertex,再調用業務邏輯函數map將Vertex生成key/value list。

3. 對生成key/value list進行排序: sort

4. 計算2th/2:reduce

將排序好的key/value list按照業務邏輯函數reduce進行規約.

5. 將reduce計算的結果更新到graph中

三. 編譯和運行

1. (not mandatory)切圖

切圖采用了metis庫,其源碼和說明位于include/metis中,其編譯使用可參考include/metis/README.md. 已經有切好的例圖,位于graph/下。

2. 編譯gmr

make clean && make

3. 運行

mpirun -np graph_nparts ./gmr

四. 例子

4.1 PageRank

4.1.1. 如下包含10個頂點的簡單圖,劃分之后包含三個子圖subgraphs[3]:

4.1.2. 迭代過程

  • 每個子圖現將自己的邊界頂點發送給其所連接的鄰居節點,采用MPI_Alltoall()實現;
  • 在每個計算節點的內部,將每個頂點映射為若干鍵值對: > {key, value1},其中key in [neighbors], value1 = value / neighbors.size()

    void map(Vertex &v, std::list<KV> &kvs){
    int neighbor_count = 0;
    while(v.neighbors[neighbor_count] != 0)neighbor_count++;
    
    float value = v.value / neighbor_count;
    for (int i = 0; i < neighbor_count; i++)
        kvs.push_back({v.neighbors[i], value});
    }
  • 在每個節點內將map生成的鍵值對按鍵值進行排序

  • 根據鍵值,對鍵值相同的鍵值組執行reduce函數

    KV reduce(std::list<KV> &kvs) {
    float sum = 0.0;
    for (auto kv : kvs) {
        sum += kv.value;
    }
    
    /*Pagerank=a*(p1+p2+…Pm)+(1-a)*1/n,其中m是指向網頁j的網頁j數,n所有網頁數*/
    sum = 0.5 * sum + (1 - 0.5) / (sizeof(vs) / sizeof(Vertex) - 1); 
    return {kvs.front().key, sum};
    }

4.2.3 PageRank終止點問題和陷阱問題

上述上網者的行為是一個馬爾科夫過程的實例,要滿足收斂性,需要具備一個條件: 圖是強連通的,即從任意網頁可以到達其他任意網頁: 互聯網上的網頁不滿足強連通的特性,因為有一些網頁不指向任何網頁,如果按照上面的計算,上網者到達這樣的網頁后便走投無路、四顧茫然,導致前面累 計得到的轉移概率被清零,這樣下去,最終的得到的概率分布向量所有元素幾乎都為0。假設我們把上面圖中C到A的鏈接丟掉,C變成了一個終止點,得到下面這個圖:

另外一個問題就是陷阱問題,即有些網頁不存在指向其他網頁的鏈接,但存在指向自己的鏈接。比如下面這個圖:

上網者跑到C網頁后,就像跳進了陷阱,陷入了漩渦,再也不能從C中出來,將最終導致概率分布值全部轉移到C上來,這使得其他網頁的概率分布值為0,從而整個網頁排名就失去了意義。

4.2 單源最短路算法SSSP(DJ算法)

4.3 并行廣度優先搜索算法的MapReduce實現

4.4 二度人脈算法:廣度搜索算法

五、對比實驗

Processor\Platform | GMR | Spark | GraphX | GraphLab | Pregel | 1 | | | | | | 3 | | | | | | 8 | | | | | | 16 | | | | | | 64 | | | | | |

</div>

 本文由用戶 Hop36R 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!