El Blog de Trespams

Blog personal sobre tecnologia, gestió de projectes i coses que se me passen pel cap

Introducció a Celery

Introducció a Celery

Celery es una aplicació que ens permet crear tasques de feina asíncrones gestionades per un gestor de cues que està basada en l'enviament de missatges de manera distribuïda. Es focalitza en operacions en temps real però també suporta la calendarització de tasques.

Les unitats d'execució, anomenades tasques, s'executen de manera concurrent en un o més nodes de treball. Aquestes tasques poden executar-se de manera asíncrona bé de manera síncrona (esperant fins que la tasca està llesta).

El sistema de missatgeria recomanat per celery és RabbitMQ encara que és bastant agnòstic en el tema i pot fer servir com a substitut Redis, MongoDB o una base de dades sql.

Encara que el programa va sorgir lligat a Django, actualment és una llibreria que es pot utilitzar de manera independent. S'han creat dos projectes a partir de l'original, Celery manté l'estructura bàsica de la llibreria i django-celery manté la integració amb Django.

Bé, fins aquí la parrafada d'introducció traduïda amb més o menys fortuna de la documentació de Celery, el que estam dien és que celery ens permet executar tasques de manera distribuïda, on el director d'orquestra (si seguim les recomanacions) és una aplicació anomenada RabbitMQ, escrita en Erlang, per cert, que se n'encarrega de rebre les ordres de les tasques que s'han d'executar i les distribueix entre els distints nodes que estan registrats per a executar dita tasca. Aquest director és el que se n'encarrega de saber com està cada tasca i d'obtenir-ne el resultat quan aquesta finalitza, de manera que el programa que ha encomanat la tasca.

Així dons hem de distingir tres actors en tot això, l'aplicació que comana la tasca, l'aplicació que executa la tasca (el worker) i l'aplicació que se n'encarrega de la comunicació entre qui comana la tasca i qui l'execute. La gràcia de tot això és que podem tenir més d'un worker a distintes màquines o a la mateixa màquina, de tal manera que el gestor se n'encarrega de repartir les tasques en funció de qui està lliure per executar-les.

Pensem un noment amb el que això significa: podem passar de tenir una aplicació que ho fa tot, a un conjunt d'aplicacions que poden estar en distintes màquines que col·laboren entre sí. Resumint: ens permet l'escalabilitat horitzontal.

Per què fer servir Celery?

Abans de Celery la meva experiència havia estat amb Beanstalkd, un sistema semblant, molt simple i ràpid. Ara us contaré una batalleta, estant de cap de projecte per Tui España un dels projectes que duia era el de la creació d'un servei web per a la venda on-line de transfers i excursions. La informació estava (i supòs que encara hi és) a una base de dades Oracle i amb una estructura pensada per a introduir-hi informació, de manera que fer una consulta un poc complexa com "vull totes les excursions que hi ha tal dia que es poden fer des de tal punt" era extremadament lent. La solució que trobàrem va ser desnormalitzar la informació passant-la cap a una base de dades Postgresql, un parell mallorquí de milions de registres que s'actualitzaven diàriament.

La primera versió del programa de càrrega estava fet amb Java, va ser complexe de crear, gairebé 3 mesos de feina, mal de mantenir i executant-ho tot amb fils estava gairebé 2 hores en tenir-ho tot carregat.

La segona versió la férem amb Python, una setmana i mitja, un 10% del codi, més funcionalitat i utilitzarem Beanstalk per a distribuir les tasques, ja que la càrrega en sí es podia particionar molt bé. Això ens permeté aprofitar la potència de servidors que estaven ociosos i aprofitar també els temps morts entre la consulta a Oracle, el parseig de la resposta i la introducció a Postgres. A una de les proves posarem en marxa processos a 4 servidors diferents, amb un total d'uns 20 workers i un temps de càrrega d'uns 3 minuts. Amb 2 servidors el temps era d'uns 5 minuts, una millora molt significativa respecte a l'aplicació Java.

Així doncs una de les utilitat que tenim és la de poder distribuir tasques molt pesades entre moltes màquines. Celery el que té molt millor que Beanstalk és una documentació molt acurada, sistemes de monitorització i gestió i en el cas de fer servir Django, la possibilitat de mantenir les tasques dins el mateix projecte.

El segon ús important de Celery és la web. En aplicacions web el que volem és donar la millor experiència d'usuari possible, i aquesta experiència es degrada si l'usuari ha d'esperar molt. El que ens interessa és donar la resposta a l'usuari de que la seva comanda s'està està executant i deixar el servidor web lliure per poder atendre altres peticions. Imaginem-nos per exemple una aplicació de comerç electrònic on l'usuari demana una factura i aquesta li arriba en pdf. En sistemes de molta càrrega la generació del pdf pot degradar la resposta global de la web, el que és interessant és poder enviar la petició de factura a un sistema extern a la web i que sigui aquest l'encarregat de la generació i l'enviament. Aquest sistema no té perquè estar ni tant sols a la mateixa màquina on hi ha l'aplicació web o poden aprofitar-se hores de poca càrrega per a fer-ne la generació i l'enviament.

Anar cap a la complexitat d'arquitectura que representa afegir un sistema de cues asíncron a la nostra aplicació implica voler anar cap a un aprofitament dels recursos i sobretot entendre com funciona la nostra aplicació, què s'ha de fer de manera immediata i què es pot fer de manera asíncrona, saber quines són les tasques més feixugues que ens afecten i com podem paralelitzar-les i distribuir-les. L'altra solució és posar més màquina amb n-mil cores i passar de tot, però a més de ser una opció econòmicament més cara i tècnicament discutible, és una opció a curt termini, ja que si la nostra aplicació té molt èxit pot arribar un moment on ja ni hi hagi màquines més grans o el cost de les mateixes es mengi tot els nostres beneficis. Podem acabar fent feina pel fabricant de hardware i per pagar-ne les llicències associades.

Convençuts? Esper que sí. Un sistema així no és per totes les aplicacions, la complexitat d'instal·lació i manteniment és més gran que tenir tot el sistema en una màquina i sense distribuir, però si teniu necessitats de fer càlculs intensius de manera puntual o tasques per les quals no voleu fer esperar l'usuari Celery és una molt bona solució. A més pensau amb sistemes com el núvol d'Amazon, puntualment podem aixecar-ne tantes instàncies com calgui i executar-ne workers, o imaginem un Datacenter propi on la majoria de servidors estan ociosos, podem posar workers a les màquiens amb mensy càrrega per a que ajudin en els processos pesats. Se'ns obre un ventall de possibilitat pràcticament il·limitat.

En el proper post, instal·lació de Celery, la creació d'una tasca i un exemple d'integració amb Django, així com problemes que ens podem trobar i com a evitar-los.

blog comments powered by Disqus