A equipe de engenharia da Teads avaliou o BigGraphite - Graphite com o backend Cassandra - como uma alternativa ao Vanilla Graphite, porém tiveram que abandoná-lo devido a problemas de desempenho. O time voltou para uma arquitetura personalizada com o WhisperDB padrão, mas usando o go-graphite, uma implementação de Go dos componentes do Graphite. Usando os balanceadores de carga da AWS, as ferramentas personalizadas e os nós espalhados pelas zonas de disponibilidade (availability zones, AZs), conseguiram obter uma configuração altamente disponível. O InfoQ entrou em contato com Vincent Miszczak, engenheiro de infraestrutura cloud da Teads.tv, para saber mais sobre a migração e os desafios.
O primeiro servidor físico Graphite da Teads foi um único ponto de falha e atingiu os limites de hardware à medida que o número de métricas aumentaram. A equipe até havia considerado opções como clusters de Graphite, Prometheus e BigGraphite, porém, escalar o Graphite usando seu armazenamento Whisper padrão é algo complexo. A equipe não escolheu o Prometheus para evitar a quebra de compatibilidade com os clientes já existentes, pois os formatos de ingestão de métricas são diferentes. O BigGraphite é um projeto de código aberto da Criteo, que substitui o Whisper por Cassandra como backend para armazenar as métricas. A Teads já executava clusters Cassandra e estava familiarizada com os aspectos operacionais, no entanto, enfrentaram problemas de desempenho na indexação, e "não foram capazes de dimensionar a carga de trabalho de indexação corretamente e a carga de trabalho dos dados custaria muitos recursos de computação", por isso, abandonaram o BigGraphite.
Voltando ao Whisper, a equipe projetou uma arquitetura de nó de retransmissão, com um AWS Network Load Balancer para inserções e Application Load Balancer para leituras. Os nós usaram armazenamento efêmero, pois o EBS não era suficiente. A outra decisão importante que tomaram foi adotar a stack do go-graphite, uma implementação Go do Graphite, para contornar os problemas padrão de gerenciamento e desempenho de processos do Graphite baseado em Python. A Booking.com havia originalmente aberto algumas partes do go-graphite.
Miszczak observa que a solução atual, bem como a BigGraphite, são possivelmente menos eficientes do que algumas outras disponíveis atualmente, como o ClickHouse e MetricTank:
Temos três questões principais quando falamos de ambas soluções. Elas escrevem pontos individualmente, significando que o desempenho de armazenamento necessário é muito alto. Para o Whisper, um ponto significa pelo menos um pedido de I/O (entrada/saída), para o BG/Cassandra, uma linha por ponto, mesmo que usemos lotes. A solução é usar pacotes compactados/codificados em pedaços (conhecidos como chunks). A segunda é que não se fragmentam com o tempo. Se consultarmos as métricas que tenham um determinado padrão, isso não restringirá a pesquisa ao intervalo de tempo que estamos usando. A fragmentação pelo tempo resolve isso. A terceira questão é que não compactam/codificam.
Miszczak diz que a "stack do Graphite está espalhada por três AZs e todas ficam ativas o tempo todo. As gravações estão espalhadas por dois (AZs) e as leituras são despachadas para todos os servidores". A equipe implementou um algoritmo de replicação para garantir que cada ponto de dados seja replicado nos AZs. No entanto, falhas no nó e paradas de manutenção ainda podem levar à perda de dados. A equipe escreveu wrappers de scripts de shell em torno de uma ferramenta chamada Carbonatet para mitigar este problema. Miszczak explica como lidam com falhas de nó:
Toleramos apenas uma falha de nó único. Quando isso acontece, lidamos com isso manualmente usando o Terraform, mas precisamos iniciá-lo manualmente. Substituímos o nó por um novo na mesma posição na lista de servidores. Quando inicializado, o novo nó realiza gravações recebidas, então iniciamos um script (usando Carbonate) para coletar os dados que devem ser criados neste local. Como lembrete, os dados destinados a um nó são replicados para o próximo. Devido a essa lógica de replicação, as informações que o novo nó deve conter é a combinação dos dados vizinhos anteriores que pertencem a esse nó e dos dados dos próximos vizinhos que não pertencem a esse nó (são os dados de replicação do nó anterior iguais ao nó que estamos substituindo).
Os sistemas de backend stateful - Cassandra, Kafka e Graphite - na Teads são monitorados com o Datadog. O CloudWatch monitora os componentes cloud, como balanceadores de carga e RDS. As métricas do Graphite são usadas para todos os sistemas stateless, como serviços da Web, e o monitoramento de negócios. Miszczak acrescenta que a equipe alerta sobre o Graphite para algumas métricas de negócios, mas decidiram não promovê-lo de forma a suportá-lo completamente, pois já usam outros dois serviços.