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

Trabajando de forma asincronica en Django/Python

Trabajando de forma asincronica en Django/Python

Martin Alderete

November 15, 2014
Tweet

More Decks by Martin Alderete

Other Decks in Programming

Transcript

  1. • Introducción y repaso • Presentación de la problemática •

    Introducción a los brokers de mensajes • Algunos brokers de mensajes • Soluciones propuestas a la problemática ◦ Arquitectura ◦ Analysis ◦ Resumen • Extra: Lock distribuido • Extra: Taskqueue (Appengine) • Pensamientos y conclusiones Agenda
  2. Protocolo de capa de aplicación utilizado por las web. Protocolo

    Request-Response (pregunta-respuesta). Protocolo SIN estados. Posee varios verbos (GET, POST, PUT, DELETE, ...) Define varios User-Agent Apps cliente (browser, crawlers, etc) Proxies webservers MÁS RÁPIDO SE RECIBE UN RESPONSE MEJOR ES! Repaso HTTP (HyperText Transfer Protocol)
  3. Presentación de la problemática “Conclusiones” Acoplado al ciclo Request- Response

    No puede moverse a otra máquina Propenso a ser un “cuello de botella” Necesita manejo de errores extras (poco DRY) send_registration_email(user) es bloqueante No escala! El trabajo “pesado” DEBE sacarse del ciclo Request-Response. Pesado: “Todo aquello que puede demorar, agregar overhead o no es necesario inmediatamente”
  4. Intro Brokers de mensajes (DS) Ventajas Contienen “Queues” tipo FIFO

    (FIFO-like) Generalmente se parecen a una HASH (key-value) Permiten desacoplar el sistema Permiten distribuir el sistema Permiten la intercomunicación entre tecnologías Permiten escalar de forma “mas” natural Desventajas Pensemos que Sistema == Sistema distribuido Agregan complejidad al stack Necesidad de mantenimiento
  5. Hardcore way! Resumen... Simple y Complejo Independiente del framework del

    Producer Desacopla el sistema Mueve el trabajo pesado a otro lado Control absoluto por parte de los desarrolladores Todo debe ser hecho “from scratch” Pegado a un solo broker (Redis) Escalabilidad limitada Se re-escribe mucho código Monitoreo ? Administracion ?
  6. Django-RQ: Ejecutando workers # Procesa solo ‘default’ python manage.py rqworker

    # Procesa ‘default’ y ‘high’ python manage.py rqworker default high # Procesa solo ‘low’ python manage.py rqworker low Django-rq nos provee un management command!
  7. Django-RQ: Ejecutando... # Corre en el thread actual (bloqueante) send_registration_email(user_id)

    # Corre en algun worker procesando ‘emails’ send_registration_email.delay(user_id) # Corre en algun worker procesando 'high' q = django_rq.get_queue('high') q.enqueue(send_registration_email, user_id)
  8. Django-RQ Resumen... Es simple de instalar y usar Define las

    “Queues” en las settings Concepto de “Job” y “Worker” Abstracción de la conexión contra Redis Abstracción de la comunicación con Redis Comando de Django para ejecutar workers Debemos crear jobs y ejecutar un worker Solo para Redis No almacena Resultados (debemos hacerlo nosotros) Para proyectos no muy demandantes ni que necesiten escalar mucho anda bien :)!
  9. Soluciones propuestas: Celery Celery is an asynchronous task queue/job queue

    based on distributed message passing. It is focused on real-time operation, but supports scheduling as well. The execution units, called tasks, are executed concurrently on a single or more worker servers.
  10. Celery pip install celery Celery = Python + Broker +

    Baterias incluidas! www.amqp.org
  11. Celery Application Es el punto de entrada de todo lo

    relacionado a Celery. Se crea una sola application (aka “app”). http://docs.celeryproject.org/en/latest/django/first-steps-with-django.html
  12. Tasks Son la base de una aplicacion Celery. Son de

    una clase. Tienen 2 responsabilidades: Definir que pasa cuando una task es llamada. Definir que hacer cuando el worker recibe la task. Todas las tasks tiene un nombre único. Son basicamente callables de python con magia. Por convension van en tasks.py Se crean usando un decorador: Reusable django apps/libraries @shared_task (from celery import shared_task) App concreta @task (from celery.task import task)
  13. Tasks Poseen muchos atributos que permiten definir cómo se comporta

    la tarea, por ejemplo: Task.name Task.bind Task.queue Task.max_retries Task.default_retry_delay Task.rate_limit Task.time_limit Task.soft_time_limit Task.ignore_result varios mas… http://celery.readthedocs.org/en/latest/reference/celery.app.task.html
  14. Routing Routing es el mecanismo por el cual podemos decidir

    cuál será la Queue que debería recibir el mensaje de una nueva tarea hacia un worker. RECOMENDADO en vez de ‘queue’ en la TASK!!!
  15. Tasks: Llamando Basicamente existen dos formas: Usando un shortcut y

    opciones definidas en el momento de crear la tarea (@shared_task, @task). Task.delay(arg1, kwarg1=value1) Usando la forma “larga”, permite customizar la llamada a la tarea modificando opciones de la tarea. Task.apply_async(args=l, kwargs=d, **options) http://docs.celeryproject.org/en/latest/reference/celery.app.task.html#celery.app.task.Task.apply_async
  16. Workers: Consumidores de tareas #loglevel=INFO celery -A projName worker --loglevel=info

    #mas workers celery -A projName worker --concurrency=10 #evenlet celery -A proj worker -P eventlet -c 1000 #autoscale (prefork, gevent) celery -A projName worker --autoscale=10,3 celery worker --help http://docs.celeryproject.org/en/latest/userguide/workers.html
  17. AsyncResult Celery nos provee de ser posible un AsyncResult (un

    future) con el resultado de ejecutar una tarea. Para que esto sea posible Celery utiliza un backend en donde almacena los resultados de las tareas. Este backend se configura en CELERY_RESULT_BACKEND Algunos backend validos son: cache (memcached), mongodb, redis, amqp, etc Cada backend tiene su configuracion. http://celery.readthedocs.org/en/latest/configuration.html#celery-result-backend
  18. Celery Canvas Celery nos provee mecanismos para poder agrupar, encadenar

    tareas, agregar callbacks, como así también procesar chunks de argumentos. Para esto se utiliza lo que Celery llama PRIMITIVAS. partial: Crea funciones parciales. group: Ejecución en paralelo. chain: Encadena tareas( f(g(a)) ). chord: Un grupo más un callback (Barrier). map: Similar a map() de Python. starmap: Similar a map() pero usa *args chunks: Separa una lista larga de elementos en partes. http://docs.celeryproject.org/en/latest/userguide/canvas.html
  19. Monitoreo: Celery Flower Monitoreo en tiempo real: Progreso e historial

    de tareas. Información sobre las tareas. Graficos y estadisticas. Control remoto: Estado y estadísticas de los workers. Apagado y reinicio de workers. Controlar autoscaling y pool size. Ver tareas que estan en ejecución. Administracion de queues. ETC… pip install flower celery -A projName flower --port=5555
  20. Pensamientos y conclusiones Los Brokers de mensajes: Llegaron para quedarse.

    Permiten sistemas con arquitecturas flexibles. Permiten la intercomunicación entre tecnologías. AMQP es un muy buen protocolo (www.amqp.org). Los sistemas distribuidos: Son complejos pero escalables. Agregan complejidad en el stack. Permiten distribucion del trabajo. Requieren mantenimiento/monitoreo constante Dificiles de debugear (mas si son multi-worker). Cada vez más servicios y pero más pequeños.
  21. Pensamientos y conclusiones Celery: Es EL framework para sistemas distribuidos.

    Es EL framework que todo Pythonista en sistemas distribuidos tiene que probar. Es un proyecto con mucho soporte/desarrollo. Tiene muy buena documentación. Es simple de configurar y poner en marcha. Es UN MUNDO para aprender y entender en profundidad. Se puede extender “facilmente” (signals, management commands, remotes). Tiene MUCHAS settings y features que aun no conozco/entiendo… Debe ser monitoreado como cualquier servicio. Algo seguro podemos charlar entre todos :)!
  22. Extra: TaskQueue Servicio dentro de AppEngine para procesamiento en background

    (builtin). Muy eficiente. API SUPER simple e intuitiva. Escalable. Seguro. https://cloud.google.com/appengine/docs/python/taskqueue/