2010-12-16 4 views
2

Я играю с библиотекой GPars, работая над улучшением масштабируемости соответствующей системы. Я хотел бы иметь возможность запрашивать базу данных и немедленно запрашивать базу данных, пока результаты обрабатываются одновременно. Узкое место читается из базы данных, поэтому я хочу, чтобы база данных работала полный рабочий день, обрабатывая результаты асинхронно, когда они доступны. Я понимаю, что у меня могут быть некоторые фундаментальные недоразумения в отношении того, как работает актерский каркас, и я был бы счастлив, если бы его исправили!Использование массивных актеров для максимальной пропускной способности из базы данных?

В псевдокоде я пытаюсь сделать следующее:

Определение двух актеров, один для работы выбирает к базе данных, а другой для обработки записей.

  1. queryActor querys база данные и отправляет результаты processorActor
  2. queryActor сразу querys базы данных снова, не дожидаясь processorActor закончить

я мог бы достичь простого случая использования без актеров, но моя конечная цель иметь пул актеров, который всегда работает над новыми запросами с потенциально разными источниками данных, чтобы увеличить пропускную способность системы в целом.

Оператор обработки всегда будет намного быстрее, чем запрос к базе данных, поэтому я хотел бы запросить несколько реплик одновременно в будущем.

 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

Я хотел бы предложить взглянуть на DataFlow Очереди в Dataflow Concurrency разделе руководства пользователя для GPars. Вы можете обнаружить, что Dataflows обеспечивают лучшую/чистую абстракцию для вашей проблемы. Потоки данных также могут использоваться совместно с участниками.

Я думаю, что в этой ситуации будут работать либо актеры, либо потоки данных, и почувствовать, что решение сводится к тому, что обеспечивает абстракцию, которая более точно соответствует тому, что вы пытаетесь выполнить. Для меня концепция задач, очередей, потоков данных кажется более подходящей терминологией.

+0

Спасибо за ваш ответ Джон. Я смотрел на различные шаблоны в библиотеке gpars, и действительно, первое, что я пробовал, это поток данных. В то время я не дошел до этого, но я должен закончить эту реализацию, чтобы понять, как это получается. – barrymac 2011-01-04 10:45:19

0

После нескольких исследований я обнаружил, что материал параллелизма DataFlow в Gpars на самом деле является built on top поддержки Actor. DataflowOperatorTest в демонстрационном дистрибутиве gpars java (мне нужно сделать реализацию Java), похоже, подходит для того, что мне нужно делать. Основной поток ожидает ввода нескольких потоков, которые в моем случае являются параллельными запросами базы данных.

Смежные вопросы