Pregunta

Quiero obtener una perspectiva de la comunidad sobre esto. Si tengo un proceso que está fuertemente DB / IO obligado, lo inteligente sería poner en paralelo trayectorias individuales del proceso utilizando la biblioteca de tareas en paralelo?

Voy a utilizar un ejemplo ... si tengo un montón de artículos, y tengo que realizar las siguientes operaciones

  1. Consulta de una base de datos para obtener una lista de los artículos
  2. Haga algunas operaciones de agregación a grupos determinados elementos en función de una lista dinámica de parámetros.
  3. Para cada resultado agrupado, consulta la base de datos de algo basado en el resultado agregado.
  4. Para cada resultado agrupado, hacer algunos cálculos numéricos (3 y 4 sucederían secuencialmente).
  5. Haga un poco de inserciones y actualizaciones para el resultado calculado en el # 3
  6. Haga un poco de inserciones y actualizaciones para cada artículo devuelto en el # 1

Lógicamente hablando, puede paralelizar en un gráfico de las tareas en los pasos # 3, # 5, # 6 como un elemento no influye en el resultado de la anterior. Sin embargo, cada uno de ellos estará esperando en la base de datos (SQL Server) que está muy bien y entiendo que sólo podemos procesar por lo que el servidor SQL nos deja.

Pero Quiero distribuir lógicamente la tarea en la máquina local para que se procesa más rápido que la base de datos nos permite sin tener que esperar para nada en nuestro extremo. He hecho algunas prototipo maqueta donde sustituyo las llamadas db con Thread.Sleeps (también probé con algunas variaciones .SpinWait, que era un millón de veces más rápido), y la versión paralela es muuuucho mas rápido que la implementación actual que es completamente serie y no paralelas en absoluto.

Lo que temo es poner demasiada tensión en el servidor SQL ... ¿hay alguna consideración que debería considerar antes de ir demasiado lejos por este camino?

¿Fue útil?

Solución

Otra opción sería la creación de una tubería de manera que el paso 3 para el segundo grupo sucediendo al mismo tiempo que el paso 4 para el primer grupo. Y si se puede solapar los cambios en el paso 5, hacer eso también. De esa manera usted está haciendo accesos concurrentes SQL y procesamiento, pero no sobre-imposición de la base de datos, ya que sólo tiene dos operaciones simultáneas ocurren al mismo tiempo.

Así que haces los pasos 1 y 2 de forma secuencial (supongo) para obtener un conjunto de grupos que requieren un procesamiento adicional. Luego. sus principales roscas de entrada:

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

Un segundo servicios de rosca los resultados cola:

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

Una tercera servicios de rosca la cola de actualización:

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

El System.Collections.Concurrent.BlockingCollection<T> es una cola muy eficaz para este tipo de cosas.

Lo bueno aquí es que si se puede escalar si así lo desea mediante la adición de múltiples hilos de cálculo o consulta / hilos de actualización si el SQL Server puede manejar más transacciones concurrentes.

Yo uso algo muy parecido a esto en un programa de fusión / actualización diaria, con muy buenos resultados. Ese proceso en particular no utiliza el servidor SQL, pero en lugar de archivos estándar de E / S, pero los conceptos traduce muy bien.

Otros consejos

Si la versión paralela es mucho más rápido que la versión de serie, no me preocupo por la cepa en su servidor SQL ... a menos que, por supuesto, las tareas que está realizando son de baja prioridad en comparación con algunas otras operaciones significativas o tiempo-críticos que también se llevan a cabo en el servidor de base de datos.

Su descripción de las tareas no se entiende bien por mí, pero casi suena como más de esas tareas deberían haber sido efectuada directamente en la base de datos (supongo que hay detalles que hacen que no sea posible?)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top