De Cassandra para Scylla — parte 01
Dissecando um processo de migração de base de dados na vida real
É meio que senso comum… migração de base de dados é uma das operações mais complexas e arriscadas que a galera da cozinha (plataforma / infra / OPs / SRE e cercanias) pode enfrentar.
Ainda mais quando estamos lidando com a base de dados “principal” da empresa . Definição bem abstrata, eu sei, mas se você é startupêro provavelmente já lembrou de alguma.
Mesmo assim — vez em quando — o trabalho e o risco valem a pena. Principalmente se houver ganhos consideráveis em termos de custo e performance.
O objetivo desta série de posts é descrever as decisões estratégicas, passos tomados e a experiência real de migração de uma base de dados em Cassandra para Scylla do ponto de vista prioritariamente técnico.
Bora começar com o caso de uso?
Aqui na Cobli, trabalhamos com telemetria de frotas de veículos. Explico: existe um dispositivo IoT em cada veículo que envia continuamente pacotes de dados em intervalo de alguns segundos.
No conjunto, esse volume de dados se torna expressivo. Em picos de utilização, chega a mais de 4.000 pacotes por segundo. Cada pacote deve ser triado, processado e armazenado no menor tempo possível. O resultado do processamento dos pacotes são informações relevantes aos nossos clientes (alertas de veículos acima da velocidade, histórico de trajetos etc) que também devem ser salvas. Tudo o mais próximo possível do “tempo real”.
Os principais requisitos de uma “base de dados” para nossas funcionalidades são alta disponibilidade e capacidade de escrita, missão delegada com sucesso para o Cassandra.
Não vou me alongar sobre todos os porquês da migração para o Scylla, mas posso resumir como a busca de um Cassandra mais rápido e — principalmente — mais barato.
Para quem é do Cassandra e não conhece o Scylla, vale uma fuçada nesta página. Em suma: Scylla é um Cassandra repaginado com foco em performance, mantendo um alto nível de compatibilidade com o mesmo (em termos de funcionalidades, APIs, ferramentas, CQL, tipos de tabelas e por aí vai…).
Qual Scylla?
O Scylla é parecido com o Cassandra no que se refere a formas de distribuição: existe a versão open source, a versão enterprise e empresas de SaaS que proveem base de dados como serviço.
Já está enraizado na cultura da Cobli: usar SaaS = foco no core business. A escolha pelo SaaS foi unânime.
O mundo Scylla é relativamente novo, e o SaaS que existe é o Scylla Cloud (não encontramos nenhum outro… ainda). Baseamos nossos cálculos de tamanho do cluster e projeção de custo através das opções disponibilizadas pelo SaaS, o que também simplificou um bocado o processo.
Outro ponto que nos deixou confortável foi a forma de integração entre nossa infraestrutura e o SaaS, comum ao mundo AWS: o modelo Bring Your Own Account. Basicamente delegamos a Scylla Cloud acessos para criação de recursos na AWS em uma conta específica, porém continuamos com o ownership desses recursos.
Antes de mais nada, fizemos um pequeno discovery com o Scylla Cloud:
- Configuramos um cluster free-tier vinculado a nossa conta AWS
- Configuramos conectividade com nosso ambiente (VPC peering) e testamos
- Validamos as interfaces de operação e monitoramento disponibilizados pela Scylla Cloud.
O Scylla Cloud provê uma interface de monitoramento incorporada ao cluster. Não é uma solução exclusiva — faz parte da versão open source da Scylla — , mas a vantagem é ser gerida por eles.
Diferença importante em relação ao Cassandra: não existem métricas por tabela/keyspace; só métricas globais. Essa restrição vem do core do Scylla, não do Scylla Cloud. Parece que existe um avanço recente no tema, mas na migração simplesmente aceitamos esse drawback.
Com o tempo, verificamos também que as métricas do Scylla Cloud são retidas por cerca de 40/50 dias. Algumas projeções podem precisar de mais tempo que isso. Felizmente é possível exportar as métricas no formato Prometheus — aceito por uma enorme gama de integrações — e replicar as métricas em outros softwares.
Por último, sentimos falta de uma interface de administração de backups (agendamento, pedidos sob demanda, deleção de backups antigos etc). As configurações de backup passam por sistemas de tickets e, obviamente, interações com o suporte ao cliente.
Primeira pergunta: é viável?
Sob o ponto de vista técnico, a primeira etapa da nossa jornada foi aferir se o Scylla é viável em termos funcionais, performáticos e que a migração dos dados coubesse dentro das restrições de tempo e esforço.
Validação funcional
Subimos um container com a versão “alvo” de Scylla (Enterprise 2020.1.4) e rodamos nossas migrações (sim, usamos migrações no cassandra!) e voilá!! Nossa base em Scylla sem mudar uma linha.
Ressalva: pode não ser sempre assim. A Scylla mantêm uma página com informações sobre compatibilidade que merece ser visitada para evitar surpresas.
Nossa validação funcional se resumiu a rodar todos os testes de todos os nossos softwares que usam o Cassandra apontando para a versão dockerizada do Scylla.
Na maior parte dos casos, não tivemos nenhum problema. Porém um dos testes retornou:
partition key cartesian product size 4735 is greater than maximum 100
A query em questão é um SELECT com a cláusula IN. Esse é um uso desaconselhado pelo Cassandra, e que o Scylla resolveu restringir de forma mais agressiva: a quantidade de valores dentro da cláusula IN é limitada por algumas configurações.
Alteramos a configuração de acordo com nosso caso de uso, o teste passou e seguimos em frente.
Validação de performance
Instanciamos um Cassandra e um Scylla com suas configurações de “produção”, populamos igualmente algumas tabelas com o auxílio do dsbulk e aplicamos testes de stress.
Os testes foram basicamente cenários comuns de leitura/escrita existentes em nossa plataforma utilizando o cassandra-stress.
Antes dos testes, seguindo recomendações da própria Scylla, trocamos a compactação size-tiered do Cassandra para a nova incremental compaction do Scylla para minimizar o space amplification.
Obs: essa compactação só existe na versão enterprise.
O ScyllaDB apresentou números surpreendentes, diminuindo de 30% a 40% as latências das queries mesmo com a metade do hardware (em termos de CPU).
Nota: este teste se mostrou insuficiente, pois o ambiente de produção é muito mais complexo que conseguimos simular. Enfrentamos alguns percalços durante a migração dignos de outro post, mas nada que já não tenha sido recompensado pela performance que o Scylla tem apresentado após as devidas correções.
Discovery do processo de cópia dos dados
Esse ponto fez-se importante para sabermos de que forma e em quanto tempo conseguiríamos ter o Scylla com todos os dados do bom e velho Cassandra.
O resultado dessa tarefa foi um guia para conseguirmos montar um roadmap de migração, além de influenciar na decisão da estratégia adotada.
Comparamos duas alternativas de “migradores”: dsbulk e o scylla-migrator.
- Dsbulk: aplicação CLI que faz operação de unload de dados do Cassandra em algum formato intermediário, que pode ser usado para uma operação de load posteriormente. É um processo em uma JVM — ou seja — escala apenas verticalmente.
- Scylla-migrator: job de Spark criado e mantido pela Scylla com diversas configurações de performance/paralelismo para copiar dados de forma massiva. Como qualquer job Spark pode ser configurado com um número virtualmente infinito de nós. Implementa mecanismo de savepoints, permitindo reinício do processo a partir do último lote copiado com sucesso em caso de falhas.
A alternativa de copiar os arquivos de dados do Cassandra para o Scylla foi descartada após recomendação dos nossos contatos no Scylla Cloud. É importante fazer com que o Scylla reorganize os dados em disco pois seu sistema de particionamento é diferente (feito por CPU, não por nó).
Em testes preliminares, já usando o Cassandra e Scylla de produção, conseguimos cerca de 03 a 04 Gbytes de dados migrados por hora para o dsbulk, e cerca de 30 Gbytes por hora para o scylla-migrator. Obviamente esses resultados são afetado por inúmeros fatores, mas nos deram uma ideia dos usos potenciais de cada ferramenta.
Para tentar aferir o tempo máximo de migração, rodamos o scylla-migrator sobre nossa maior tabela (840G) e conseguimos cerca de 10 GBytes por hora, ou cerca de 8 dias de migração em regime 24/7.
Com todos estes resultados em mãos, decidimos encarar a migração. A próxima pergunta é “como?”. Na próxima parte desta série, vamos tomar a decisão mais difícil em migrações deste tipo: controle/previsão de downtime.
Até breve!