Otimização da capacidade e da disponibilidade do Amazon ECS
A disponibilidade da aplicação é crucial para fornecer uma experiência sem erros e minimizar a latência da aplicação. A disponibilidade depende de recursos disponíveis com capacidade suficiente para atender à demanda. A AWS fornece diversos mecanismos para gerenciar a disponibilidade. Para aplicações hospedadas no Amazon ECS, isso inclui o ajuste de escala automático e zonas de disponibilidade (AZs). O ajuste de escala automático gerencia o número de tarefas ou de instâncias com base nas métricas que você define, enquanto as zonas de disponibilidade permitem a hospedagem da aplicação em locais isolados, mas geograficamente próximos.
Assim como acontece com os tamanhos das tarefas, a capacidade e a disponibilidade apresentam determinadas compensações que você devem ser consideradas. Idealmente, a capacidade estaria perfeitamente alinhada com a demanda. Sempre haveria capacidade suficiente para atender a solicitações e processar trabalhos com a finalidade de cumprir os Objetivos de Nível de Serviço (SLOs), incluindo a baixa latência e a taxa de erro. A capacidade nunca seria excessivamente alta, resultando em custos desnecessários, nem demasiadamente baixa, causando altas latências e taxas de erro.
O ajuste de escala automático é um processo latente. Primeiro, as métricas em tempo real devem ser fornecidas ao CloudWatch. Em seguida, elas precisam ser agregadas para análise, o que pode demorar alguns minutos, dependendo da granularidade da métrica. O CloudWatch compara as métricas com os limites de alarme para identificar uma escassez ou um excesso de recursos. Para evitar instabilidade, configure os alarmes para exigir que o limite definido seja ultrapassado por alguns minutos antes de o alarme disparar. Além disso, demora algum tempo para efetuar o provisionamento do novas tarefas e encerrar as tarefas que não são mais necessárias.
Devido a esses possíveis atrasos no sistema descrito, é importante que você mantenha alguma reserva de capacidade através do provisionamento excessivo. Essa ação pode ajudar a satisfazer picos temporários de demanda. Além disso, essa ação ajuda a aplicação a atender solicitações adicionais sem atingir a saturação. Como uma boa prática, é possível definir a meta de ajuste de escala entre 60% e 80% de utilização. Isso auxilia a aplicação a lidar melhor com os picos de demanda extra enquanto a capacidade adicional ainda está em processo de provisionamento.
Outro motivo pelo qual recomendamos o provisionamento excessivo é para poder responder com rapidez às falhas de zona de disponibilidade. Recomendamos que as workloads de produção sejam atendidas por diversas zonas de disponibilidade. Isso ocorre porque, se ocorrer uma falha na zona de disponibilidade, as tarefas que estão em execução nas zonas de disponibilidade restantes ainda poderão atender à demanda. Se a sua aplicação for executada em duas zonas de disponibilidade, você precisará dobrar a contagem normal de tarefas. Isso ocorre para que você possa fornecer capacidade imediata durante qualquer falha potencial. Se a sua aplicação for executada em três zonas de disponibilidade, recomendamos executar 1,5 vezes a contagem normal de tarefas. Em outras palavras, execute três tarefas para cada duas necessárias durante o serviço normal.
Maximização da velocidade de ajuste de escala
O ajuste de escala automático é um processo reativo que demora algum tempo para entrar em vigor. No entanto, existem algumas maneiras de ajudar a minimizar o tempo necessário para aumentar a escala horizontalmente.
Minimize o tamanho da imagem. As imagens em tamanhos maiores demoram mais para serem baixadas de um repositório de imagens e descompactadas. Portanto, manter tamanhos de imagem menores reduz o tempo que é necessário para iniciar um contêiner. Para reduzir o tamanho de uma imagem, é possível seguir estas recomendações específicas:
-
Se for possível criar um binário estático ou usar a linguagem de programação Go, compile a imagem
FROM
zero e inclua somente a aplicação com o binário na imagem resultante. -
Use imagens base minimizadas de fornecedores de distribuição primários, como o Amazon Linux ou o Ubuntu.
-
Não inclua nenhum artefato de compilação na imagem final. O uso de compilações em vários estágios pode ajudar nisso.
-
Realize a compactação de estágios
RUN
sempre que possível. Cada estágioRUN
cria uma nova camada de imagem, resultando em uma ida e volta adicional para efetuar o download da camada. Um único estágioRUN
com diversos comandos unidos por&&
tem menos camadas do que um com vários estágiosRUN
. -
Se desejar incluir dados, como dados de inferência de ML, na imagem final, inclua somente os dados necessários para iniciar e começar a atender o tráfego. Se você precisar acessar dados sob demanda do Amazon S3 ou de outro armazenamento sem impactar o serviço, armazene esses dados localmente.
Mantenha as imagens por perto. Quanto maior a latência da rede, mais tempo demora para efetuar o download da imagem. Hospede as imagens em um repositório na mesma região da em que a workload está hospedada. O Amazon ECR é um repositório de imagens de alta performance disponível em todas as regiões em que o Amazon ECS está disponível. Evite navegar pela Internet ou por um link de VPN para efetuar o download de imagens de contêiner. A hospedagem de imagens na mesma região contribui para uma maior confiabilidade geral. Fazer isso mitiga o risco de problemas de conectividade de rede e de disponibilidade que poderiam ser causados por uma região diferente. Como alternativa, também é possível implementar a replicação entre regiões do Amazon ECR para ajudar nisso.
Reduza os limites de verificação de integridade do balanceador de carga. Os balanceadores de carga executam verificações de integridade antes de enviar tráfego para a aplicação. A configuração padrão da verificação de integridade para um grupo de destino pode demorar 90 segundos ou mais. Durante esse momento, o balanceador de carga verifica o status de integridade e recebe solicitações. A redução de tempo entre o intervalo de verificação de integridade e a contagem de limites pode fazer com que a aplicação aceite o tráfego com maior rapidez e reduza a carga em outras tarefas.
Considere o desempenho da inicialização a frio. Algumas aplicações usam runtimes, como Java, para realizar a compilação Just-In-Time (JIT). O processo de compilação, pelo menos na inicialização, pode mostrar o desempenho da aplicação. Uma solução alternativa é reescrever as partes críticas em termos de latência da workload em linguagens que não impõem uma penalidade de desempenho durante a inicialização a frio.
Use o ajuste de escala em etapas em vez de políticas de ajuste de escala com rastreamento de destino. Há várias opções de ajuste de escala automático de aplicações para tarefas. O rastreamento de destinos é o modo mais fácil de usar. Com isso, tudo o que você precisa fazer é definir um valor de destino para uma métrica, como a utilização média da CPU. Em seguida, o escalador automático gerencia automaticamente o número de tarefas necessárias para atingir esse valor. Com a escalabilidade por etapas, é possível reagir mais rapidamente às mudanças na demanda, pois define os limites específicos para suas métricas de escalabilidade e quantas tarefas adicionar ou remover quando os limites são ultrapassados. E, o mais importante, é possível reagir rapidamente às mudanças na demanda minimizando a quantidade de tempo em que um alarme de limite é violado. Para obter mais informações, consulte Ajuste de escala automático de serviços.
Se você usa instâncias do Amazon EC2 para fornecer capacidade de cluster, considere as seguintes recomendações:
Use instâncias maiores do Amazon EC2 e volumes mais rápidos do Amazon EBS. É possível aumentar as velocidades de download e de preparação de imagens ao usar uma instância maior do Amazon EC2 e um volume mais rápido do Amazon EBS. Em uma determinada família de instância, o throughput máximo da rede e do Amazon EBS aumenta à medida que o tamanho da instância aumenta (por exemplo, de m5.xlarge
para m5.2xlarge
). Além disso, também é possível personalizar os volumes do Amazon EBS para aumentar o throughput e as IOPS. Por exemplo, se você usa volumes gp2
, opte por usar volumes maiores que ofereçam mais throughput de linha de base. Se você usa volumes gp3
, especifique o throughput e as IOPS ao criar o volume.
Use o modo de rede bridge para tarefas em execução nas instâncias do Amazon EC2. As tarefas que usam o modo de rede bridge
no Amazon EC2 são iniciadas com maior rapidez do que as tarefas que usam o modo de rede awsvpc
. Quando o modo de rede awsvpc
é usado, o Amazon ECS anexa uma interface de rede elástica (ENI) à instância antes de iniciar a tarefa. Isso introduz latência adicional. Existem várias vantagens e desvantagens no uso de redes bridge. Essas tarefas não recebem o próprio grupo de segurança e há algumas implicações para o balanceamento de carga. Para obter mais informações, consulte Load balancer target groups no Guia do usuário do Elastic Load Balancing.
Como lidar com choques de demanda
Algumas aplicações sofrem grandes choques repentinos na demanda. Isso acontece por diversos motivos, por exemplo, um evento de notícias, uma grande liquidação, um evento de mídia ou algum outro evento que se torna viral e faz com que o tráfego aumente rápida e significativamente em um espaço de tempo demasiadamente curto. Se não houver planejamento, isso pode fazer com que a demanda ultrapasse os recursos disponíveis com rapidez.
A melhor forma de lidar com choques de demanda é antecipá-los e planejar adequadamente. Como o ajuste de escala automático pode demorar algum tempo, recomendamos aumentar a escala horizontalmente da aplicação antes que o choque de demanda comece. Para obter os melhores resultados, recomendamos ter um plano de negócios que envolva uma estreita colaboração entre as equipes que usam um calendário compartilhado. A equipe que está planejando um evento deve colaborar estreitamente com a equipe responsável pela inscrição desde o início. Isso fornece à equipe tempo suficiente para ter um plano de programação claro. As pessoas da equipe podem programar a capacidade para aumentar a escala horizontalmente antes do evento e para reduzir a escala horizontalmente após o evento. Para obter mais informações, consulte Escalabilidade programada no Guia do usuário do Application Auto Scaling.
Se você tiver um plano do Enterprise Support, certifique-se de também colaborar com seu gerente técnico de contas (TAM). O TAM pode verificar suas cotas de serviço e garantir que todas as cotas necessárias sejam aumentadas antes do início do evento. Dessa forma, você evita acidentalmente atingir qualquer cota de serviço. Eles também podem ajudar você através da preparação de serviços, como balanceadores de carga, para garantir que seu evento ocorra sem complicações.
Lidar com choques de demanda não programados é um problema mais complexo. Os choques não programados, se forem suficientemente grandes em amplitude, podem rapidamente fazer com que a demanda ultrapasse a capacidade. Além disso, isso pode superar a capacidade de reação do ajuste de escala automático. A melhor forma de se preparar para choques não programados é provisionar recursos em excesso. Você deve ter recursos suficientes para lidar com a demanda máxima de tráfego prevista a qualquer momento.
Manter a capacidade máxima em antecipação a choques não programados na demanda pode ser dispendioso. Para mitigar o impacto nos custos, encontre uma métrica ou um evento de indicador antecedente que preveja que um grande choque de demanda é iminente. Se a métrica ou o evento fornecer um aviso prévio significativo de forma confiável, inicie o processo de aumentar a escala horizontalmente imediatamente quando o evento ocorrer ou quando a métrica ultrapassar o limite específico definido.
Se a aplicação estiver propensa a choques repentinos e não programados na demanda, considere adicionar um modo de alta performance à aplicação que sacrifique funcionalidades que não são essenciais, mas retenha funcionalidades cruciais para um cliente. Por exemplo, suponha que a aplicação possa deixar de gerar respostas personalizadas dispendiosas e passar a disponibilizar uma página de resposta estática. Nesse cenário, é possível aumentar significativamente o throughput sem a necessidade de escalar a aplicação.
Considere separar os serviços monolíticos para lidar melhor com os impactos de demanda. Se a aplicação for um serviço monolítico que é dispendioso para executar e demorado para escalar, você poderá extrair ou reescrever partes críticas de desempenho e executá-las como serviços separados. Estes novos serviços podem ser escalados independentemente de componentes menos críticos. Ter a flexibilidade de aumentar a escala horizontalmente da funcionalidade crítica para o desempenho separadamente de outras partes da aplicação pode reduzir o tempo necessário para adicionar capacidade e ajudar a economizar custos.