HASHED / SHARDED ActionBlocks
-
21-12-2019 - |
Domanda
Ho un flusso costante di determinati elementi che ho bisogno di elaborare in parallelo quindi sto usando TPL Dataflow
.La cattura è che gli elementi che condividono lo stesso tasto (simili a un dizionario) dovrebbero essere elaborati in un ordine FIFO e non essere paralleli l'uno all'altro (possono essere paralleli ad altri articoli con valori diversi).
Il lavoro svolto è molto cpugato con serrature asincrono minime in modo che la mia soluzione fosse quella di creare una serie di generatori ActionBlock<T>
s le dimensioni del Environment.ProcessorCount
senza parallelismo e postare a loro in base al valore GetHashCode
del tasto.
Creazione:
_actionBlocks = new ActionBlock<Item>[Environment.ProcessorCount];
for (int i = 0; i < _actionBlocks.Length; i++)
{
_actionBlocks[i] = new ActionBlock<Item>(_ => ProcessItemAsync(_));
}
.
Uso:
bool ProcessItem(Key key, Item item)
{
var actionBlock = _actionBlocks[(uint)key.GetHashCode() % _actionBlocks.Length];
return actionBlock.Post(item);
}
.
Allora, la mia domanda è, è questa la soluzione migliore per il mio problema?Sto ferendo prestazioni / scalabilità?Mi manca qualcosa?
Soluzione
Penso che il tuo approccio sia ragionevole, supponendo che tu sappia che i codici HASH saranno distribuiti bene.
Se si desidera avere una migliore protezione contro le cattive distribuzioni, è possibile utilizzare un numero maggiore di generatori ActionBlock
s mentre limita il loro livello di concorrenza totale utilizzando un singolo personalizzato TaskScheduler
condiviso da tutti i blocchi.È possibile trovare tale scheduler in parallelextensionsextras o su msdn .