tiempo threads programacion programa procesos paralela mismo metodos manejo hilos eliminar ejecutar detener concurrentes con como python multiprocessing celery gevent monkeypatching

threads - programa de hilos en python



Uso de Celery en procesos y gevent en tareas al mismo tiempo. (4)

Me gustaría usar Celery como una cola para mis tareas para que mi aplicación web pueda poner en cola una tarea, devolver una respuesta y la tarea se procesará mientras tanto / algún día / ... Construyo una especie de API, por lo que no Sepa qué tipo de tareas habrá de antemano. En el futuro, puede haber tareas relacionadas con solicitudes HTTP, otra IO, pero también tareas que consumen CPU. Con respecto a eso, me gustaría dirigir a los trabajadores de Celery en los procesos, ya que estos son un paralelismo de tipo universal en Python.

Sin embargo, también me gustaría usar gevent en mis tareas, por lo que podría hacer que una sola tarea genere muchas solicitudes HTTP, etc. El problema es que cuando hago esto:

from gevent import monkey monkey.patch_all()

El apio se detiene para trabajar. Comienza, pero no se pueden poner en cola tareas en forma efectiva; parece que van al intermediario, pero el trabajador de Celery no las recoge y las procesa. Solo comienza y espera. Si borro esas líneas y realizo la tarea sin ningún gevent ni paralelización, todo funciona.

Creo que podría ser porque los parches gevent también se enhebran. Así que lo intenté

from gevent import monkey monkey.patch_all(thread=False)

... pero luego Celery ni siquiera se inicia, se bloquea sin dar una razón (el nivel de depuración del registro está activado).

¿Es posible usar Celery para poner en cola tareas y gevent para hacer algunas cosas dentro de una sola tarea? ¿Cómo? ¿Qué hago mal?


Creo que la forma recomendada para comenzar la tarea es la siguiente.

python manage.py celery worker -P gevent --loglevel=INFO

Gevent necesita ser reparado lo antes posible.


Desde mi extraña experiencia, Celery Beat no puede funcionar correctamente con trabajadores con gevent pool (las tareas programadas están bloqueadas y esperan para siempre), a menos que active el parche de gevent monkey para el proceso de Beat.

Sin embargo, celery beat no admite la --pool=gevent o -P gevent . La forma correcta de inyectar parches de gevent monkey es usar un binario curstomized de celery , como:

#!/usr/bin/env python # -*- coding: utf-8 -*- from gevent import monkey monkey.patch_all() import re import sys from celery.__main__ import main if __name__ == ''__main__'': sys.argv[0] = re.sub(r''(-script/.pyw|/.exe)?$'', '''', sys.argv[0]) sys.exit(main())

celery-gevent como celery-gevent y ejecute el servicio Beat de la siguiente manera:

celery-gevent beat --app=proj.celery:app --loader=djcelery.loaders.DjangoLoader -f /var/log/celery/beat.log -l INFO --workdir=/my/proj --pidfile=/var/run/celery/beat.pid

En proj.celery también deberías parchear la conexión Django para evitar DatabaseError :

from __future__ import absolute_import import os # Set the Django settings module for the ''celery'' program os.environ.setdefault(''DJANGO_SETTINGS_MODULE'', ''proj.settings'') import django # Load Django model definitions, etc django.setup() from django.db import connection # Allow thread sharing to ensure that Django database connection # works properly with gevent. connection.allow_thread_sharing = True from django.conf import settings from celery import Celery app = Celery(''proj'') # Using a string here means the worker will not have to # pickle the object when using Windows. app.config_from_object(''django.conf:settings'') app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)

(El ejemplo anterior funciona para Python 2.7.10, Celery 3.1.18, Django 1.8.2 y gevent 1.0.2)


Por lo que pude aprender, esto no es posible . Si alguien encuentra una mejor respuesta, la aceptaré en lugar de esta mía.

La única opción es usar gevent también como backend para los trabajadores de Celery. Lo que uno tiene que hacer para lograr tal cosa es agregar lo siguiente en el archivo de configuración:

CELERYD_POOL = ''gevent''

Más detalles sobre estas opciones se pueden encontrar here . Más información sobre la piscina de gevent está en esta página . Tenga en cuenta el hecho de que el grupo de gevent todavía está marcado como experimental. No encontré puntos de referencia disponibles para comparar procesos y async gevent pool en diferentes tareas (tareas orientadas a IO, tareas orientadas a la CPU), pero finalmente me di cuenta de que incluso mis tareas relacionadas con la CPU serán de hecho más IO que CPU, porque uso la base de datos para guardar resultados y la conexión de la base de datos será un cuello de botella, no la parte informática. No tendré ninguna tarea científica que realmente afecte a la CPU.


Puede ejecutar el apio con varios hilos que contienen varios greenlets como este:

$ celery multi start 4 -P gevent -l info -c:1-4 1000