6 de fevereiro de 2015

Caso de Uso: Globo.com

   Nesse post é relatado o depoimento do engenheiro de software sênior da Globo, Juarez Bochi, sobre a necessidade de implantação e sua experiência implantando a base de dados Cassandra.

Fonte: http://planetcassandra.org/wp-content/uploads/2014/10/logo_globo-e1338484540158.jpg


"Globo.com é o braço da Internet do Grupo Globo, o maior conglomerado de mídia da América Latina. Recentemente transmitimos a Copa do Mundo da FIFA 2014 para mais de 450 mil usuários simultâneos.

Nosso novo player, chamado Clappr, suporta HLS, um protocolo que também da suporte as duas principais plataformas móveis: Android e iOS. Isto é uma enorme vantagem, porque podemos transmitir para web e para clientes móveis com um único protocolo, mantendo nossa arquitetura muito simples e eficiente. Basicamente, usamos um codificador (principalmente o Elemental) para codificar um sinal de vídeo em H.264 e ingerir o fluxo de vídeo em nosso segmentador (EvoStream) usando o protocolo RTMP. O Evostrean cria os pedaços de vídeo HLS e as listas de reprodução de vídeo em disco, isso porque HLS é baseada em HTTP, podemos usar um par de servidores distribuídos geograficamente de camada Nginx para fornecer e armazenar em cache os arquivos de vídeo.

Retrocedendo o Redis

Um dos novos recursos da nossa plataforma de streaming de vídeo ao vivo, desenvolvido para o Copa do Mundo foi o DVR, ou Digital Video Recording. Nós mantivermos o último par de horas do fluxo de vídeo gravado, para que o usuário pudesse pausar ou buscar de novo para assistir o gol que ele perdeu. Para a Copa do Mundo, que só tinha duas partidas simultâneas, portanto poderíamos facilmente manter os fluxos na memória. Para adicionar este recurso criamos um aplicativo Python que move os segmentos de vídeo HLS para o Redis que depois roteiriza o Nginx com Lua para obter os segmentos do Redis e gerar a lista de reprodução do HLS dinamicamente.

O principal problema com esta solução é que ela não tem alta disponibilidade. Se um servidor Redis falhar (o que é raro, mas acontece) gostaríamos de mudar para outra instância Redis para não perder todo o vídeo gravado. Felizmente isso não aconteceu durante qualquer partida da Copa do Mundo (embora não me importaria de excluir esses 7 gols da Alemanha). A outra questão é que esta solução não escala bem para mais fluxos. Uma vez que cada fluxo requer cerca de 10GB por hora registrado, não foi possível gravar muito mais do que dois ou três fluxos com uma única instância do Redis.

O Brasil teve recentemente eleições para presidente e governador e queríamos transmitir todos os 27 debates de governo que ocorreriam simultaneamente com a funcionalidade DVR. Mas como nossa solução com Redis não é escalável decidimos dar uma oportunidade ao Cassandra.

Acabou por ser relativamente simples modificar o nosso software Python para enviar os arquivos para o Cassandra, em vez do Redis, usando o driver DataStax Python. O problema mais difícil foi lidar a grande relação de arquivo de eventos que a aplicação tinha. Nos acabamos criando vários processos Phyton e usando execuções assíncrona. Outra questão é que nós não sabíamos como iríamos extrair os blods do Cassandra e entregá-los usando Nginx, uma vez que não foi possível encontrar um driver Cassandra disponível para Lua ou Nginx. Nós pensamos sobre o desenvolvimento de um aplicativo Python, mas somos grandes fãs de Lua e Ngnix, por isso, decidimos ir em frente e desenvolver o nosso próprio driver para Lua: lua-Resty-Cassandra; sim, é open source! Quando ficou pronto tornou-se muito fácil de portar nossos scripts Lua do Redis para o Cassandra.

Anti-padrões e Compactação no Cassandra

Nossa solução funcionou, mas o tempo de resposta com o Cassandra aumentou muito depois de algumas horas. Depois de um certo ponto, os clientes passariam do tempo limite (timeout) e a reprodução de vídeo iria parar. Levou umas semanas para nós percebermos que tínhamos implementado um conhecido anti-padrão do Cassandra: Queues e queue-like datasets.

Felizmente nós poderíamos resolver o problema com algumas mudanças simples.

Nós desnormalizamos nossos dados, usando diferentes tabelas em pedaços (uma vez que cada pedaço de vídeo pode ter até 2MB) e pedaço do index (que são armazenados como linhas e podem conter alguns milhares de colunas).

Mudamos a estratégia de compactação para LeveledCompactionStrategy, que funciona melhor quando você tem que fazer compactações frequentes. Ajustamos durable_writes para False já que a maioria dos nossos dados são efêmeros.

Por último e mais importante, pois sabíamos o tamanho máximo que uma lista poderia ter, podemos especificar a coluna de partida (filtering with id > minTimeuuid(now – playlist_duration)), como sugerido no blog do DataStax. Isso realmente atenua o efeito tombstones para leituras.

Após estas alterações, fomos capazes de alcançar uma latência na ordem de 10ms para o nosso percentual de 99%. Os debates foram realizados e fomos capazes de transmitir todos os 27 fluxos com 2 horas de gravação, sem grandes problemas. Estamos muito felizes com o Cassandra agora.

Detalhes da implantação

Estamos usando apenas 4 nós no momento. Cada nó tem 24 núcleos, 64GB de RAM, 6 discos e estamos executando o Cassandra 2.1.0 no RHEL 6.5. Temos cerca de 60GB de dados armazenados em cada nó (o RF é 2). A taxa de fluxo de rede é de cerca de 65 Mbits/s. A carga média da CPU é menor que 1. A latência de leitura de 99% é de 10ms e a latência de escrita de 99% é de 30ms."



Fonte: Planet Cassandra, Disponível em <http://planetcassandra.org/blog/interview/globo-rewinds-redis-for-their-dvr-system-fast-forwards-to-apache-cassandra-for-increased-availability/>, Acessado 04 de fevereiro de 2015.

Nenhum comentário:

Postar um comentário