MEO Cloud - Python Lisbon Meetup

52
Codebits 2014 SNAKES ON THE CLOUD

Transcript of MEO Cloud - Python Lisbon Meetup

Codebits 2014

SNAKES ON THE CLOUD

Índice

1. MEO Cloud - apresentação

2. Backend

3. Desktop apps

4. API pública

5. Q/A

MEO Cloud• Serviço de alojamento e sincronização de ficheiros

• Clientes desktop para Windows, OSX e Linux (inc RPI)

• Clientes mobile para iOS, Android, Windows Phone

• Cifra client-side (beta)

• Tráfego mobile gratuito na rede PT

• Music player

• Upload2Me

Backend

Ideia inicial

1. Enviar ficheiros

2. Receber ficheiros

3. ????

4. Profit!!!

Arquitectura inicial• Metadata:

• BD relacional (MySQL)

• Ficheiros:

• Filesystem distribuído (GlusterFS)

• Web app:

• Nginx + Apache (mod_wsgi) + Python (Django)

Boneco

Desafios desenvolvimento

• Pedidos buffered

• Muitos pedidos lentos em simultâneo

• Green threads

• Modelo event-driven

• Expor servidor aplicacional

Desafios desenvolvimento

• Sincronização de alterações eficiente (deltas)

• Objectos (ficheiros) potencialmente grandes

• librsync

• dividir ficheiros em blocos <= 4MB

Desafios desenvolvimento

• Grande volume de dados (e metadados)

• Resiliência a falhas

• Sistemas escaláveis na horizontal

• Sem SPOF

Desafios desenvolvimento

• Deduplicação de dados

• Hashes dos blocos

Desafios desenvolvimento

• Segurança da informação

• Cifra em todos os passos

Tecnologias usadas• Python + gevent + Django + M2Crypto

• Cassandra

• Solr

• Zookeeper

• Swift

• uWSGI

• Nginx

• SAPO Broker

• Memcached

Diagrama

requirements.txt

• Django

• uWSGI

• gevent

• greenlet

• oauthlib

• M2Crypto

• duplicity

Core

requirements.txt

• SAPO-Broker

• requests

• pycassa

• kazoo

• python-memcached

Serviços

requirements.txt

• Pillow

• mutagen

• pybloomfiltermmap

• progressbar

• defusedxml

• dm.xmlsec.binding

• objgraph

• Jinja2

Utils

Desafios pós-lançamento

• Solução criada de raiz usando tecnologia recente (bleeding edge)

• uWSGI - http parser, connector https, Gevent loop engine, cache distribuído de sessões SSL

• Pycassa - connection pool && long-lived applications

• Solr - SolrCloud

Desafios pós-lançamento

• Schema Cassandra

• normalização vs desnormalização

• tombstones && slice queries

Desafios pós-lançamento

• Swift

• PUT && Rename VS store local

Desafios pós-lançamento

• Python GC

• objgraph

Desafios pós-lançamento

• Processamento não cooperativo ou CPU bound

• Muitos stacktraces, muito debugging

Alguns números…

• 60% imagens, 20% música, 10% vídeos

• 1,2M uploads/dia - 4,8MB tamanho médio

• 310K downloads/dia - 35MB tamanho médio

• Compressão - BZip2 (12,4%) - Zlib (11,7%)

Desktop Apps

Desafios• Codebase comum entre Windows, OS X e Linux

• Sincronização transparente em background (daemon que reage a eventos de rede e filesystem)

• Efficiente (RAM, CPU, Disco, Rede, Bateria)

• Robusta/Fiável -> Just works

• De longe, o maior desafio

• A vossa ajuda é preciosa. Really

Python 2.7 (custom) + C

Because awesome

Because speed

Tecnologias usadas

• GUI Windows: C++, Win32 API [Jorge Cruz]

• GUI OS X: Objective-C, Cocoa [Paulo Andrade]

• CLI Linux: Python, gevent [Francisco Vieira]

• GUI Linux: Python, GTK [Ivo Nunes]

Tecnologias usadas

Core de sincronização

Lessons Learned

Tratamento de erros

Tratamento de errosPOSIX Win32

Tratamento de errosErros do Windows: It’s over 9000!

Tratamento de erros• Não podemos pedir ao utilizador “Tente novamente mais

tarde”.

• Manter estado:

• O que é que falhou?

• Porque é que falhou?

• Já avisámos o utilizador?

• Quando é podemos voltar a tentar?

• O problema já está resolvido?

• Se é para rebentar, fazê-lo ASAP!

Sistema de Ficheiros• Surpresas do Python em Windows (para quem vem do Unix)

• rename() se ficheiro de destino já existe, erro

• open(<path>, ‘rb’) abertura em modo exclusivo -> várias aplicações partem

• readlink() (suporte para symlinks em Windows) não existe

• Tesourinhos: PROGRA~1 -> Usar GetLongPathNameW()

• OS X e Linux

• Pop quiz: link(file1, file2); rename(file1, file2). O que acontece?

Hint: é diferente de mv file1 file2

Nomes de ficheiros

Unicode Normalization

NFC, NFD, NFKC, NFKD

Nomes de ficheiros(pequeno guia para manter a sanidade mental)

• Em Windows, utilizar paths Unicode e “Long Path Names”, e.g. u’\\\\?\\C:\\file.txt' (>= Windows Vista)

• Em OS X, filesystem utiliza NFD

>>> unicodedata.normalize('NFC', u'João').encode('utf-8')

'Jo\xc3\xa3o'

>>> unicodedata.normalize('NFD', u'João').encode('utf-8')

'Joa\xcc\x83o'

• Em Linux, vale tudo :(

Rede(Much love for pycurl and pyuv)

• Reutilizar ligações para reduzir overhead handshake TCP e SSL

• Transferências simultâneas

• Mitigar overhead relacionado com disk seeks, deltas rsync, etc.

• Minimizar efeito “dente de serra” do TCP quando a latência ou packet loss são elevados

• Enviar apenas o que foi modificado (deltas rsync)

• SSL/TLS: garantir que os certificados são mesmo validados. Bonus points: Certificate Pinning

• Tratar timeouts, resets, stalls, outros.

CPU

• “O Python é lento” -> ineficiente, battery hog?

• “O Python não consegue usar mais que um processador em simultâneo” o “drama” do GIL (Global Interpreter Lock)”

CPU• O core é IO-bound (filesystem e rede)

• Tarefas que usam mais CPU implementadas em C:

• Crypto (block hashes, cifra client-side, SSL)

• deltas rsync

• sqlite (Row objects are cool)

CPU

• Na verdade, o GIL é liberto em muitos casos:

• Quando há IO (rede, filesystem)

• Quando os módulos querem :)

The GIL is free

• Cython

• Quando em dúvida, profile stuff: cProfile, logs (!), etc.

CPU10x mais rápido :)

Memória

6 lessons from Dropbox, on http://highscalability.com/

Memória

:(

malloc(…)

free(obj1)free(obj3)

Memória

To the moon!

Memória• Melhorou muito a partir do Python 3.4 (issue #11849)

• Fizemos backport do novo memory allocator (mmap/VirtualAlloc based) para o nossa versão do Python

• Exemplo: Quanta RAM precisamos para sincronizar?:

• 148.887 ficheiros (100.000 ficheiros aleatórios de 10KB + Linux 3.14 source tree):

• Ficheiro 50GB (much data)

MemóriaMB 100k ficheiros kernel tree

ficheiro 50 GB

force reclaim

50 MB RAM

API Pública

API Pública• Autenticação:

• OAuth 1.0a

• OAuth 2.0

• Documentação:

• https://meocloud.pt/developers

• Superset da API REST da Dropbox

• 40+ operações

Exemplos• Long-polling para notificação de alterações

• Key-Value store por user e por aplicação

• Download de pasta como zip

• Thumbnails

• …

• 95% da funcionalidade do web site

Use case(s)

• Cameras + Long polling = motion sensor

• CopyRef + Proximidade = instant transfers

• Upload 2 me = transferências anónimas

Perguntas?

Obrigado