deixa para depois, procrastinando com celery em python
DESCRIPTION
Palestra do #TDC2011 que mostra como usar o celery para tarefas distribuidasTRANSCRIPT
![Page 2: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/2.jpg)
O que é o Celery?
![Page 3: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/3.jpg)
Ponto forte do Celery
• Gerenciador de tarefas assíncrono
![Page 4: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/4.jpg)
Ponto forte do Celery
• Gerenciador de tarefasassíncrono
• Distribuído entre máquinas
![Page 5: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/5.jpg)
Os dois pontos fortesdo Celery
• Gerenciador de tarefasassíncrono
• Distribuído entre máquinas
![Page 6: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/6.jpg)
Os dois pontos fortesdo Celery
• Gerenciador de tarefasassíncrono
• Distribuído entre máquinas
• Agendador
![Page 7: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/7.jpg)
CeleryDentre os pontos fortes do Celerydestacam-se
• Gerenciador de tarefasassíncrono
• Distribuído entre máquinas
• Agendador
• Com tolerância a falhas
![Page 8: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/8.jpg)
Como Funciona?
![Page 9: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/9.jpg)
Resposta Curta
![Page 10: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/10.jpg)
.
![Page 11: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/11.jpg)
Resposta Longa
![Page 12: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/12.jpg)
EstruturaTarefa
Publicadores
Fila
Trabalhadores/Consumidores
![Page 13: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/13.jpg)
Tarefa
![Page 14: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/14.jpg)
Tarefa
from celery.task import task
@taskdef foo(val): return val
![Page 15: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/15.jpg)
Publicador
![Page 16: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/16.jpg)
PublicadoresSincronamente
>>> foo(5)5
![Page 17: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/17.jpg)
PublicadoresAssincronamente
>>> res = foo.delay(5)
![Page 18: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/18.jpg)
Dois Jeitos
# não bloqueia>>> res.ready()True ou False>>> res.result5# ou bloqueia>>> res.get()5
![Page 19: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/19.jpg)
Fila
![Page 20: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/20.jpg)
FilaBackend sugerido é o RabbitMQ
(todas as crianças legais do bairro usamerlang)
![Page 21: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/21.jpg)
Mas também suportaRedis
Beanstalk
MongoDB
CouchDB
e bancos suportados pelo ORM do Django
![Page 22: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/22.jpg)
Trabalhador
![Page 23: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/23.jpg)
TrabalhadorPode estar rodando em outra máquina
Cada Worker process ainda pode usarvários threads
![Page 24: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/24.jpg)
Trabalhador
$ celeryd
$ ./manage celeryd
![Page 25: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/25.jpg)
Por que?
![Page 26: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/26.jpg)
Web ou StandAlone?
![Page 27: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/27.jpg)
WebPainel de Escalabilidade (djangocon.eu)
http://2011.djangocon.eu/talks/47/
![Page 28: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/28.jpg)
Problemas comunsWhat are the common mistakes you see.--------------------------------------Things that take a long time ("sending an email")that lock up a process. Using the filesystem for caching.Testing locally and pushing it live and see it fall over.Using an external API can also take a long time.Work with timeouts to work around it.
![Page 29: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/29.jpg)
Processos demoradosentopem os tubes
![Page 30: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/30.jpg)
Soluções comunsTenha um celery de criança:Scaling wise, what should you think about before scalingbecomes an actual issue? And what should you definitelyleave until the moment comes you need to scale?----------------------------------------------
First things first: use a queue like celery, even on small sites.Get used to such a queue and have it in place, that'll help alot with performance later.Make sure you've got your databaseschema is mostly OK. It doesn't have to be perfect right away,but at least mostly OK.
Expect something to change and assume you'll have to swap somethingout later to improve the performance.
![Page 31: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/31.jpg)
email.pyfrom celery.task import taskfrom django.core.mail import send_mail
@taskdef send(subject, message, recipient_list, from_email=None, **kwargs): if subject[0] != "[": subject = "[projeto] "+ subject if from_email is None: from_email = "[email protected]" send_mail(subject, message, from_email, recipient_list, **kwargs)
![Page 32: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/32.jpg)
Um bom padrãofrom email import send
@taskdef relatorio(dados): ....gera relatorio.... send.delay("Relatorio Pronto", """ Pode baixadas daqui: http://fuuuuuu.com/relatorios/%s.pdf """% filename, (email,))
![Page 33: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/33.jpg)
StandAloneScripts
![Page 34: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/34.jpg)
Map Reducetarefas = []livros =["iliada.txt","odisseia.txt"....]for filename in livros: tarefas.append( conta_palavras.delay(filename) )
para pegar o resultado
if all([i.ready() for i in tarefas]): palavras = sum([i.result for i in tarefas])
![Page 35: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/35.jpg)
Armadilhas e dicas
![Page 36: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/36.jpg)
Django-celery noadmin
![Page 37: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/37.jpg)
Inicia um worker
$ ./manage.py celeryd -l info -E
![Page 38: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/38.jpg)
e daí: BAM!
![Page 39: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/39.jpg)
Tem que rolar também
$ ./manage.py celerycam
![Page 40: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/40.jpg)
Testar#no settings.pyTEST_RUNNER='djcelery.contrib.test_runner.run_tests'
from django.test import TestCasefrom myapp.tasks import add
class AddTestCase(TestCase):
def testNoError(self): """Test that the ``add`` task runs with no errors, and returns the correct result.""" result = add.delay(8, 8)
self.assertEquals(result.get(), 16) self.assertTrue(result.successful())
![Page 41: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/41.jpg)
Sem resposta
CELERY_IGNORE_RESULT = True
![Page 42: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/42.jpg)
Transactions nodjangodef bar(request): sanduiche = Sanduiche("Pernil") sanduiche.save() avisa_novo.delay(sanduiche.id)
![Page 43: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/43.jpg)
Especialmente seMIDDLEWARE_CLASSES = ( 'django.middleware.transaction.TransactionMiddleware', ...
![Page 44: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/44.jpg)
Assimdef bar(request): sanduiche = Sanduiche("Pernil") sanduiche.save() if transaction.is_managed(): transaction.commit() avisa_novo.delay(sanduiche.id)
![Page 45: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/45.jpg)
Para desenvolvimentofrom socket import error
try: avisa_novo.delay(sanduiche.id)except error: log.error("conexao recusada") if not DEBUG: raise error
![Page 46: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/46.jpg)
Muitas tarefas
for i in algo_grande: avisa_novo.delay(i)
![Page 47: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/47.jpg)
Muitas tarefassubtasks = []for i in algo_grande: subtasks.append(subtask(avisa_novo, args=(i)))
TaskSet(tasks=subtasks).apply_async()
![Page 48: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/48.jpg)
Créditoshttp://www.flickr.com/photos/lexnger/1794462309http://www.flickr.com/photos/atmtx/4250159996http://www.flickr.com/photos/prettydaisies/2368005479http://www.flickr.com/photos/benobryan/3766107097http://www.flickr.com/photos/eli_k_hayasaka/3989808211http://www.flickr.com/photos/carolinabarmell/2980660350http://www.flickr.com/photos/jjay/2415455625http://www.flickr.com/photos/tim_proffitt_white/3181616233http://www.flickr.com/photos/daniele_sartori/4484430735http://www.flickr.com/photos/project-404/27730644
![Page 49: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/49.jpg)
Dúvidas?@fractal
+Adriano Petrich
[codando.com.br, sfp.adrianopetrich.com,blog.adrianopetrich.com]
![Page 50: Deixa para depois, Procrastinando com Celery em Python](https://reader033.vdocuments.site/reader033/viewer/2022061206/5481d392b47959d80c8b4608/html5/thumbnails/50.jpg)