2010-12-16 58 views
2

爲了提高匹配系統的可擴展性,我在玩GPars庫。我希望能夠查詢數據庫並在結果同時處理的同時立即查詢數據庫。瓶頸在於從數據庫中讀取數據,所以我希望在數據庫可用時異步處理結果,並保持數據庫全部忙碌。我意識到我可能對演員框架的工作原理有一些根本的誤解,我很樂意予以糾正!使用groovy actors來最大化數據庫的吞吐量?

在僞代碼我試圖做到以下幾點:

定義兩個角色,一個是對數據庫運行選擇和其他處理的記錄。

  1. queryActor querys數據庫,將結果發送到processorActor
  2. queryActor立即再次querys數據庫,而無需等待processorActor完成

我大概可以實現簡單的使用情況下不使用的演員,但我的最終目標是擁有一個始終處理具有潛在不同數據源的新查詢的行爲者池,以便增加系統的吞吐量。

處理Actor將始終比數據庫查詢快得多,所以我想在未來同時查詢多個副本。

 def processor = actor { 
    loop { 
     react {querySet -> 
     println "processing recordset" 
     if (querySet instanceof Object[]) { 
      MatcherDataRowProcessor matcher = new MatcherDataRowProcessor(matchedRecords, matchedRecordSet); 

      matchedRecords = matcher.processRecordset(querySet); 
      reply matchedRecords 
     } 
     else { 
      println 'processor fed nothing, halting processor actor' 
      stop() 
     } 
     } 
    } 
    } 

    def dbqueryer = actor { 
    println "dbqueryer has started" 

    while (batchNum.longValue() <= loopLimiter) { 
     println "hitting db" 
     Object[] querySet 
     def thisRuleBatch = new MatchRuleBatch(targetuidFrom, targetuidTo) 
     thisRuleBatch.targetuidFrom = batchNum * perBatch - perBatch 
     thisRuleBatch.targetuidTo = thisRuleBatch.targetuidFrom + perBatch 
     thisRuleBatch.targetName = targetName 
     thisRuleBatch.whereClause = whereClause 
     querySet = dao.getRecordSet(thisRuleBatch) 
     processor.send querySet 
     batchNum++ 
    } 

    react { processedRecords -> 
     processor.send false 
    } 
    } 

回答

1

我建議看看GPars用戶指南的Dataflow Concurrency部分中的數據流隊列。您可能會發現Dataflow爲您的問題提供了更好/更清晰的抽象。數據流也可以與演員一起使用。

我認爲演員或數據流可以在這種情況下工作,並覺得決定歸結爲哪一個提供了更接近你想要完成的抽象。對我而言,任務,隊列,數據流的概念似乎是一個更加貼合術語的概念。

+0

感謝您的回答約翰。我正在研究gpars庫中的各種模式,事實上,我嘗試的第一個數據流就是數據流。當時我沒有那麼做,但是我應該完成這個實現來看看它是如何實現的。 – barrymac 2011-01-04 10:45:19

0

經過一番更多的研究後,我發現Gpars中的DataFlow併發性實際上是Actor支持的built on top。 DataGridOperatorTest在gpars java演示發佈(我需要做一個java實現)似乎是我需要做的一個很好的匹配。主線程等待多個流輸入被填充,在我的情況下是並行數據庫查詢。