Domanda

Voglio ottenere la prospettiva della comunità su questo. Se ho un processo che è fortemente DB / IO legato, come intelligente sarebbe di parallelizzare i percorsi individuali di processo utilizzando la libreria Task Parallel?

Io uso un esempio ... se ho un mucchio di oggetti, e ho bisogno di fare le seguenti operazioni

  1. query un DB per un elenco di elementi
  2. Fare alcune operazioni di aggregazione per raggruppare alcuni elementi in base a un elenco dinamico di parametri.
  3. Per ogni risultato raggruppato, interrogare il database per qualcosa in base al risultato aggregato.
  4. Per ogni risultato raggruppati, Fare alcuni calcoli numerici (3 e 4 accadrebbe sequenziale).
  5. fare un po 'di inserimento e aggiornamento per il risultato calcolato in # 3
  6. Fare un po 'di inserimento e aggiornamento per ogni articolo restituito a # 1

A rigor di logica, posso parallelizzare in un grafico di compiti a passi # 3, # 5, # 6 come un elemento non ha alcuna incidenza sul risultato del precedente. Tuttavia, ognuno di questi sarà in attesa sul database (SQL server) che è bene e capisco che siamo in grado di elaborare solo per quanto riguarda il server SQL ci lascerà.

Ma voglio distribuire logicamente il compito sulla macchina locale in modo che i processi veloce come il database ci permette, senza dover attendere per qualche cosa da parte nostra. Ho fatto qualche prototipo finto dove ho sostituire il chiamate DB con Thread.Sleeps (ho provato anche alcune varianti con .SpinWait, che era un milione di volte più veloce), e la versione parallela è waaaaay più velocemente di quanto l'implementazione corrente che è completamente di serie e non in parallelo a tutti.

Quello che ho paura di sta mettendo troppa tensione sul server SQL ... ci sono delle considerazioni che dovrebbero prendere in considerazione prima di andare troppo lontano su questa strada?

È stato utile?

Soluzione

Un'altra opzione sarebbe quella di creare una pipeline in modo che il punto 3 per il secondo gruppo accadendo allo stesso tempo come il punto 4 per il primo gruppo. E se è possibile sovrapporre gli aggiornamenti al punto 5, fare anche questo. In questo modo si sta facendo accessi SQL simultanee e di trasformazione, ma non sovraccaricare il database, perché hai solo due operazioni simultanee in corso in una sola volta.

Quindi fate i passi 1 e 2 in modo sequenziale (presumo) per ottenere un insieme di gruppi che necessitano di ulteriore elaborazione. Poi. i tuoi principale inizia Discussione:

for each group
  query the database
  place the results of the query into the calc queue

Un secondo filo servizi coda il risultato:

while not end of data
  Dequeue result from calc queue
  Do numeric calculations
  place the results of the query into the update queue

Un terzo servizi filo coda di aggiornamento:

while not end of data
  Dequeue result from update queue
  Update database

Il System.Collections.Concurrent.BlockingCollection<T> è una coda molto efficace per questo genere di cose.

La cosa bella è che se è possibile scalare, se si vuole con l'aggiunta di più thread di calcolo o le discussioni aggiornamento se SQL Server è in grado di gestire le transazioni più concorrenti di query /.

io uso qualcosa di molto simile a questo in un programma di fusione / aggiornamento giornaliero, con ottimi risultati. Questo particolare processo non usa SQL server, ma piuttosto di file standard di I / O, ma i concetti si traducono molto bene.

Altri suggerimenti

Se la versione parallela è molto più veloce rispetto alla versione di serie, io non ti preoccupare la tensione sul server SQL ... a meno che, naturalmente, le attività che si sta eseguendo sono a bassa priorità rispetto ad alcune altre operazioni significative o time-critical che vengono eseguiti anche sul server di database.

La tua descrizione dei compiti non è ben compreso da me, ma suona quasi come più di tali operazioni avrebbero dovuto essere eseguite direttamente nel database (presumo ci sono dettagli che rendono questo non possibile?)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top