Question

Je veux obtenir le point de vue de la communauté à ce sujet. Si j'ai un processus qui est fortement lié DB / IO, comment serait-il intelligent de paralléliser chemins de processus individuels en utilisant la bibliothèque parallèle de tâches?

Je vais utiliser un exemple ... si j'ai un tas d'articles, et je dois faire les opérations suivantes

  1. Interroger une base de données pour une liste d'éléments
  2. Faites des opérations d'agrégation pour regrouper certains éléments basés sur une liste dynamique des paramètres.
  3. Pour chaque résultat groupé, interroger la base de quelque chose en fonction du résultat agrégé.
  4. Pour chaque résultat groupé, faire des calculs numériques (3 et 4 se produiraient de manière séquentielle).
  5. Faites quelques insertions et mises à jour pour le résultat calculé # 3
  6. Faites quelques insertions et mises à jour pour chaque article retourné dans # 1

Logiquement, je peux paralléliser en un graphe de tâches aux étapes n ° 3, n ° 5, n ° 6 comme un article n'a aucune incidence sur le résultat de la précédente. Cependant, chacun d'entre eux seront en attente sur la base de données (serveur SQL) ce qui est bien et je comprends que nous ne pouvons traiter autant que le serveur SQL nous permettra.

Mais je veux distribuer logiquement la tâche sur la machine locale afin qu'elle traite aussi vite que la base de données nous permet, sans avoir à attendre quoi que ce soit sur notre fin. J'ai fait quelques prototypes maquette où je remplace les appels db avec Thread.Sleeps (j'ai essayé aussi quelques variations avec .SpinWait, ce qui était un million de fois plus rapide), et la version parallèle est waaaaay plus rapide que l'implémentation actuelle qui est complètement série et non parallèles du tout.

Ce que je crains, c'est de mettre trop de pression sur le serveur SQL ... sont là des considérations que je devrais considérer avant d'aller trop loin dans cette voie?

Était-ce utile?

La solution

Une autre option consisterait à créer un pipeline de sorte que l'étape 3 pour le deuxième groupe se produit en même temps que l'étape 4 pour le premier groupe. Et si vous pouvez chevaucher les mises à jour à l'étape 5, faire aussi. De cette façon, vous faites simultanément des accès SQL et le traitement, mais pas trop taxer la base de données parce que vous avez seulement deux opérations simultanées en cours à la fois.

Alors que vous faites les étapes 1 et 2 de manière séquentielle (je suppose) pour obtenir un ensemble de groupes qui nécessitent un traitement ultérieur. Ensuite. vos principaux départs de fil:

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

Un second services de fil les résultats file d'attente:

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

Un troisième services de fil de la file d'attente de mise à jour:

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

Le System.Collections.Concurrent.BlockingCollection<T> est une file d'attente très efficace pour ce genre de chose.

La chose intéressante est ici que si vous pouvez l'échelle si vous voulez en ajoutant plusieurs threads de calcul ou threads requête / mise à jour si le SQL Server peut gérer plusieurs transactions simultanées.

J'utilise quelque chose de très semblable à cela dans un programme de fusion / mise à jour, avec de très bons résultats. Ce processus particulier ne pas utiliser de serveur SQL, mais plutôt fichier standard E / S, mais les concepts se traduisent très bien.

Autres conseils

Si la version parallèle est beaucoup plus rapide que la version de série, je vous inquiétez pas au sujet de la pression sur votre serveur SQL ... à moins bien sûr les tâches que vous effectuez sont une faible priorité par rapport à d'autres opérations critiques ou beaucoup de temps qui sont également effectuées sur le serveur DB.

Votre description des tâches ne sont pas bien compris par moi, mais ça sonne presque comme plus de ces tâches auraient dû être effectuées directement dans les la base de données (je suppose que il y a des détails qui rendent ce pas possible?)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top