Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Celery: Procesamiento distribuido de tareas con Python

Celery: Procesamiento distribuido de tareas con Python

Introducción al uso de celery y a las caracteristicas mas habituales.

Jesús Espino

November 21, 2014
Tweet

More Decks by Jesús Espino

Other Decks in Programming

Transcript

  1. MADRID · NOV 21-22 · 2014 Celery: Procesamiento distribuido de

    tareas con Python Jesús Espino - Programador en Kaleidos y Taiga.io (@jespinog)
  2. MADRID · NOV 21-22 · 2014 ¿Que es celery? ❖

    Sistema cola de tareas ❖ Asíncrono ❖ Distribuido ❖ Python
  3. MADRID · NOV 21-22 · 2014 ¿Para qué usarlo? ❖

    Procesos lentos que pueden realizarse de forma asíncrona. (Envio de mails, recalculo datos). ❖ Tareas periódicas (como sustituto de cron). ❖ Tareas largas con posterior acceso a los resultados. ❖ Procesamiento distribuido. ❖ Procesamiento de flujos complejos de tareas.
  4. MADRID · NOV 21-22 · 2014 SHOW ME THE CODE

    Jerry Maguire © TriStar Pictures
  5. MADRID · NOV 21-22 · 2014 Instalar celery $ mkvirtualenv

    celery $ pip install celery $ apt-get install rabbitmq-server
  6. MADRID · NOV 21-22 · 2014 Mi primera tarea celery

    # Fichero: tasks.py from celery import Celery app = Celery('tasks', broker='amqp://guest@localhost//') @app.task def add(x, y): return x + y @app.task def duplicate(x): return x + x
  7. MADRID · NOV 21-22 · 2014 Mi primera tarea celery

    # Fichero: send_task.py import tasks tasks.add.delay(2, 2)
  8. MADRID · NOV 21-22 · 2014 Mi primera tarea celery

    $ celery -A tasks --loglevel=info worker $ python send_task.py
  9. MADRID · NOV 21-22 · 2014 Recuperando el resultado #

    Fichero: tasks.py from celery import Celery app = Celery('tasks', broker='amqp://guest@localhost//', backend='amqp') @app.task def add(x, y): return x + y @app.task def duplicate(x): return x + x if __name__ == “__main__”: res = add.delay(2, 2) print(res.get())
  10. MADRID · NOV 21-22 · 2014 Recuperando el resultado $

    celery -A tasks --loglevel=info worker $ python tasks.py
  11. MADRID · NOV 21-22 · 2014 Ejecutar tareas asincronas task(2,

    extra_info=7) task.delay(2, extra_info=7) task.apply_async((2,2), {"extra_info": 7}, **task_options)
  12. MADRID · NOV 21-22 · 2014 Afinando mis tareas add.apply_async((2,2),

    link=add.s(10)) add.apply_async((2,2), link_error=error_handler_task.s()) add.apply_async((2,2), countdown=60) add.apply_async((2,2), eta=datetime.now() + timedelta(days=1)) add.apply_async((2,2), expires=60) add.apply_async((2,2), expires=datetime.now() + timedelta(days=1)) add.apply_async((2,2), retry=True, retry_policy={‘max_retries’: 3, ‘interval_start’: 0, ‘interval_step’: 0.2, ‘interval_max’: 0.2)} add.apply_async((2,2), queue=”priority.high”)
  13. MADRID · NOV 21-22 · 2014 Signatures/Subtasks ❖ Forma de

    pasar tareas a otras tareas. ❖ Serializable. ❖ Contiene args, kwargs y opciones de la tarea. ❖ Básico para crear canvas. ❖ Permite aplicación parcial
  14. MADRID · NOV 21-22 · 2014 Signatures/Subtasks sub_add = add.subtask((2,

    2), countdown=10) sub_add.apply_async(countdown=1) partial_add = add.subtask((2, )) partial_add = add.s(2) partial_add(2) partial_add.delay(2) partial_add.apply_async((2, ))
  15. MADRID · NOV 21-22 · 2014 Primitivas de Canvas ❖

    group: Ejecuta en paralelo una lista de tareas, devuelve una lista. ❖ chain: Hace un pipe de una lista de tareas. ❖ chord: group + chain de una tarea. ❖ map: Ejecuta una funcion sobre todos los elementos de una lista. ❖ starmap: Ejecuta una funcion sobre todos las listas de *args de una lista. ❖ chunks: Un starmap que se divide en grupos.
  16. MADRID · NOV 21-22 · 2014 Group res = group([add.s(1,

    1), add.s(2, 2), add.s(3, 3)])() res.get() # [2, 4, 6] emails = get_from_db_list_of_emails() subject = “...” body = “...” group([send_email.s(email, subject, body) for email in emails])()
  17. MADRID · NOV 21-22 · 2014 Chain res = chain(add.s(1,

    1), add.s(2), add.s(3))() res.get() # 7 link_scrapping = chain(fetch_url.s(), extract_links.s(), store_links_on_db.s()) link_scrapping(“www.google.com”) link_scrapping = fetch_url.s() | extract_links.s() | store_links_on_db.s() link_scrapping(“www.google.com”)
  18. MADRID · NOV 21-22 · 2014 Chord res = chord([add.s(1,

    1), add.s(2,2), add.s(3,3)], list_sum.s())() res.get() # 12 chord([informe1.s(), informe2.s(), informe3.s()], enviar_informes.s())
  19. MADRID · NOV 21-22 · 2014 Map/Starmap duplicate.map([1, 2, 3])()

    # [2, 4, 6] add.starmap([[1, 1], [2, 2], [3, 3]])() # [2, 4, 6]
  20. MADRID · NOV 21-22 · 2014 Chunks res = add.chunks(zip(range(10),

    range(10)), 3)() res.get() # [[0, 2, 4], [6, 8, 10], [12, 14, 16], [18]]
  21. MADRID · NOV 21-22 · 2014 Workers $ celery -A

    tasks worker --config=celeryconfig $ celery -A tasks worker --concurrency=10 $ celery -A tasks worker -c 10 # 10 concurrent tasks $ celery -A tasks worker --queues high,normal,low $ celery -A tasks worker -Q high,normal,low $ celery -A tasks worker --events $ celery -A tasks worker -E $ celery -A tasks control --help $ celery -A tasks inspect --help
  22. MADRID · NOV 21-22 · 2014 Periodic tasks # Fichero:

    celeryconfig.py from datetime import timedelta from celery.schedules import crontab CELERYBEAT_SCHEDULE = { 'add-every-3-seconds': { 'task': 'tasks.add', 'schedule': timedelta(seconds=3), 'args': (16, 16) }, 'run-it-once-a-week': { 'task': 'tasks.add', 'schedule': crontab(hour=7, minute=30, day_of_week=1), 'args': (16, 16) }, } CELERY_TIMEZONE = 'UTC'
  23. MADRID · NOV 21-22 · 2014 Periodic tasks Usamos: $

    celery -A tasks --config=celeryconfig worker -B o: $ celery -A tasks --config=celeryconfig beat
  24. MADRID · NOV 21-22 · 2014 Monitoring $ celery -A

    tasks worker -E $ celery -A tasks events $ flower