¿Cuál es la forma adecuada de programar las tareas de apio para maximizar la productividad de los trabajadores?

Estoy desarrollando un sistema que construirá un enorme modelo de n-gramas para un proyecto de IA.
Mi tubería es la siguiente:
entrada de recursos -> Obtener datos -> Analizadores -> Entrenador
La entrada de recursos (básicamente URL que deben analizarse) no es constante, lo que significa que puedo introducir una gran cantidad de miles de recursos a la vez, luego otra gran cantidad de docenas y así sucesivamente.

Mi idea es implementar cada paso de la canalización como una tarea de Celery e implementarla en la nube (por ejemplo, usando los dynos de trabajo de Heroku). Pero soy nuevo en Celery y tengo dudas sobre cómo poner en cola estas tareas para que mis trabajadores trabajen al 100% y mantengan la integridad del sistema al mismo tiempo.
El enfoque directo es comenzar a poner en cola las tareas tan pronto como finalice la anterior, por lo que, por ejemplo, si obtengo una entrada de recursos de 1000 elementos, programaría 1000 tareas de "obtención de datos" y cada una de ellas pondría en cola un " parse" cuando haya terminado y así sucesivamente. Pero esto generará una gran cola porque llegarán más recursos antes de que finalicen estas tareas, y sé que tomará meses construir el modelo (¡si es que alguna vez se completa!).

Así que no estoy seguro de si Celery puede manejar todo eso sin caer en problemas de memoria (Heroku tiene sus límites) o cualquier otro problema que no puedo imaginar ahora. O tal vez debería usar una técnica más complicada como programar fragmentos de tareas cada X minutos, almacenar resultados parciales en la base de datos, etc., lo que podría evitar algunos de estos problemas, pero no obtendré el 100 % del tiempo de mis trabajadores.

¿Alguna idea?
¡Gracias!


EDITAR

La respuesta a mi pregunta está en los comentarios de la respuesta aceptada.

preguntado el 27 de julio de 12 a las 15:07

1 Respuestas

Al tener colas separadas para cada tarea y ejecutar un trabajador dedicado para cada cola, puede asegurarse de que su sistema utilizará el 100 % de los recursos del sistema y prestará la misma atención a cada tarea. Además, puede agregar trabajadores para equilibrar el procesamiento de tareas en función de los tiempos de ejecución de tareas.

Por ejemplo, definir tareas

@celery.task
def fetch(url):
    # fetch url
    return html

@celery.task
def parse(html):
    pass

y configurando enrutamiento automático:

CELERY_ROUTES = {'tareas.fetch': {'cola': 'fetch_queue'}, 'tareas.parse': {'cola': 'parse_queue'}}

Y trabajadores en funcionamiento:

$ celery worker -Q fetch_queue

$ celery worker -Q parse_queue

Tendrá un trabajador separado para cada tipo de tarea.

Usando devoluciones de llamada, puede analizar fácilmente después de buscar:

fetch.apply_async((url), link=parse.subtask())

PD Para buscar trabajador puedes usar Grupo de eventos para aprovechar las E/S asíncronas.

Respondido 28 Jul 12, 10:07

Pero las tareas no son igualmente costosas (en tiempo de CPU). Imagine que las tareas de "entrenamiento" toman el doble de tiempo que las tareas de "búsqueda". Con esta solución, el trabajador de capacitación trabajará el 100 % del tiempo, mientras que el trabajador de búsqueda solo estará ocupado el 50 % del tiempo. ¿Estoy equivocado? - eric marcos

Como mencioné, puede equilibrar la carga agregando más trabajadores para una tarea menos costosa. En su ejemplo, puede tener 2 trabajadores para tareas de "búsqueda" y un trabajador para "capacitación". - ella

Creo que te refieres a lo contrario, 2 trabajadores para la tarea más costosa. De todos modos, no veo la ventaja de su solución sobre la solución directa (sf) que mencioné en la pregunta. Además, la solución sf es muy escalable, ya que comenzaría con 1 trabajador que puede manejar todo tipo de tareas y luego escalaría si veo que va muy lento. Mi duda sobre la solución de sf es si Celery puede manejar una cola de miles de tareas durante meses (virtualmente, una cola infinita), o si esto surgirá algún tipo de problema... Por cierto, gracias por señalarme a Evenlet, parece muy bueno =) - eric marcos

Sí, quise decir lo contrario :) Mi respuesta mostró cómo aprovechar al máximo los recursos del sistema con múltiples tareas. - ella

El apio no maneja la parte de la cola. Recibe las tareas de una cola una por una (si no utiliza la captación previa múltiple) y las procesa. Miles de tareas en una cola es un número muy pequeño para la mensajería. Por ejemplo, RadditMQ puede manejar más de 50000 mensajes por segundo. - ella

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.