5

Ho un servizio che esegue scansioni di vari server. Le reti in questione possono essere enormi (centinaia di migliaia di nodi di rete).Gestione della coda TPL

L'attuale versione del software utilizza un'architettura di accodamento/threading progettata da noi che funziona ma non è efficiente come potrebbe essere (non ultimo perché i lavori possono generare figli che non vengono gestiti correttamente)

V2 sta arrivando e sto prendendo in considerazione l'utilizzo del TPL. Sembra che dovrebbe essere idealmente adatto.

Ho visto this question, la risposta alla quale implica che non ci sono limiti alle attività che TPL può gestire. Nei miei semplici test (Spin up di 100.000 task e assegnarli a TPL), TPL è stato messo in discussione abbastanza presto con un'eccezione Out of Memory (abbastanza corretto, specialmente sul mio box di sviluppo).

Le scansioni richiedono un intervallo di tempo variabile ma 5 minuti/compito è una buona media.

Come potete immaginare, le scansioni per reti enormi possono richiedere molto tempo, anche su server muscolosi.

Ho già installato un framework che consente ai processi di scansione (memorizzati in Db) di essere suddivisi tra più server di scansione, ma la domanda è come esattamente dovrei passare il lavoro al TPL su un server specifico.

Posso monitorare la dimensione della coda di TPL e (per esempio) ricaricarla se scende al di sotto di un paio di centinaia di voci? C'è un lato negativo a fare questo?

Devo anche gestire la situazione in cui è necessario mettere in pausa una scansione. Ciò sembra più facile da fare non assegnando il lavoro a TPL piuttosto che annullando/ripristinando attività che potrebbero già essere parzialmente elaborate.

Tutte le attività iniziali possono essere eseguite in qualsiasi ordine. I bambini devono essere eseguiti dopo che il genitore ha iniziato l'esecuzione, ma dal momento che il genitore li genera, questo non dovrebbe mai essere un problema. I bambini possono essere gestiti in qualsiasi ordine. Per questo motivo, attualmente sto immaginando che le attività figlio vengano riscritte sul Db non generato direttamente in TPL. Ciò consentirebbe ad altri server di "rubare" se necessario.

Qualcuno ha avuto esperienza con l'utilizzo della TPL in questo modo? Ci sono delle considerazioni di cui ho bisogno di essere a conoscenza?

+0

La pianificazione di migliaia di 'Task's, in cui ciascuno può richiedere diversi minuti, probabilmente non è una buona idea. In tal caso, il TPL pianificherà ripetutamente il 'Task', che probabilmente non è una buona idea nel tuo caso. – svick

+0

Non è chiaro per me se una data scansione (un'attività che dura da circa 5 minuti) passi la maggior parte del tempo in I/O in attesa di cose che tornano dalla rete o la maggior parte del tempo nella CPU che analizza le cose. Un paio di altri framework che potreste considerare più adatti per questo sarebbe TPL DataFlow e Reactive Extensions 2.0. Se è possibile fornire un codice che mostri l'aspetto di una determinata scansione (almeno in termini di alcuni pseudocodice per capire quale tipo di bilancia IO/CPU ha), ciò può aiutare gli altri a dare una direzione migliore. –

+0

@JamesManning Mi scuso, avrei dovuto renderlo più chiaro ...> Il 99% dei 5 minuti è in attesa sulla rete IO – Basic

risposta

10

TPL si tratta di avviare piccole unità di lavoro e eseguirle in parallelo. È non sul monitoraggio, la sospensione o la limitazione di questo lavoro.

Si dovrebbe vedere TPL come uno strumento di basso livello per avviare "lavoro" e sincronizzare i thread.

Punto chiave: attività TPL! = Attività logiche. Le attività logiche sono nel tuo caso attività di scansione ("scansione di un intervallo di IP da x a y"). Tale attività deve essere non corrispondente a un'attività fisica "System.Threading.Task" perché i due concetti sono diversi.

È necessario pianificare, orchestrare, monitorare e sospendere le attività logiche da soli perché TPL non li capisce e non può essere creato.

preoccupazioni Ora il più funzionale:

  1. TPL può certamente iniziare 100k compiti senza OOM.L'OOM è successo perché il codice attività memoria esaurita.
  2. Le reti di scansione sembrano un ottimo caso per il codice asincrono, perché mentre si esegue la scansione è probabile che si aspettino risultati con un elevato grado di parallelismo. Probabilmente non vuoi avere 500 thread nel tuo processo in attesa che arrivi un pacchetto di rete. Le attività asincrone si adattano bene al TPL perché ogni attività che esegui diventa puramente legata alla CPU e piccola. Questo è il punto debole per TPL.
+0

Grazie - quindi, in breve, adatterò la mia libreria esistente e manterrò la pianificazione, ecc ... il così com'è, ma semplicemente passare la gestione attuale del thread a TPL. – Basic

+0

@Basic, in realtà sì ;-) Se C# 5 è disponibile per rendere il codice async è abbastanza semplice. Se non si è su v5, è possibile considerare il pattern "async interator" come soluzione alternativa (http://blogs.msdn.com/b/pfxteam/archive/2009/06/30/9809774.aspx). – usr

+0

Grazie, ho scelto .Net 4.5 già - Perché non dal momento che una riscrittura è in lavorazione? Inoltre, mi piace molto il nuovo 'ApiController' in MVC;) – Basic