Pregel:一個大規模圖計算系統

本文不是原文翻譯,但是包含所有重點的內容。查看原論文請點擊此鏈接

1.簡介

1.1 爲什麼開發Pregel

  1. 爲每一種圖算法都定製開發一個分佈式程序需要非常大的工作。
  2. 現有的分佈式計算平臺不能滿足圖計算的需求。像MapReduce可以處理非常大的數據量,但是處理圖計算的性能稍差。
  3. 用單機版本的圖算法限制了能處理的圖的規模。
  4. 現有的並行圖計算系統沒有容錯能力。容錯能力對大數據系統非常重要。

塊同步並行(Bulk Synchronous Parallel)模型的啓發Pregel的框架組織。
Pregel的計算由一系列的迭代組成,每步迭代叫一個超級步(superstep)。在一個超級步中,框架爲每一個頂點並行執行用戶的自定義函數。函數有頂點信息V和超級步S信息,可以讀取S-1步發送過來的信息,並且可以發送信息給其他頂點,這些信息會在S+ 1步收到。

2. 計算模型

在Pregel計算中,輸入是一個有向圖。每一個頂點都有一個唯一標識,標識的類型是字符串。每一個頂點都包含一個用戶定義的,可以修改的對象,代表頂點的值(value)。
有向邊和邊的起始頂點在一起。每個邊也有一個用戶定義的值,和目的頂點的標識符。

一個典型的Pregel計算過程包括(1)當圖被初始化時的圖數據輸入。(2)一些被全局同步點分割開的超級步,這些超級步執行迭代計算,直到計算結束。(3)計算結束時的結果輸出。

計算是否結束是根據每個頂點的投票。在超級步0,每個頂點都是活動狀態。活動狀態的頂點參加本超級步的計算。一個頂點可以通過投票停止計算來使自己變成不活動狀態。在以後的超級步計算中,這個頂點就不在參加計算,除非它收到信息後,又變成活動狀態。 再次變成活動狀態後,需要投票使自己變成不活動狀態。整個計算在所有頂點都處於非活動狀態時才停止。

我們不用遠程讀,也不使用共享內存。第一、因爲信息傳遞模式足夠了,不需要遠程讀。我們沒有發現哪個圖的算法,用信息傳遞的方式不能滿足。第二、在集羣環境中,從遠程服務器中讀取數據有非常大的延遲。我們通過異步的批量傳遞信息的方式來減少整體延遲。

圖計算可以用一系列的MapReduce來計算。因爲可用性和性能的原因,我們不選用。Pregel 在整個計算過程中,把頂點和邊一直保存在服務器內存中。MapReduce需要在每個MapReduce任務中重新構建頂點和邊。這樣需要傳遞更多的數據。

3. 計算API

3.1信息傳輸

用戶需要實現compute()方法,框架會爲每個活動的頂點調用compute方法。在此方法內,用戶可以用getValue得到此頂點的值,setValue來給頂點重新賦值。

// T: vertex value type 
// M: Message type send to target vertex.
class Vertex<V, M> {
      public void compute(MessageIterator messages);
      String getVertexID();
      int getCurrentSuperStep();
      T getValue();
      void setValue(T newValue);
      OutEdgeIterator getOutEdgeIterator();
      void sendMessageTo(String descVertex, M messageValue);
}

通常一個頂點會遍歷以它爲源頂點的邊,發送信息給邊上的目標頂點。但是在sendMessageTo 信息時,descVertex不一定非的是這個頂點的鄰居。

當信息傳遞的目的頂點不存在時,我們執行用戶定義的handler。這個handler可以創建沒有的頂點,也可以把起始頂點中,沒有目標頂點的邊刪除。

3.2 Combiners

可以通過Combiners減少發送數據和緩存數據的代價。假設發送的數據是數值型,到達目標頂點後會被加在一起。那麼可以把這些值合併成一個值,然後再發送或者保存。Combiner不是必須的,如果實現Combiner,需要滿足交換律和結合律,因爲不能保證Combiner的調用這些值的順序。

可以發現在最短路徑中,用Combiner後,發送的數據量只有不用Combiner的四分之一。

3.3 Aggregators

Aggregators 用來做全局通信。每個頂點可以在超級步S中提供一個值給Aggregator。系統會把這些值合併計算成一個結果值。這個值會讓所有頂點在S+1步看到。Pregel提供了一些內置的Aggregator,如min, max, sum.

Aggregators可以用來做統計。如用sum aggregator,每個頂點都輸出它的出度。在S+1步,可以得到圖中所有邊的個數。

Aggregators可以用來做全局協調。如當aggregator中計算出所有頂點滿足一定條件時,在Compute方法裏執行另一段邏輯。

定義一個新的Aggregator,需要繼承Aggregator類,並且計算要滿足交換律和結合律。

默認情況下,Aggregator的值只能在下一個超級步可以看到。用戶也可以定義(sticky)的Aggregator。(sticky)的Aggregator的值可以在所有超級步裏得到。 如頂點和邊的數量可以定義爲(sticky)的Aggregator.

Aggregator有更高級的用法。如可以用來實現分佈式的優先級隊列。在超級步中,每個頂點輸出minimum距離。合併後的minimum會在下一個超級步被廣播到所有的服務器。

3.4 修改圖的拓撲結構

一些圖算法需要修改圖的拓撲。一個聚類算法,可能用一個頂點來代表一個類別。最小生成樹算法只保留樹的邊,其他的邊都刪除。
在一個超級步中,多個頂點可能發起有衝突的請求。如兩個請求增加頂點V,每個請求的值不相同。我們用兩種機制:偏序和handlers。

和消息傳遞一樣,修改圖的拓撲結構也在請求發出後的下一個超級步生效。在超級步裏,先做刪除操作。做刪除操作時,先刪除邊,再刪除頂點,因爲刪除頂點隱含了把它所有的出邊都刪除。刪除做完再做增加操作,先增加頂點,再增加邊。所有圖的修改操作在調用compute()之前, 偏序解決了大部分的衝突問題。

剩餘的衝突問題通過用戶定義的handlers解決。比如在一個超級步裏,有數個創建相同的頂點的請求。默認情況下,系統會隨機選一個。用戶可以在handler裏,接收所有的相同頂點的請求,然後進行處理。增加邊和刪除邊也是同樣的道理。爲了保持Vertex的代碼簡單, handlers的定義不和Vertex在一起。

Pregel也支持純本地修改。如一個頂點增加或者刪除以它爲源頂點的邊。本地計算不會有衝突問題,所以本地修改立即生效。

3.5 輸入和輸出

存儲圖的格式有很多種。Pregel爲一些常見文件提供了readers和writers。如果不能滿足需求,用戶可以繼承Reader和Writer類,自己實現圖的讀寫程序。

4實現

Pregel 在Google的集羣上運行,文件存儲在GFS上或者在BigTable裏。

4.1基礎架構

Pregel把圖分成若干分區,每個分區有一些頂點和以這些頂點爲源頂點的所有邊。
僅用頂點的ID來決定該頂點屬於哪個分區。默認用hash(ID) mod N的方法,N是分區的數量。用戶可以使用自定義的分區策略,如Web圖把相同的站點的頁面放在同一個分區裏,可以減少遠程發送的信息量。

在不考慮故障恢復的情況下,Pregel程序的執行包含以下幾個步驟:

  1. 多個用戶程序開始在集羣上並行執行。 其中一個用戶程序作爲Master的角色。Master不處理任何圖數據,僅僅是協調工作。Works負責真正圖的計算。
  2. Master決定圖有多少個分區,並且決定每個work處理那些分區。一個 work 處理多個分區可以更好的負載均衡,並且會提高性能。每個Work負責維護它負責的這部分圖的狀態,執行用戶的compute方法,並且管理Works之間的消息傳遞。
  3. 在數據加載過程中,Master爲每個 work分配一部分用戶的輸入數據。這部分數據和在超級步裏處理的數據沒有關係。是從GFS或其他地方分佈式加載的數據。依次讀取數據,如果數據屬於本Work處理,就更新相關數據。如果數據屬於其他Work處理,則通過異步批量的方式發送給其他Work。
  4. Master給每個Work發送執行超級步的指令。Work爲每個分區分配一個線程。在此線程裏,查找活動的頂點,然後調用compute方法,並且提供上個超級步裏發送給該頂點的信息。信息是異步發送的,可以平衡計算和發送數據,但是在本超級步結束之前,要把數據都發送完。每個超級步執行後,都向Master彙報還有多少個頂點處於活動狀態。
  5. 當計算全部結束時,Master可能給每個Worker發送指令,保存結果。

4.2 故障恢復

故障恢復是通過檢查點實現的。在一個超級步執行之前,Master給Workers發送指令,來保存他們的分區到持久存儲上。包含頂點值,邊的值,和頂點的輸入信息(上一個超級步輸出的)。Master存儲Aggregator 信息。

Work的失效通過週期性的心跳來解決。如果Worer超過一定時間沒有收到來自Master的心跳信息,Worker就結束自己的進程。如果Master超過一定時間沒有收到來自Worker的心跳信息,Master認爲該Work失敗。

當一個或者多個Worker失效時,分配給這些Wokers的分區信息丟失。Master 從最後的檢查點重新分配圖分區信息到存活的Workers。假設最後的檢查點在S’步,現在執行到S步。S’可能比S早好幾個超級步。我們根據平均失敗模型來選擇執行檢查點的頻率,平衡執行檢查點的代價和恢復的代價。

細力度的恢復正在開發中。在細力度的恢復中,除了基本的檢查點外,Workers也保存所有的輸出信息到本地磁盤。這些輸出信息包括在加載圖時向其他Workers輸出的信息,和在每個超級步時輸出到其他Workers的信息。系統可以重新計算到超級步S’。 保存輸出信息增加了開銷,但是一般服務器上都有足夠的磁盤帶寬,保證IO不會成爲瓶頸。本方法只用計算丟失的分區。
細力度的恢復需要用戶程序的輸出是確定性的。如果程序中用到了隨機化,那麼可以用超級步編號和分區作爲Key來生成隨機數。非確定性的算法可以禁用細粒度的恢復,僅使用基本的基於檢查點的恢復。

4.3 Worker的實現

Worker在內存中保存它的這一部分圖的數據。數據包含頂點ID到頂點狀態的映射。頂點狀態包含它的當前值,出邊的列表,包含輸入信息的隊列和確定頂點是否處於活動狀態的標識。出邊的列表中每個元素包含目的頂點和邊的值。當Worker執行超級步時,它依次爲每個活動頂點執行compute方法,傳遞相關信息。

因爲性能的原因,活動頂點的標識和輸入信息隊列分開存儲。並且,僅存儲一份頂點和邊的信息。存儲兩份活動頂點信息和輸入信息隊列。一份是給當前超級步用,一份爲下一超級步用。如果節點V收到信息,那麼V會變成活動的,當前狀態可能不是活動的。(注:當前超級步執行時,會收到下一超級步用到的信息。一個超級步執行結束前,信息會發送結束。所以本次超級步執行的時候,本超級步需要的信息已經到達。本次超級步執行的時候,會收到下一超級步需要的信息)。

當compute()請求給其他頂點發送信息時,先判斷目標頂點是否是在同一個Worker裏。如果是,則直接放到目標頂點的輸入信息隊列裏。如果是遠程Worker,則放到一個緩衝區裏,如果緩衝區寫入的數據達到一定閾值,則異步的寫到遠程Woker裏。
當定義Combiner時,會在放到本地目標頂點的輸入信息隊列時調用,或者遠程Woker接收到這些數據時調用。雖然不能減少網絡發送的數據量,但是可以減少內存開銷。

4.4 Master的實現

Master主要負責協調Workers的活動。每個Worker在向Master註冊時,分配一個唯一的標識。Master維護一個活動的Woker列表。包含Woker的標識,它的地址信息,負責哪一部分圖計算信息。 Master的數據量和分區的數量相關,和頂點和邊的數量無關,所以Master可以爲很大的圖做協調計算。

大部分Master操作,包括輸入,輸出,計算,保存檢查點,從檢查點恢復,都在柵欄(barriers)處結束。Master發送同樣的請求到各Worker,並且等待Woker響應。如果Worker失敗,Master進入4.2描述的恢復模式。如果柵欄同步成功,Master進入下一個階段,例如在計算過程中,Master會增加全局超級步編號,並且進入下一超級步。

Master還保存關於計算過程的統計信息,和圖的狀態信息,如圖的大小,頂點的出度分佈,活動頂點的數量,最近超級步的運行時間和發送的信息量。爲了用戶監控,Master運行一個HTTP服務用於顯示這些信息。

4.5 Aggregators

Aggregator通過計算匯聚函數,把用戶函數輸出的值,合併爲一個全局的值。每一個Worker有Aggregator實例的集合,Aggregator實例用它的類型名和實例名標識。當Worker在執行一個超級步時,會合並Aggregators的所有數據爲一個本地數據。在超級步計算結束時,把本地數據發給Master,然後合併成一個全局數據。Master在下一個超級步開始前,把全局數據發送給所有Worker。

5. 應用

5.1 PageRank

以PageRank爲例,探討下Pregel的實現方法。首先,我們實現PageRankVertex類,繼承Vertex. 頂點用一個double 來存儲當前的PageRank值。因爲邊不存儲數據,邊的類型是void。我們設置Graph在超級步0初始化,每個頂點的值是1/NumVertices()。

class PageRankVertex : public Vertex<Double, Void ,Double>
public  void Compute(MessageIterator msgs) {
        if (superstep() >= 1) {
            double sum = 0;
            for (Message msg : msgs) {
                sum += msg.getValue();
            }
            this.value =0.15 / getNumOfVertices() + 0.85 * sum;
        }

     if (superstep() < 30) {
         int outSize = getOutEdgerIterator().getSize();
         sendMessageToAllNeighbors(this.value / n);
     } else {
         voteToHalt();
     }
    }

從超級步1開始,每個頂點把發送過來的值都加到sum裏。並且設置臨時的PageRank值爲0.15 / getNumOfVertices() + 0.85 * sum。到達超級步30後,不再發送信息,並且投票結束。實際運行中,PageRank算法可能會一直計算到收斂。

5.2 最短路徑

爲了簡單明瞭,我們主要關注單源最短路徑,即從一個頂點出發,到所有其他頂點的最短路徑。

class ShortestPathVertex extends Vertex<Integer, Integer, Integer> {
    public  void Compute(MessageIterator msgs) {
        int mindist = isSource(this.getVertexID()) ? 0 : Integer.MAX_VALUE;
        for (Message msg : msgs) {
            mindist = Math.min(mindist, msg.getValue());
        }
        if (mindist < this.getValue()) {
             this.setValue(mindist);
        }
        OutEdgeIterator iter = this.getOutEdgeIterator();
        for (OutEdge outEdge: iter) {
            sendMessageTo(outEdge.getTarget(), mindist + outEdge.getValue());
        }
        voteToHalt();
    }
}

class MinIntCombiner extends Combiner<Integer> {
    public void combine(MessageIterator msgs) {
        int mindist = Integer.MAX_VALUE;
        for (Message msg : msgs) {
            mindist = Math.min(mindist, msg.getValue());
        }
        output("combined_source", mindist);
    }
}

在這個程序裏,我們把每個頂點的初始距離都是Integer.MAX_VALUE. 在每一超級步,每個頂點先接收從上游鄰接頂點發過來的信息。用最小的值更新當前的值,然後更新它的下游鄰接頂點。依次類推,此算法會在沒有更新時結束。

本算法有一個Combiner來減少Woker之間傳輸的數據量。

6. 實驗

我們進行了各種最短路徑的測試,這些測試運行在由300臺多核通用服務器組成的集羣上。我們報告了二叉樹的運行時間(研究可擴展的特性),和用不同圖大小的對數正態分佈的隨機圖,對數正態分佈的隨機圖的所有邊的權重都設置爲1。

初始化集羣時間、在內存中生成測試圖的時間、和驗證結果的時間是不包括在度量信息裏。因爲這些實驗都運行相對較短的時間,失敗的可能性很低,所以我們禁用檢查點。

作爲Pregel和計算任務數量之間的可擴展性的一個指示圖,圖7顯示計算由10億頂點二叉樹組成的最短路徑的運行時間。Pregel的計算任務的數量從50提高到800,運行時間從174秒減少到17.3秒。用了16倍的計算任務,性能提升差不多10倍。

圖7:最短路徑--10億頂點的二叉樹: 在300臺多核服務器上,不同數量的計算任務的運行時間

爲了展示Pregel和圖大小之間的可擴展性。圖8展示了從10億頂點到500億頂點等不同大小組成的二叉樹的最短路徑的運行時間。這些測試固定用800個計算任務,運行在由300臺多核服務器組成的集羣上。運行時間從17.3秒到702秒顯示了低出度圖的運行時間和圖大小成比例。
在這裏插入圖片描述
圖8: 最短路徑--二叉樹: 不同圖大小,運行800個計算任務,運行在由300臺多核服務器組成的集羣上

7. 相關工作

Pregel是一個分佈式的編程框架,關注於爲用戶提供一個自然的圖計算API,並且隱藏分佈式的一些細節,如信息傳輸和故障恢復。在概念上,它和MapReduce很相似,但是提供了更加自然的圖API, 對圖的迭代計算更高效。Pregel和Sawzall[41]、Pig Latin[40]、Dryad[27, 47]不同,因爲Pregel隱藏了數據的分佈細節。 Pregel還有一點不一樣,因爲它實現了一個有狀態的模型,它用一個長駐進程來實現計算、交換信息、修改本地狀態,而不是用一個數據流模型。數據流模型只做基於輸入的計算,然後產生輸出數據。輸出的數據被其他任務接着計算。

8. 總結和下一步工作

本論文貢獻了一個大規模圖計算的模型,並且表示了它的產品特性、擴展性、故障恢復的實現。

基於我們用戶的反映,我們認爲此模型非常有用並且方便易用。已經部署了數十個Pregel應用程序,更多的正在設計、實現和調優。用戶反映一旦轉換爲“像頂點一樣思考”的編程模式,這些API變得直觀、靈活、並且易於使用。我們和最初的使用者密切合作,這些最初的使用者會影響API的設計,這一點不奇怪。例如,增加Aggregators來減少一些早期Pregel的一些限制。

Pregel的性能、可擴展性和故障恢復已經可以滿足數十億頂點的圖計算。我們正在研究可以擴展到更大規模的圖計算技術,像降低模型的同步,避免運行速度快的任務必須在超級步間的同步點經常等待的問題。

當前全部的計算狀態保存在內存中。 我們已經溢寫一些數據到磁盤,並且將繼續沿着這個方向進行開發,目的是在未來能使在數T字節的內存沒有的情況下可以進行大圖的計算。

爲服務器分配頂點並且最小化服務器之間的信息傳輸是一個挑戰。當拓撲能和信息流對應時,基於拓撲對輸入數據進行分區也許足夠,但是並不總是這樣。我們想設計動態重新分區的機制。

Pregel是爲稀疏圖設計的,主要是沿着邊進行通信。儘管已經非常謹慎的支持高扇出、高扇入的信息流,但是當絕大部分頂點都和其他的大部分頂點進行通信時,性能會下降。一些類似的算法可以用Combiners、Aggregators、或者修改圖來編寫Pregel友好的算法。當然類似的計算對於任何的高度分佈式的計算都困難。

一個比較實際的擔心是Pregel正在變爲生產環境中基礎架構的一部分。我們不能隨意的改變API,我們需要考慮兼容性。儘管如此,我們認爲我們設計的編程接口足夠抽象和靈活,對未來底層系統有較好的適應能力。

9. 聲明

我們特別感謝Pregel的早期使用者,我們還感謝Pregel的所有使用者對Pregel的反饋和提出的建議。

10. 參考文獻

[1] Thomas Anderson, Susan Owicki, James Saxe, and Charles Thacker, High-Speed Switch Scheduling for Local-Area Networks. ACM Trans. Comp. Syst. 11(4), 1993, 319-352.
[2] David A. Bader and Kamesh Madduri, Designing multithreaded algorithms for breadth-rst search and st-connectivity on the Cray MTA-2, in Proc. 35th Intl. Conf. on Parallel Processing (ICPP’06), Columbus, OH, August 2006, 523|530.
[3] Luiz Barroso, Jerey Dean, and Urs Hoelzle, Web search for a planet: The Google Cluster Architecture. IEEE Micro 23(2), 2003, 22-28.
[4] Mohsen Bayati, Devavrat Shah, and Mayank Sharma, Maximum Weight Matching via Max Product Belief Propagation. in Proc. IEEE Intl. Symp. on Information Theory, 2005, 1763-1767.
[5] Richard Bellman, On a routing problem. Quarterly of Applied Mathematics 16(1), 1958, 87-90.
[6] Olaf Bonorden, Ben H.H. Juurlink, Ingo von Otte, and Ingo Rieping, The Paderborn University BSP (PUB) Library. Parallel Computing 29(2), 2003, 187{207.
[7] Sergey Brin and Lawrence Page, The Anatomy of a Large-Scale Hypertextual Web Search Engine. in Proc. 7th Intl. Conf. on the World Wide Web, 1998, 107-117.
[8] Albert Chan and Frank Dehne, CGMGRAPH/CGMLIB: Implementing and Testing
CGM Graph Algorithms on PC Clusters and Shared Memory Machines. Intl. J. of High Performance Computing Applications 19(1), 2005, 81-97.
[9] Fay Chang, Jerey Dean, Sanjay Ghemawat, Wilson C. Hsieh, Deborah A. Wallach, Mike Burrows, Tushar Chandra, Andrew Fikes, Robert E. Gruber, Bigtable: A Distributed Storage System for Structured Data. ACM Trans. Comp. Syst. 26(2), Art. 4, 2008.
[10] Boris V. Cherkassky, Andrew V. Goldberg, and Tomasz Radzik, Shortest paths algorithms: Theory and experimental evaluation. Mathematical Programming 73, 1996, 129-174.
[11] Jonathan Cohen, Graph Twiddling in a MapReduce World. Comp. in Science & Engineering, July/August 2009, 29-41.
[12] Joseph R. Crobak, Jonathan W. Berry, Kamesh Madduri, and David A. Bader, Advanced Shortest Paths Algorithms on a Massively-Multithreaded Architecture. in Proc. First Workshop on Multithreaded Architectures and Applications, 2007, 1-8.
[13] John T. Daly, A higher order estimate of the optimum checkpoint interval for restart dumps. Future Generation Computer Systems 22, 2006, 303{312.
[14] Jerey Dean and Sanjay Ghemawat, MapReduce: Simplied Data Processing on Large Clusters. in Proc. 6th USENIX Symp. on Operating Syst. Design and
Impl., 2004, 137-150.
[15] Edsger W. Dijkstra, A Note on Two Problems in Connexion with Graphs. Numerische Mathematik 1,1959, 269-271.
[16] Martin Erwig, Inductive Graphs and Functional Graph Algorithms. J. Functional Programming 1(5), 2001, 467-492.
[17] Lester R. Ford, L. R. and Delbert R. Fulkerson, Flowsin Networks. Princeton University Press, 1962.
[18] Ian Foster and Carl Kesselman (Eds), The Grid 2: Blueprint for a New Computing Infrastructure (2nd edition). Morgan Kaufmann, 2003.
[19] Sanjay Ghemawat, Howard Gobio, and Shun-Tak Leung, The Google File System. in Proc. 19th ACM Symp. on Operating Syst. Principles, 2003, 29-43.
[20] Michael T. Goodrich and Roberto Tamassia, Data Structures and Algorithms in JAVA. (second edition). John Wiley and Sons, Inc., 2001.
[21] Mark W. Goudreau, Kevin Lang, Satish B. Rao, Torsten Suel, and Thanasis Tsantilas, Portable and Ecient Parallel Computing Using the BSP Model. IEEE Trans. Comp. 48(7), 1999, 670-689.
[22] Douglas Gregor and Andrew Lumsdaine, The Parallel BGL: A Generic Library for Distributed Graph Computations. Proc. of Parallel Object-Oriented Scientic Computing (POOSC), July 2005.
[23] Douglas Gregor and Andrew Lumsdaine, Lifting Sequential Graph Algorithms for Distributed-Memory Parallel Computation. in Proc. 2005 ACM SIGPLAN Conf. on Object-Oriented Prog., Syst., Lang., and Applications (OOPSLA’05), October 2005, 423{437.
[24] Jonathan L. Gross and Jay Yellen, Graph Theory and Its Applications. (2nd Edition). Chapman and Hall/CRC, 2005.
[25] Aric A. Hagberg, Daniel A. Schult, and Pieter J.Swart, Exploring network structure, dynamics, and function using NetworkX. in Proc. 7th Python in Science Conf., 2008, 11-15.
[26] Jonathan Hill, Bill McColl, Dan Stefanescu, Mark Goudreau, Kevin Lang, Satish Rao, Torsten Suel, Thanasis Tsantilas, and Rob Bisseling, BSPlib: The
BSP Programming Library. Parallel Computing 24, 1998, 1947-1980.
[27] Michael Isard, Mihai Budiu, Yuan Yu, Andrew Birrell, and Dennis Fetterly, Dryad: Distributed Data-Parallel Programs from Sequential Building Blocks. in Proc. European Conf. on Computer Syst., 2007, 59{72.
[28] Paris C. Kanellakis and Alexander A. Shvartsman, Fault-Tolerant Parallel Computation. Kluwer Academic Publishers, 1997.
[29] Donald E. Knuth, Stanford GraphBase: A Platform for Combinatorial Computing. ACM Press, 1994.
[30] U Kung, Charalampos E. Tsourakakis, and Christos Faloutsos, Pegasus: A Peta-Scale Graph Mining System - Implementation and Observations. Proc. Intl. Conf. Data Mining, 2009, 229-238.
[31] Andrew Lumsdaine, Douglas Gregor, Bruce Hendrickson, and Jonathan W. Berry, Challenges in Parallel Graph Processing. Parallel Processing Letters 17, 2007, 5-20.
[32] Kamesh Madduri, David A. Bader, Jonathan W. Berry, and Joseph R. Crobak, Parallel Shortest Path Algorithms for Solving Large-Scale Graph Instances. DIMACS Implementation Challenge - The Shortest
Path Problem, 2006.
[33] Kamesh Madduri, David Ediger, Karl Jiang, David A. Bader, and Daniel Chavarria-Miranda, A Faster Parallel Algorithm and Efficient Multithreaded Implementation for Evaluating Betweenness Centrality on Massive Datasets, in Proc. 3rd Workshop on
Multithreaded Architectures and Applications (MTAAP’09), Rome, Italy, May 2009.
[34] Grzegorz Malewicz, A Work-Optimal Deterministic Algorithm for the Certied Write-All Problem with a Nontrivial Number of Asynchronous Processors. SIAM J. Comput. 34(4), 2005, 993-1024.
[35] Kurt Mehlhorn and Stefan Naher, The LEDA Platform of Combinatorial and Geometric Computing. Cambridge University Press, 1999.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章