Eficiência em escala: uma história de otimização de custos da AWS
Publicados: 2022-07-22Recentemente, lancei uma plataforma de análise de criptomoedas, esperando um pequeno número de usuários diários. No entanto, quando alguns YouTubers populares acharam o site útil e publicaram uma avaliação, o tráfego cresceu tão rapidamente que sobrecarregou o servidor e a plataforma (Scalper.AI) ficou inacessível. Meu ambiente AWS EC2 original precisava de suporte extra. Depois de considerar várias soluções, decidi usar o AWS Elastic Beanstalk para dimensionar meu aplicativo. As coisas pareciam boas e funcionando sem problemas, mas fiquei surpreso com os custos no painel de cobrança.
Este não é um problema incomum. Uma pesquisa de 2021 descobriu que 82% dos tomadores de decisão de TI e nuvem encontraram custos desnecessários na nuvem e 86% não sentem que podem obter uma visão abrangente de todos os seus gastos com nuvem. Embora a Amazon ofereça uma visão detalhada das despesas adicionais em sua documentação, o modelo de preços é complexo para um projeto em crescimento. Para facilitar o entendimento, detalharei algumas otimizações relevantes para reduzir seus custos de nuvem.
Por que escolhi a AWS
O objetivo do Scalper.AI é coletar informações sobre pares de criptomoedas (os ativos trocados ao negociar em uma bolsa), executar análises estatísticas e fornecer aos comerciantes de criptomoedas informações sobre o estado do mercado. A estrutura técnica da plataforma consiste em três partes:
- Scripts de ingestão de dados
- Um servidor web
- Um banco de dados
Os scripts de ingestão coletam dados de diferentes fontes e os carregam no banco de dados. Eu tinha experiência em trabalhar com serviços da AWS, então decidi implantar esses scripts configurando instâncias do EC2. O EC2 oferece muitos tipos de instância e permite que você escolha o processador, o armazenamento, a rede e o sistema operacional de uma instância.
Escolhi o Elastic Beanstalk para a funcionalidade restante porque prometia um gerenciamento de aplicativos suave. O balanceador de carga distribuiu adequadamente a carga entre as instâncias do meu servidor, enquanto o recurso de escalonamento automático tratou da adição de novas instâncias para uma carga maior. A implantação de atualizações ficou muito fácil, levando apenas alguns minutos.
O Scalper.AI funcionou de forma estável e meus usuários não enfrentaram mais tempo de inatividade. Claro, eu esperava um aumento nos gastos desde que adicionei serviços extras, mas os números foram muito maiores do que eu havia previsto.
Como eu poderia ter reduzido os custos da nuvem
Olhando para trás, havia muitas áreas de complexidade no uso dos serviços da AWS pelo meu projeto. Examinaremos as otimizações de orçamento que descobri ao trabalhar com recursos comuns do AWS EC2: instâncias de desempenho com capacidade de intermitência, transferências de dados de saída, endereços IP elásticos e estados de encerramento e interrupção.
Instâncias de desempenho com capacidade de intermitência
Meu primeiro desafio foi suportar o consumo de energia da CPU para meu projeto em crescimento. Os scripts de ingestão de dados do Scalper.AI fornecem aos usuários análise de informações em tempo real; os scripts são executados a cada poucos segundos e alimentam a plataforma com as atualizações mais recentes das trocas de criptomoedas. Cada iteração desse processo gera centenas de trabalhos assíncronos, portanto, o aumento do tráfego do site exigiu mais poder da CPU para diminuir o tempo de processamento.
A instância mais barata oferecida pela AWS com quatro vCPUs, a1.xlarge, teria me custado ~$75 por mês na época. Em vez disso, decidi distribuir a carga entre duas instâncias t3.micro com duas vCPUs e 1 GB de RAM cada. As instâncias t3.micro ofereciam velocidade e memória suficientes para o trabalho que eu precisava por um quinto do custo da a1.xlarge. No entanto, minha conta ainda era maior do que eu esperava no final do mês.
Em um esforço para entender o motivo, pesquisei a documentação da Amazon e encontrei a resposta: quando o uso de CPU de uma instância fica abaixo de uma linha de base definida, ela coleta créditos, mas quando a instância estoura acima do uso da linha de base, ela consome os créditos ganhos anteriormente. Se não houver créditos disponíveis, a instância gastará “créditos excedentes” fornecidos pela Amazon. Essa capacidade de ganhar e gastar créditos faz com que o Amazon EC2 faça uma média de uso de CPU de uma instância em 24 horas. Se o uso médio for acima da linha de base, a instância será cobrada extra a uma taxa fixa por vCPU-hora.
Monitorei as instâncias de ingestão de dados por vários dias e descobri que minha configuração de CPU, destinada a reduzir custos, fazia o oposto. Na maioria das vezes, meu uso médio de CPU foi maior que a linha de base.
Inicialmente, analisei o uso da CPU para alguns pares de criptografia; a carga era pequena, então achei que tinha muito espaço para crescer. (Eu usei apenas uma micro-instância para ingestão de dados, pois menos pares de criptografia não exigia tanto poder de CPU.) No entanto, percebi as limitações da minha análise original quando decidi tornar meus insights mais abrangentes e oferecer suporte à ingestão de dados para centenas de pares de criptografia — a análise do serviço em nuvem não significa nada, a menos que seja realizada na escala correta.
Transferências de dados de saída
Outro resultado da expansão do meu site foi o aumento das transferências de dados do meu aplicativo devido a um pequeno bug. Com o tráfego crescendo de forma constante e sem mais tempo de inatividade, eu precisava adicionar recursos para capturar e prender a atenção dos usuários o mais rápido possível. Minha atualização mais recente foi um alerta de áudio acionado quando as condições de mercado de um par de criptomoedas correspondiam aos parâmetros predefinidos do usuário. Infelizmente, cometi um erro no código e os arquivos de áudio foram carregados no navegador do usuário centenas de vezes a cada poucos segundos.
O impacto foi enorme. Meu bug gerou downloads de áudio de meus servidores da web, causando transferências de dados de saída adicionais. Um pequeno erro no meu código resultou em uma fatura quase cinco vezes maior que as anteriores. (Esta não foi a única consequência: o bug pode causar um vazamento de memória no computador do usuário, então muitos usuários pararam de voltar.)
Os custos de transferência de dados podem representar mais de 30% dos aumentos de preços da AWS. A transferência de entrada do EC2 é gratuita, mas as taxas de transferência de saída são cobradas por GB (US$ 0,09 por GB quando criei o Scalper.AI). Como aprendi da maneira mais difícil, é importante ser cauteloso com o código que afeta os dados de saída; reduzir downloads ou carregamento de arquivos sempre que possível (ou monitorar cuidadosamente essas áreas) o protegerá de taxas mais altas. Esses centavos aumentam rapidamente, pois as cobranças pela transferência de dados do EC2 para a Internet dependem da carga de trabalho e das taxas específicas da região da AWS. Uma advertência final desconhecida para muitos novos clientes da AWS: a transferência de dados se torna mais cara entre diferentes locais. No entanto, o uso de endereços IP privados pode evitar custos extras de transferência de dados entre diferentes zonas de disponibilidade da mesma região.
Endereços IP elásticos
Mesmo ao usar endereços públicos, como endereços IP elásticos (EIPs), é possível reduzir os custos do EC2. EIPs são endereços IPv4 estáticos usados para computação em nuvem dinâmica. A parte “elástica” significa que você pode atribuir um EIP a qualquer instância do EC2 e usá-lo até optar por parar. Esses endereços permitem que você troque facilmente instâncias não íntegras por saudáveis, remapeando o endereço para uma instância diferente em sua conta. Você também pode usar EIPs para especificar um registro DNS para um domínio para que ele aponte para uma instância do EC2.
A AWS fornece apenas cinco EIPs por conta por região, tornando-os um recurso limitado e caro com uso ineficiente. A AWS cobra uma taxa horária baixa para cada EIP adicional e cobra extra se você remapear um EIP mais de 100 vezes em um mês; ficar abaixo desses limites reduzirá os custos.
Terminar e Parar Estados
A AWS oferece duas opções para gerenciar o estado de instâncias do EC2 em execução: encerrar ou parar. O encerramento encerrará a instância e a máquina virtual provisionada para ela não estará mais disponível. Todos os volumes do Elastic Block Store (EBS) anexados serão desanexados e excluídos, e todos os dados armazenados localmente na instância serão perdidos. Você não será mais cobrado pela instância.
Parar uma instância é semelhante, com uma pequena diferença. Os volumes EBS anexados não são excluídos, portanto, seus dados são preservados e você pode reiniciar a instância a qualquer momento. Em ambos os casos, a Amazon não cobra mais pelo uso da instância, mas se você optar por interromper em vez de encerrar, os volumes do EBS gerarão um custo enquanto existirem. A AWS recomenda interromper uma instância somente se você espera reativá-la em breve.
Mas há um recurso que pode aumentar sua fatura da AWS no final do mês, mesmo que você tenha encerrado uma instância em vez de interrompê-la: snapshots do EBS. Esses são backups incrementais de seus volumes do EBS armazenados no Simple Storage Service (S3) da Amazon. Cada instantâneo contém as informações necessárias para criar um novo volume do EBS com seus dados anteriores. Se você encerrar uma instância, seus volumes EBS associados serão excluídos automaticamente, mas seus snapshots permanecerão. Como o S3 cobra pelo volume de dados armazenados, recomendo que você exclua esses instantâneos se não for usá-los em breve. A AWS apresenta a capacidade de monitorar a atividade de armazenamento por volume usando o serviço CloudWatch:
- Enquanto estiver conectado ao Console AWS, no menu Serviços no canto superior esquerdo, localize e abra o serviço CloudWatch.
- No lado esquerdo da página, no menu recolhível Métricas , clique em Todas as métricas .
- A página mostra uma lista de serviços com métricas disponíveis, incluindo EBS, EC2, S3 e muito mais. Clique em EBS e depois em Métricas por volume . (Observação: a opção EBS ficará visível apenas se você tiver volumes EBS configurados em sua conta.)
- Clique na guia Consulta . Na visualização Editor , copie e cole o comando
SELECT AVG(VolumeReadBytes) FROM "AWS/EBS" GROUP BY VolumeId
e clique em Executar . (Observação: o CloudWatch usa um dialeto do SQL com uma sintaxe exclusiva.)
O CloudWatch oferece vários formatos de visualização para analisar a atividade de armazenamento, como gráficos de pizza, linhas, barras, gráficos de área empilhada e números. Usar o CloudWatch para identificar volumes e snapshots inativos do EBS é uma etapa fácil para otimizar os custos da nuvem.
Dinheiro extra no seu bolso
Embora as ferramentas da AWS, como o CloudWatch, ofereçam soluções decentes para monitoramento de custos na nuvem, várias plataformas externas se integram à AWS para uma análise mais abrangente. Por exemplo, plataformas de gerenciamento de nuvem como o CloudHealth da VMWare mostram uma análise detalhada das principais áreas de gastos que podem ser usadas para análise de tendências, detecção de anomalias e monitoramento de custo e desempenho. Também recomendo que você configure um alarme de cobrança do CloudWatch para detectar quaisquer aumentos nas cobranças antes que se tornem excessivos.
A Amazon oferece muitos serviços de nuvem excelentes que podem ajudá-lo a delegar o trabalho de manutenção de servidores, bancos de dados e hardware à equipe da AWS. Embora os custos da plataforma em nuvem possam crescer facilmente devido a bugs ou erros do usuário, as ferramentas de monitoramento da AWS equipam os desenvolvedores com o conhecimento para se defenderem de despesas adicionais.
Com essas otimizações de custo em mente, você está pronto para tirar seu projeto do papel e economizar centenas de dólares no processo.