

# Práticas recomendadas de gerenciamento de capacidade e ajuste de escala automático do Amazon ECS
<a name="capacity-availability"></a>

Você pode executar workloads de aplicações em contêineres de todos os tamanhos no Amazon ECS. Isso inclui ambientes de teste mínimos e grandes ambientes de produção que operam em escala global.

Com o Amazon ECS, como em todos os serviços da AWS, você paga somente pelo que usar. Ao arquitetar sua aplicação adequadamente, você pode reduzir os custos consumindo somente os recursos necessários, quando precisar deles.

As recomendações a seguir mostram como executar suas workloads do Amazon ECS para alcançar suas metas de nível de serviço e, ao mesmo tempo, operar de forma econômica.

**Topics**
+ [Determinação do tamanho de tarefas do Amazon ECS](capacity-tasksize-best-practice.md)
+ [Otimização do ajuste de escala automático de serviços do Amazon ECS](capacity-autoscaling-best-practice.md)
+ [Capacidade e disponibilidade do Amazon ECS](capacity-availability-best-practice.md)
+ [Capacidade de clusters do Amazon ECS](capacity-cluster-best-practice.md)
+ [Escolha de tamanhos de tarefas do Fargate para o Amazon ECS](fargate-task-size-best-practice.md)
+ [Aceleração do provisionamento de capacidade de clusters do Amazon ECS com provedores de capacidade no Amazon EC2](capacity-cluster-speed-up-ec2-best-practice.md)

# Determinação do tamanho de tarefas do Amazon ECS
<a name="capacity-tasksize-best-practice"></a>

Uma das escolhas mais importantes a serem feitas ao implantar contêineres no Amazon ECS é sobre o tamanho deles e das tarefas. Os tamanhos de contêineres e tarefas são essenciais para o planejamento de escalabilidade e capacidade.

O Amazon ECS usa duas métricas de recursos para a capacidade: CPU e memória. O Amazon ECS mede a CPU em unidades de 1/1024 de uma vCPU completa (em que 1.024 unidades são iguais a 1 vCPU inteira). O Amazon ECS mede a memória em megabytes.

Na definição da tarefa, você pode declarar reservas e limites de recursos.

Ao declarar uma reserva, você declara a quantidade mínima de recursos que uma tarefa exige. Sua tarefa recebe, pelo menos, a quantidade de recursos solicitada. A aplicação pode conseguir usar mais CPU ou memória do que a reserva declarada. No entanto, isso está sujeito a quaisquer limites que também tenham sido declarados.

Usar mais do que a quantidade da reserva é conhecido como intermitência. A expansão significa que sua aplicação usa mais recursos do que o reservado, mas permanece dentro dos limites declarados. O Amazon ECS garante as reservas. Por exemplo, se você usar instâncias do Amazon EC2 para fornecer capacidade, o Amazon ECS não colocará uma tarefa em uma instância em que a reserva não possa ser atendida.

Um limite é a quantidade máxima de unidades de CPU ou memória que o contêiner ou a tarefa pode usar. Se seu contêiner tentar usar mais CPU do que esse limite, o Amazon ECS controlará a utilização. Se seu contêiner tentar usar mais memória do que esse limite, o Amazon ECS interromperá seu contêiner.

Escolher esses valores pode ser um desafio. Os valores mais adequados para a aplicação dependem muito dos requisitos de recursos dela.

Testar a carga da aplicação é a chave para um planejamento bem-sucedido dos requisitos de recursos. O teste de carga ajuda você a entender melhor os requisitos da sua aplicação.

## Aplicações sem estado
<a name="capacity-tasksize-stateless"></a>

Em aplicações sem estado que escalam horizontalmente, como uma aplicação por trás de um balanceador de carga, recomendamos primeiro determinar a quantidade de memória que a aplicação consome ao atender às solicitações.

Para fazer isso, você pode usar ferramentas tradicionais, como `ps` ou `top`. Também é possível utilizar soluções de monitoramento, como o CloudWatch Container Insights.

Ao determinar uma reserva de CPU, considere como você deseja escalar a aplicação para atender às suas necessidades de negócios.

Você pode usar reservas de CPU menores, como 256 unidades de CPU (ou 1/4 de vCPU), para aumentar a escala horizontalmente de uma forma refinada que minimize os custos. Porém, elas podem não ser escaladas com rapidez suficiente para atender a picos significativos na demanda.

Você pode usar reservas maiores de CPU para aumentar e reduzir a escala horizontalmente com mais rapidez. Isso ajuda você a acompanhar os picos de demanda mais rapidamente. No entanto, reservas maiores de CPU são mais caras.

## Outros aplicativos
<a name="capacity-tasksize-other"></a>

Em aplicações que não são escaláveis horizontalmente, como operadores singleton ou servidores de banco de dados, a capacidade disponível e o custo representam suas considerações mais importantes.

Você deve escolher a quantidade de memória e CPU com base na necessidade indicada pelo teste de carga para atender ao seu objetivo no nível de serviço. O Amazon ECS garante que a aplicação seja colocada em um host com capacidade adequada.

# Otimização do ajuste de escala automático de serviços do Amazon ECS
<a name="capacity-autoscaling-best-practice"></a>

Um serviço do Amazon ECS é uma coleção gerenciada de tarefas. Cada serviço tem uma definição de tarefa associada, uma contagem de tarefas desejada e uma estratégia de posicionamento opcional.

O ajuste de escala automático de serviços do Amazon ECS funciona por meio do serviço Application Auto Scaling. O Application Auto Scaling usa métricas do CloudWatch como fonte para métricas de escalabilidade. Ele também usa os alarmes do CloudWatch para definir limites sobre quando aumentar ou reduzir horizontalmente a escala do serviço.

Você fornece os limites para escalabilidade. Você pode definir uma meta de métrica, chamada de *escala de rastreamento de metas*. Você também pode especificar limites, o que é chamado de *escalabilidade de etapas*.

Depois que o Application Auto Scaling é configurado, ele calcula continuamente a contagem adequada de tarefas desejadas para o serviço. Ele também notifica o Amazon ECS quando a contagem de tarefas desejada deve mudar, seja aumentando ou reduzindo a escala horizontalmente.

Para usar o ajuste de escala automático do serviço de forma eficaz, você deve escolher uma métrica de escalabilidade apropriada. Vamos abordar como escolher uma métrica nas seções a seguir.

## Caracterização da aplicação
<a name="capacity-autoscaling-app"></a>

A escalabilidade adequada de uma aplicação exige que você conheça as condições em que você deve reduzir e aumentar a escala horizontalmente dela.

Em essência, você deverá aumentar a escala horizontalmente se houver previsão de que a demanda vá ultrapassar a capacidade. Por outro lado, você poderá reduzir a escala horizontalmente da aplicação para conservar os custos quando os recursos excederem a demanda.

### Identificação de uma métrica de utilização
<a name="capacity-autoscaling-app-utilizationmetric"></a>

Para escalar com eficácia, você deve identificar uma métrica que indique a utilização ou saturação. Essa métrica deve exibir as propriedades a seguir para ser útil ao escalar.
+ A métrica deve estar correlacionada com a demanda. Quando os recursos são mantidos estáveis, mas a demanda muda, o valor da métrica também deve mudar. A métrica deve aumentar ou diminuir quando a demanda aumenta ou diminui.
+ O valor da métrica deve reduzir a escala horizontalmente de modo proporcional à capacidade. Quando a demanda se mantém constante, a adição de mais recursos deve resultar em uma mudança proporcional no valor da métrica. Portanto, dobrar o número de tarefas deve fazer com que a métrica diminua em 50%.

A melhor maneira de identificar uma métrica de utilização é por meio de testes de carga em um ambiente de pré-produção, como um ambiente de teste. Soluções de teste de carga comerciais e de código aberto estão amplamente disponíveis. Normalmente, essas soluções podem gerar carga sintética ou simular tráfego real de usuários.

Para iniciar o processo de teste de carga, você deve primeiro criar painéis para as métricas de utilização da aplicação. Essas métricas incluem utilização da CPU, utilização da memória, operações de E/S, profundidade da fila de E/S e throughput da rede. Você pode coletar essas métricas com um serviço, como o CloudWatch Container Insights. Também é possível coletá-las usando o Amazon Managed Service for Prometheus junto com o Amazon Managed Grafana. Durante esse processo, certifique-se de coletar e traçar métricas para os tempos de resposta da aplicação ou para as taxas de conclusão do trabalho.

Ao testar a carga, comece com uma pequena taxa de solicitação ou inserção de trabalho. Mantenha essa taxa estável por alguns minutos para permitir o aquecimento da aplicação. Em seguida, aumente lentamente a taxa e mantenha-a estável por alguns minutos. Repita esse ciclo, aumentando a taxa a cada vez, até que os tempos de resposta ou conclusão da aplicação estejam muito lentos para atender aos objetivos de nível de serviço (SLOs).

Durante o teste de carga, examine cada uma das métricas de utilização. As métricas que aumentam com a carga são as principais candidatas a melhores métricas de utilização.

Em seguida, identifique o recurso que atinge a saturação. Ao mesmo tempo, também examine as métricas de utilização para ver qual delas se estabiliza primeiro em um nível alto. Ou examine qual delas atinge o pico e, em seguida, trava sua aplicação primeiro. Por exemplo, se a utilização da CPU aumentar de 0% para 70% a 80% à medida que você adiciona carga, e permanecer nesse nível após adicionar ainda mais carga, é seguro dizer que a CPU está saturada. Dependendo da arquitetura da CPU, talvez nunca chegue a 100%. Por exemplo, suponha que a utilização da memória aumente à medida que você adiciona carga e, em seguida, a aplicação trava repentinamente ao atingir o limite de memória da tarefa ou da instância do Amazon EC2. Nessa situação, é provável que a memória tenha sido totalmente consumida. Vários recursos podem ser consumidos pela aplicação. Portanto, escolha a métrica que representa o recurso que se esgota primeiro.

Por fim, tente testar a carga novamente depois de dobrar o número de tarefas ou de instâncias do Amazon EC2. Suponha que a métrica principal aumente ou diminua pela metade da taxa de antes. Se for esse o caso, a métrica é proporcional à capacidade. Essa é uma boa métrica de utilização para ajuste de escala automático.

Agora, considere esse cenário hipotético. Suponha que você teste a carga de uma aplicação e descubra que a utilização da CPU chega a 80% com 100 solicitações por segundo. Quando mais carga é adicionada, a utilização da CPU não aumenta mais. No entanto, isso faz com que a aplicação responda mais lentamente. Em seguida, você executa o teste de carga novamente, dobrando o número de tarefas, mas mantendo a taxa no valor de pico anterior. Se você descobrir que a utilização média da CPU cai para cerca de 40%, a utilização média da CPU é uma boa candidata para uma métrica de escalabilidade. Por outro lado, se a utilização da CPU permanecer em 80% após aumentar o número de tarefas, a utilização média da CPU não é uma boa métrica de escalabilidade. Nesse caso, você precisa fazer mais pesquisa para encontrar uma métrica adequada.

### Modelos de aplicações e propriedades de escala comuns
<a name="capacity-autoscaling-app-common"></a>

É possível executar softwares de todos os tipos na AWS. Muitas workloads são desenvolvidas internamente, enquanto outras são baseadas em softwares populares de código aberto. Independentemente de sua origem, observamos alguns padrões comuns de design de serviços. A forma eficaz de escalar depende, em grande parte, do padrão.

#### O servidor eficiente vinculado à CPU
<a name="capacity-autoscaling-app-common-cpu"></a>

O servidor eficiente vinculado à CPU não utiliza quase nenhum recurso além da CPU e do throughput da rede. Cada solicitação pode ser processada apenas pela aplicação. As solicitações não dependem de outros serviços, como bancos de dados. A aplicação pode processar centenas de milhares de solicitações simultâneas e utilizar com eficiência várias CPUs para isso. Cada solicitação é atendida por um thread dedicado com pouca sobrecarga de memória ou há um loop de eventos assíncrono executado em cada CPU que atende às solicitações. Cada réplica da aplicação é igualmente capaz de processar uma solicitação. O único recurso que pode ser esgotado antes da CPU é a largura de banda da rede. Em serviços vinculados à CPU, a utilização da memória, mesmo no pico de throughput, é uma fração dos recursos disponíveis.

Você pode usar o ajuste de escala automático baseado em CPU para esse tipo de aplicação. A aplicação desfruta da máxima flexibilidade em termos de escala. Ela pode ser escala verticalmente, o que fornece à aplicação instâncias maiores do Amazon EC2 ou vCPUs do Fargate. Além disso, ela também pode ser escalada horizontalmente adicionando mais réplicas. Adicionar réplicas ou dobrar o tamanho da instância reduz pela metade a utilização média da CPU em relação à capacidade.

Se estiver usando a capacidade do Amazon EC2 nessa aplicação, considere colocá-la em instâncias otimizadas para computação, como a família `c5` ou `c6g`.

#### O servidor eficiente vinculado à memória
<a name="capacity-autoscaling-app-common-memory"></a>

O servidor eficiente vinculado à memória aloca uma quantidade significativa de memória por solicitação. Na máxima simultaneidade, mas não necessariamente no throughput, a memória se esgota antes dos recursos da CPU. A memória associada a uma solicitação é liberada quando a solicitação se encerra. Solicitações adicionais podem ser aceitas desde que haja memória disponível.

Você pode usar ajuste de escala automático baseado em memória para esse tipo de aplicação. A aplicação desfruta da máxima flexibilidade em termos de escala. Você pode escalá-la verticalmente, fornecendo a ela maiores recursos de memória do Amazon EC2 ou do Fargate. Além disso, ela também pode ser escalada horizontalmente adicionando mais réplicas. Adicionar réplicas ou dobrar o tamanho da instância pode reduzir pela metade a utilização média da memória em relação à capacidade.

Se estiver usando a capacidade do Amazon EC2 nessa aplicação, considere colocá-la em instâncias otimizadas para memória, como a família `r5` ou `r6g`.

Algumas aplicações vinculadas à memória não liberam a memória associada a uma solicitação quando ela se encerra, de modo que uma redução na simultaneidade não resulta em uma redução na memória usada. Para isso, não recomendamos usar a escalabilidade baseada em memória. 

#### O servidor baseado em operadores
<a name="capacity-autoscaling-app-common-worker"></a>

O servidor baseado em operadores processa uma solicitação para cada thread de operador individual, uma após a outra. Os threads de operador podem ser leves, como os threads POSIX. Eles também podem ser mais pesados, como os processos UNIX. Não importa qual thread eles sejam, sempre há uma simultaneidade máxima que a aplicação pode suportar. Normalmente, o limite de simultaneidade é definido proporcionalmente aos recursos de memória disponíveis. Se o limite de simultaneidade for atingido, a aplicação colocará solicitações adicionais em uma fila de backlog. Se a fila de backlog transbordar, solicitações adicionais de entrada serão imediatamente rejeitadas. As aplicações comuns que se encaixam nesse padrão incluem o servidor Web Apache e o Gunicorn.

A simultaneidade de solicitações costuma ser a melhor métrica para escalar essa aplicação. Como há um limite de simultaneidade para cada réplica, é importante aumentar a escala horizontalmente antes que o limite médio seja atingido.

A melhor maneira de obter métricas de simultaneidade de solicitações é fazer com que a aplicação as relate ao CloudWatch. Cada réplica da aplicação pode publicar o número de solicitações simultâneas como uma métrica personalizada em alta frequência. Recomendamos que a frequência seja definida para, pelo menos, uma vez a cada minuto. Depois que vários relatórios são coletados, você pode usar a simultaneidade média como métrica de escalabilidade. Essa métrica é calculada pegando a simultaneidade total e dividindo-a pelo número de réplicas. Por exemplo, se a simultaneidade total for 1.000 e o número de réplicas for 10, a simultaneidade média será 100.

Se a aplicação estiver por trás de um Application Load Balancer, você também pode usar a métrica `ActiveConnectionCount` do balanceador de carga como fator na métrica de escalabilidade. A métrica `ActiveConnectionCount` deve ser dividida pelo número de réplicas para obter um valor médio. O valor médio deve ser usado para ajuste de escala, em oposição ao valor bruto da contagem.

Para que esse projeto funcione melhor, o desvio padrão da latência de resposta deve ser pequeno em taxas de solicitação baixas. Recomendamos que, durante períodos de baixa demanda, a maioria das solicitações seja respondida em pouco tempo e que não haja muitas solicitações que demorem muito mais do que o tempo médio para serem respondidas. O tempo médio de resposta deve estar próximo ao tempo de resposta do 95º percentil. Caso contrário, podem ocorrer transbordamos de fila como resultado. Isso leva a erros. Recomendamos que você forneça réplicas adicionais quando necessário para reduzir o risco de transbordamento.

#### O servidor em espera
<a name="capacity-autoscaling-app-common-waiting"></a>

O servidor em espera realiza algum processamento para cada solicitação, mas dependente muito de um ou mais serviços downstream para funcionar. As aplicações de contêiner costumam fazer uso intenso de serviços downstream, como bancos de dados e outros serviços de API. Pode levar algum tempo para que esses serviços respondam, principalmente em cenários de alta capacidade ou alta simultaneidade. Isso ocorre porque essas aplicações tendem a usar poucos recursos da CPU e a utilizar sua máxima simultaneidade em termos de memória disponível.

O serviço em espera é adequado tanto no padrão de servidor vinculado à memória quanto no padrão de servidor baseado em operadores, dependendo de como a aplicação foi projetada. Se a simultaneidade da aplicação for limitada somente pela memória, a utilização média da memória deve ser usada como métrica de escalabilidade. Se a simultaneidade da aplicação for baseada em um limite de operadores, a simultaneidade média deve ser usada como uma métrica de escalabilidade.

#### O servidor baseado em Java
<a name="capacity-autoscaling-app-common-java"></a>

Se o servidor baseado em Java estiver vinculado à CPU e escalar proporcionalmente aos recursos da CPU, ele pode ser adequado para o padrão eficiente de servidor vinculado à CPU. Se for esse o caso, a utilização média da CPU pode ser apropriada como métrica de escalabilidade. No entanto, muitas aplicações Java não são vinculadas à CPU, o que as torna difíceis de escalar.

Para obter o melhor desempenho, recomendamos alocar o máximo de memória possível no heap da Java Virtual Machine (JVM). Versões recentes da JVM, incluindo a atualização 191 ou posterior do Java 8, definem automaticamente o tamanho do heap o maior possível para caber no contêiner. Isso significa que, em Java, a utilização da memória raramente é proporcional à utilização da aplicação. À medida que a taxa de solicitações e a simultaneidade aumentam, a utilização da memória permanece constante. Por isso, não recomendamos escalar servidores baseados em Java com base na utilização da memória. Em vez disso, recomendamos escalar a utilização da CPU.

Em alguns casos, os servidores baseados em Java esgotam o heap antes de esgotar a CPU. Se a aplicação for propensa ao esgotamento de heap com alta simultaneidade, as conexões médias são a melhor métrica de escalabilidade. Se a aplicação for propensa ao esgotamento de heap com alto throughput, a taxa média de solicitações é a melhor métrica de escalabilidade.

#### Servidores que usam outros runtimes com coleta de resíduos
<a name="capacity-autoscaling-app-common-garbage"></a>

Muitas aplicações de servidor são baseadas em runtimes que realizam coleta de resíduos, como .NET e Ruby. Essas aplicações de servidor podem se encaixar em um dos padrões descritos anteriormente. No entanto, como acontece em Java, não recomendamos escalar essas aplicações com base na memória, porque a utilização média de memória observada não costuma estar correlacionada ao throughput ou à simultaneidade.

Para essas aplicações, recomendamos escalar a utilização da CPU se a aplicação estiver vinculada à CPU. Caso contrário, recomendamos escalar o throughput médio ou a simultaneidade média, com base nos resultados do teste de carga.

#### Processadores de trabalhos
<a name="capacity-autoscaling-app-common-job"></a>

Muitas workloads envolvem o processamento assíncrono de trabalhos. Elas incluem aplicações que não recebem solicitações em tempo real, mas se inscrevem em uma fila de trabalho para receber tarefas. Para esses tipos de aplicações, a métrica de escalabilidade adequada é quase sempre a profundidade da fila. O crescimento da fila é uma indicação de que o trabalho pendente supera a capacidade de processamento, enquanto uma fila vazia indica que há mais capacidade do que trabalho a ser feito.

Serviços de mensagens da AWS, como Amazon SQS e Amazon Kinesis Data Streams, fornecem métricas do CloudWatch que podem ser usadas para escalar. No Amazon SQS, `ApproximateNumberOfMessagesVisible` é a melhor métrica. No Kinesis Data Streams, considere usar a métrica `MillisBehindLatest`, publicada pela Kinesis Client Library (KCL). Essa métrica deve ser calculada em média entre todos os consumidores antes de usá-la para escalar.

# Capacidade e disponibilidade do Amazon ECS
<a name="capacity-availability-best-practice"></a>

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 acessíveis e 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 as 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, o CloudWatch deve receber métricas em tempo real. Em seguida, o CloudWatch precisa agregá-las 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, você deve configurar 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, é importante que você mantenha uma margem de segurança por meio do superprovisionamento. O superprovisionamento pode ajudar a acomodar picos de demanda de curto prazo. Além disso, essa ação ajuda a aplicação a atender a 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 que você possa responder com rapidez às falhas da zona de disponibilidade. A AWS recomenda que as workloads de produção sejam disponibilizadas de 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
<a name="capacity-availability-speed"></a>

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ágio `RUN` cria uma nova camada de imagem, resultando em uma ida e volta adicional para efetuar o download da camada. Um único estágio `RUN` com diversos comandos unidos por `&&` tem menos camadas do que um com vários estágios `RUN`.
+ 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 AWS 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. 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.** Você tem várias opções de ajuste de escala automático de aplicação para tarefas do Amazon ECS. 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 [Usar escalabilidade automática](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service-auto-scaling.html) no *Guia do desenvolvedor do Amazon Elastic Container Service*.

Se você estiver usando 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 do Amazon EC2, 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ê estiver usando volumes `gp2`, opte por usar volumes maiores que ofereçam mais throughput de linha de base. Se você estiver usando 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](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-target-groups.html) no *Guia do usuário do Elastic Load Balancing*.

## Como lidar com choques de demanda
<a name="capacity-availability-shocks"></a>

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](https://docs.aws.amazon.com/autoscaling/application/userguide/application-auto-scaling-scheduled-scaling.html) 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. Os gerentes técnicos de contas 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.

Por último, você pode considerar separar os serviços monolíticos para lidar melhor com os choques 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.

# Capacidade de clusters do Amazon ECS
<a name="capacity-cluster-best-practice"></a>

Você pode fornecer capacidade para um cluster do Amazon ECS de várias maneiras. Por exemplo, você pode inicializar instâncias do Amazon EC2 e registrá-las no cluster na inicialização usando o agente de contêineres do Amazon ECS. No entanto, esse método pode ser desafiador porque você precisa gerenciar a escalabilidade por conta própria. Dessa forma, recomendamos que você use provedores de capacidade do Amazon ECS. Os provedores de capacidade gerenciam a escalabilidade de recursos para você. Existem três tipos de provedores de capacidade: Amazon EC2, Fargate e Fargate Spot. Para obter mais informações sobre provedores de capacidade do Fargate, consulte [Clusters do Amazon ECS para workloads do Fargate](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/fargate-capacity-providers.html), e para workload do EC2, consulte [Clusters do Amazon ECS para workloads do EC2](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/asg-capacity-providers.html).

Os provedores de capacidade do Fargate e do Fargate Spot cuidam do ciclo de vida das tarefas do Fargate para você. O Fargate fornece capacidade sob demanda, e o Fargate Spot fornece capacidade spot. Quando você inicializa uma tarefa, o Amazon ECS provisiona um recurso do Fargate para você. Esse recurso do Fargate vem com as unidades de memória e CPU que correspondem diretamente aos limites do nível de tarefa que você declarou na definição da tarefa. Cada tarefa recebe seu próprio recurso do Fargate, criando uma relação 1:1 entre a tarefa e os recursos computacionais.

As tarefas executadas no Fargate Spot estão sujeitas a interrupção. As interrupções ocorrem após um aviso de dois minutos. Isso ocorre durante períodos de grande demanda. O Fargate Spot funciona melhor para workloads tolerantes a interrupções, como trabalhos em lote, ambientes de desenvolvimento ou de preparação. Elas também são adequadas para qualquer outro cenário em que a alta disponibilidade e a baixa latência não sejam um requisito.

Você pode executar tarefas do Fargate Spot junto com tarefas sob demanda do Fargate. Ao usá-los juntos, você recebe capacidade de “expansão” de provisionamento a um custo menor.

O Amazon ECS também pode gerenciar a capacidade de instâncias do Amazon EC2 para suas tarefas. Cada provedor de capacidade do Amazon EC2 é associado a um grupo do Amazon EC2 Auto Scaling especificado. Quando você usa o provedor de capacidade do Amazon EC2, o ajuste de escala automático do cluster mantém o tamanho do grupo do Amazon EC2 Auto Scaling para garantir que todas as tarefas agendadas possam ser realizadas.

# Escolha de tamanhos de tarefas do Fargate para o Amazon ECS
<a name="fargate-task-size-best-practice"></a>

Para definições de tarefas do AWS Fargate, é necessário especificar a CPU e a memória no nível da tarefa, sem considerar nenhuma sobrecarga. Você também pode especificar a CPU e a memória no nível do contêiner para tarefas do Fargate. Porém, isso não é necessário. Os limites de recursos devem ser maiores ou iguais às reservas declaradas. Na maioria dos casos, você pode defini-los como a soma das reservas de cada contêiner declarado na definição da tarefa. Em seguida, arredonde o número até o tamanho mais próximo do Fargate. Para obter mais informações sobre os tamanhos disponíveis, consulte [CPU e memória da tarefa](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/fargate-tasks-services.html#fargate-tasks-size). 

# Aceleração do provisionamento de capacidade de clusters do Amazon ECS com provedores de capacidade no Amazon EC2
<a name="capacity-cluster-speed-up-ec2-best-practice"></a>

Os clientes que executam o Amazon ECS no Amazon EC2 podem aproveitar o [Ajuste de escala automático de clusters (CAS) do Amazon ECS](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/cluster-auto-scaling.html) para gerenciar o ajuste de escala de grupos do Amazon EC2 Auto Scaling (ASG). Com o CAS, você pode configurar o Amazon ECS para escalar o ASG automaticamente e se concentrar apenas na execução das tarefas. O Amazon ECS garantirá que o ASG aumente e reduza a escala horizontalmente conforme necessário, sem necessidade de intervenção adicional. Os provedores de capacidade do Amazon ECS são usados ​​para gerenciar a infraestrutura do cluster ao garantir que haja instâncias de contêiner suficientes para atender às demandas da aplicação. Para saber como o CAS do Amazon ECS funciona, consulte [Deep Dive on Amazon ECS Cluster Auto Scaling](https://aws.amazon.com/blogs/containers/deep-dive-on-amazon-ecs-cluster-auto-scaling/).

Como o CAS depende de uma integração baseada no CloudWatch com o ASG para ajustar a capacidade de clusters, ele tem latência inerente associada à publicação das métricas do CloudWatch, ao tempo que a métrica `CapacityProviderReservation` demora para acionar os alarmes do CloudWatch (nos pontos alto e baixo) e ao tempo que uma instância do Amazon EC2 inicializada recentemente demora para aquecer. Você tomar as seguintes medidas para tornar o CAS mais responsivo para implantações mais rápidas:

## Tamanhos do ajuste de escala para as etapas do provedor de capacidade
<a name="cas-step-size"></a>

Os provedores de capacidade do Amazon ECS eventualmente aumentarão ou reduzirão as instâncias de contêiner para atender às demandas da aplicação. Por padrão, o número mínimo de instâncias que o Amazon ECS iniciará está definido como um. Isso poderá adicionar mais tempo às implantações, se forem necessárias diversas instâncias para a atribuição das tarefas pendentes. É possível aumentar [https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_ManagedScaling.html](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_ManagedScaling.html) usando a API do Amazon ECS para elevar o número mínimo de instâncias em que o Amazon ECS aumenta ou reduz a escala horizontalmente ao mesmo tempo. Um [https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_ManagedScaling.html](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_ManagedScaling.html) muito baixo pode limitar quantas instâncias de contêiner terão aumento ou redução da escala horizontalmente por vez, o que pode atrasar as implantações.

**nota**  
No momento, essa configuração está disponível somente usando a API [https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_CreateCapacityProvider.html](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_CreateCapacityProvider.html) ou [https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_UpdateCapacityProvider.html](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_UpdateCapacityProvider.html).

## Período de aquecimento da instância
<a name="instance-warmup-period"></a>

O período de aquecimento da instância corresponde ao período após o qual uma instância do Amazon EC2 iniciada recentemente pode contribuir para as métricas do CloudWatch relacionadas ao grupo do Auto Scaling. Depois que o período de aquecimento especificado expirar, a instância será contabilizada nas métricas agregadas do ASG, e o CAS continuará com sua próxima iteração de cálculos para estimar o número de instâncias necessárias.

O valor padrão para [https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_ManagedScaling.html#ECS-Type-ManagedScaling-instanceWarmupPeriod](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_ManagedScaling.html#ECS-Type-ManagedScaling-instanceWarmupPeriod) é de 300 segundos, e você pode configurar para um valor mais baixo usando as APIs [https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_CreateCapacityProvider.html](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_CreateCapacityProvider.html) ou [https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_UpdateCapacityProvider.html](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_UpdateCapacityProvider.html) para obter um ajuste de escala mais responsivo.

## Capacidade não utilizada
<a name="spare-capacity"></a>

Se o provedor de capacidade não tiver instâncias de contêiner disponíveis para a atribuição de tarefas, ele precisará aumentar (aumentar a escala horizontalmente) a capacidade do cluster ao iniciar instâncias do Amazon EC2 rapidamente e aguardar a inicialização antes de iniciar os contêineres nelas. Isso pode reduzir significativamente a taxa de inicialização de tarefas. Você tem duas opções disponíveis para lidar com isso.

 Nesse caso, ter a capacidade não utilizada do Amazon EC2 já iniciada e pronta para executar tarefas aumentará a taxa efetiva de inicialização de tarefas. É possível usar a configuração `Target Capacity` para indicar que deseja manter a capacidade não utilizada em seus clusters. Por exemplo, ao definir a `Target Capacity` como 80%, você indica que o cluster precisa de 20% de capacidade não utilizada disponível em todos os momentos. Essa capacidade não utilizada pode permitir que qualquer tarefa independente seja iniciada imediatamente, garantindo que a inicialização de tarefas não sofra o controle de utilização. A desvantagem desta abordagem é o potencial aumento dos custos de manutenção da capacidade não utilizada do cluster. 

Uma abordagem alternativa que pode ser considerada é adicionar reserva de capacidade ao seu serviço e não ao provedor de capacidade. Isso significa que, em vez de reduzir a configuração `Target Capacity` para iniciar a capacidade não utilizada, é possível aumentar o número de réplicas em seu serviço ao modificar a métrica de ajuste de escala de rastreamento de destino ou os limites de ajuste de escala em etapas do ajuste de escala automático do serviço. Observe que essa abordagem será útil somente para workloads com picos, mas não terá efeito ao implantar novos serviços e escalar de zero a determinado número de tarefas pela primeira vez. Para obter mais informações sobre políticas de escalabilidade relacionadas, consulte [Target Tracking Scaling Policies](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service-autoscaling-targettracking.html) ou [Step Scaling Policies](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service-autoscaling-stepscaling.html)