O blog da AWS
Entendendo os limites de limitação de invocação do AWS Lambda
Quando você chama a API Invoke do AWS Lambda, uma série de limites de “throttle” (controle de acessos simultâneos) são avaliados para decidir se sua chamada será atendida ou limitada com uma exceção de 429 “Muitas solicitações” / “Too Many Requests”. Este blog explica os limites de “throttling” de invocação mais comuns e a relação entre eles, para que você possa entender melhor as cargas de trabalho de escalabilidade no AWS Lambda.
Visão Geral
Os limites de “throttling” existem para proteger os seguintes componentes da arquitetura interna de serviços do Lambda e seus workloads:
- Ambiente de execução: Um ambiente de execução é um em que seu código de função é executado. Um determinado ambiente de execução hospeda somente uma invocação por vez, mas pode ser reutilizado para invocações subsequentes da mesma versão da função.
- Plano de dados de invocação: são uma série de serviços web internos que, em uma chamada, selecionam (ou criam) uma sandbox e direcionam sua solicitação para ela. Isso também é responsável por impor os limites de “throttling”.
Quando você faz uma chamada da API Invoke, ela transita por alguns ou todos os serviços do Invoke Data Plane, antes de chegar a um ambiente de execução em que seu código de função é baixado e executado.
Há três limites de “throttling” distintos, mas relacionados, que juntos decidem se sua solicitação de invocação é aceita pelo plano de dados ou limitada.
Simultaneidade
Concorrência ou Simultaneidade (Concurrency) significa “existir, acontecer ou ao mesmo tempo”. Assim, o limite de simultaneidade do Lambda é um limite nas invocações simultâneas em voo (em execução simultânea) permitida a qualquer momento. Não é um limite de transações por segundo (TPS) por si só, mas sim um limite de quantas invocações podem estar em andamento ao mesmo tempo. Essa documentação explica visualmente o conceito de simultaneidade.
Nos bastidores, o limite de simultaneidade se traduz aproximadamente em um limite no número máximo de ambientes de execução (e, portanto, de microVMs do Firecracker) que sua conta pode reivindicar a qualquer momento. O Lambda executa uma frota de instâncias de hardware básico multilocatário (multi-tenant), nas quais as microVMs Firecracker são criadas para servir como ambientes de execução para suas funções. A AWS monitora e dimensiona constantemente essa frota com base na demanda recebida e compartilha a capacidade disponível de forma justa entre os clientes.
O limite de simultaneidade ajuda a proteger o AWS Lambda de um único cliente esgotar toda a capacidade disponível e causar uma negação de serviço a outros clientes.
Transações por segundo (TPS)
Os clientes geralmente perguntam como seu limite de simultaneidade se traduz em TPS. A resposta depende de quanto tempo duram suas invocações de função.
O diagrama acima considera três casos, cada um com uma duração de invocação de função diferente, mas um limite fixo de simultaneidade de 1000. No primeiro caso, as invocações têm uma duração constante de 1 segundo. Isso significa que você pode iniciar 1.000 invocações e reivindicar todos os 1.000 ambientes de execução permitidos pelo seu limite de simultaneidade. Esses ambientes de execução permanecem ocupados durante todo o segundo e você não pode iniciar mais invocações nesse segundo porque seu limite de simultaneidade impede que você reivindique mais ambientes de execução. Portanto, o TPS que você pode obter com um limite de simultaneidade de 1000 e uma duração de função de 1 segundo é 1000 TPS.
No caso 2, a duração da invocação é reduzida pela metade para 500 ms, com o mesmo limite de simultaneidade de 1000. Você pode iniciar 1000 invocações simultâneas no início da segunda, como antes. Essas invocações mantêm os ambientes de execução ocupados durante a primeira metade do segundo. Depois de terminar, você pode iniciar mais 1000 invocações nos mesmos ambientes de execução e, ao mesmo tempo, estar dentro do limite de simultaneidade. Então, ao reduzir pela metade a duração da função, você dobrou seu TPS para 2000.
Da mesma forma, no caso 3, se a duração da função for de 100 ms, você poderá iniciar 10 rodadas de 1000 invocações cada uma em um segundo, alcançando um TPS de 10K.
Codificando isso como uma equação, o TPS que você pode alcançar com um limite de simultaneidade é:
TPS = simultaneidade/duração da função em segundos
Levada ao extremo, com uma duração de função de apenas 1 ms e com um limite de simultaneidade de 1000 (o limite padrão), uma conta pode gerar um TPS de invocação de um milhão. Para cada unidade adicional de simultaneidade concedida por meio de um aumento de limite, ela concede implicitamente mais 1000 TPS por unidade de simultaneidade aumentada. O alto número de TPS não requer nenhum ambiente de execução adicional (Firecracker microVMS), portanto, não é problemático do ponto de vista da capacidade. No entanto, gerar mais de um milhão de TPS a partir de uma única conta sobrecarrega os serviços do Invoke Data Plane. Eles também devem ser protegidos dos impactos de outras chamadas, para que todos os clientes tenham uma parcela justa da largura de banda dos serviços. Um limite de simultaneidade por si só não é suficiente para se proteger contra isso — o limite de TPS fornece essa proteção.
No momento em que este artigo foi escrito, o TPS de invocação estava limitado a 10 vezes sua simultaneidade. Adicionado à equação anterior:
TPS = min (10 x simultaneidade, simultaneidade/duração da função em segundos)
O fator de simultaneidade é comum em ambos os termos na função min, então a comparação principal é:
min (10, 1/duração da função em segundos)
Se a duração da função for exatamente 100ms (ou 1/10 de segundo), os dois termos na função min serão iguais. Se a duração da função for superior a 100 ms, o segundo termo será menor e o TPS será limitado de acordo com a duração da simultaneidade/função. Se a duração da função for inferior a 100 ms, o primeiro termo será menor e o TPS será limitado de acordo com 10 x simultaneidade.
Resumindo, o limite de TPS existe para proteger o Invoke Data Plane da alta rotatividade de invocações de curta duração, para as quais o limite de simultaneidade por si só proporciona um TPS muito alto. Se você gerar invocações curtas de menos de 100 ms, sua taxa de transferência será limitada como se a duração da função fosse de 100 ms (com 10 x a simultaneidade), conforme mostrado no diagrama acima. Isso implica que invocações de curta duração podem ser limitadas por TPS, em vez de limitadas por concorrência. No entanto, se a duração da função for superior a 100 ms, você poderá efetivamente ignorar o limite de TPS de simultaneidade de 10 vezes e calcular o TPS disponível como duração da simultaneidade/função.
Burst / Explosão
O terceiro limite de “throttling” é o limite de rajada. O AWS Lambda não mantém ambientes de execução provisionados para todo o seu limite de simultaneidade em todos os momentos. Isso seria um desperdício, especialmente se os picos de uso forem transitórios, como é o caso de muitas cargas de trabalho. Em vez disso, o serviço ativa os ambientes de execução na hora certa quando a invocação chega, caso ainda não exista. Depois que um ambiente de execução é ativado, ele permanece “aquecido” por algum período de tempo e fica disponível para hospedar invocações subsequentes da mesma versão da função.
No entanto, se uma invocação não encontrar um ambiente de execução quente, ela terá uma “inicialização a frio” (cold start) enquanto provisionamos um novo ambiente de execução. As “inicializações a frio” envolvem certas operações adicionais além do caminho de inicialização a quente, como baixar seu código ou contêiner e inicializar seu aplicativo no ambiente de execução. Essas operações de inicialização geralmente são computacionalmente pesadas e, portanto, têm uma taxa de transferência menor em comparação com o caminho de invocação quente. Se houver picos repentinos e acentuados no número de “cold start”, isso pode pressionar os serviços de invocação que lidam com essas operações de “cold start” e também causar efeitos colaterais indesejáveis em seu aplicativo, como aumento de latências, redução da eficiência do cache e aumento da distribuição nas dependências posteriores. O limite de burst (explosão) existe para proteger contra esses picos de “cold start”, especialmente para contas que têm um alto limite de simultaneidade. Ele garante que a subida até um limite alto de simultaneidade seja gradual, a fim de suavizar o número de inicializações a frio em uma explosão.
O algoritmo usado para impor o limite de burst é o algoritmo de limitação de taxa do Token Bucket. Considere um bucket do Amazon S3 que contém fichas. O bucket tem uma capacidade máxima de B tokens (burst). O bucket começa cheio. Cada vez que você envia uma solicitação de invocação que exige uma unidade adicional de simultaneidade, ela custa um token do bucket. Se o token / ficha existir, você receberá a simultaneidade adicional e o token será removido do bucket. O bucket é reabastecido a uma taxa constante de r tokens por minuto (taxa) até atingir sua capacidade máxima.
O que isso significa é que a taxa de aumento da simultaneidade é limitada a “r” tokens por minuto. Embora o algoritmo permita coletar até “b” tokens e explodir, você deve esperar que o bucket seja reabastecido antes de estourar novamente, limitando efetivamente sua taxa média a “r” por minuto.
O gráfico acima mostra o limite de “burst” em ação com um limite máximo de simultaneidade de 3000, um máximo de “burst” (B) de 1000 e uma taxa de recarga (r) de 500/minuto. O bucket de tokens começa cheio com 1000 tokens, assim como o espaço livre de burst disponível.
Há uma atividade de “burst” entre o primeiro e o segundo minuto, que consome todos os tokens no bucket e reivindica todos os 1000 ambientes de execução simultânea permitidos pelo limite de “burst”. Nesse ponto, o bucket está vazio e qualquer tentativa de reivindicar ambientes adicionais de execução simultânea é interrompida (throttled) , apesar de a simultaneidade máxima ainda não ter sido alcançada.
O bucket de tokens e o espaço livre de “burst” são reabastecidos nos minutos dois e três com 500 fichas a cada minuto para trazê-lo de volta à sua capacidade máxima de 1000. No quarto minuto, não há recarga adicional porque o bucket está na capacidade máxima. Entre os minutos quatro e cinco, há uma segunda atividade de “burst” que esvazia o bucket novamente e exige mais 1.000 ambientes de execução, elevando o número total de ambientes de execução ativos para 2.000.
O bucket continua sendo reabastecido a uma taxa de 500/minuto nos minutos cinco e seis. Nesse ponto, tokens suficientes foram acumulados para cobrir todo o limite de simultaneidade de 3000 e, portanto, o bucket não é mais recarregado, mesmo quando você tem a terceira atividade de intermitência no minuto sete. No décimo minuto, quando todo o uso diminui, o espaço livre de “burst” disponível desce lentamente até a explosão inicial máxima de 1K.
Os números reais da taxa máxima de “burst” e recarga variam de acordo com a região e estão sujeitos a alterações. Visite a página de limites de intermitência do Lambda para obter valores específicos.
É importante distinguir que o limite de intermitência não é um limite de taxa na própria invocação, mas um limite de taxa sobre a rapidez com que a simultaneidade pode aumentar. No entanto, como invocar o TPS é uma função da simultaneidade, ela também determina a rapidez com que o TPS pode aumentar (um limite de taxa para um limite de taxa). O gráfico a seguir mostra como a altura máxima de estouro do TPS segue um padrão de degrau de escada semelhante ao da altura livre de “bust” simultânea, somente com um multiplicador.
Conclusão
Este blog explica os três principais limites de “throttling” aplicados às invocações do AWS Lambda: o limite de simultaneidade, o limite de TPS e o limite de “burst”. Ele descreve a relação entre esses limites e como cada um protege o sistema e sua carga de trabalho. Com esse conhecimento, você pode interpretar melhor quaisquer exceções 429 de limitação que você possa receber ao escalar seus aplicativos no AWS Lambda.
Para obter mais informações sobre como começar a usar o Lambda, visite o Guia do desenvolvedor.
Para obter mais recursos de aprendizado sem servidor, visite Serverless Land.
Este artigo foi traduzido do Blog da AWS em Inglês.
Sobre o autor
Archana Srikanta
Tradutor
Daniel Abib é Enterprise Solution Architect na AWS, com mais de 25 anos trabalhando com gerenciamento de projetos, arquiteturas de soluções escaláveis, desenvolvimento de sistemas e CI/CD, microsserviços, arquitetura Serverless & Containers e segurança. Ele trabalha apoiando clientes corporativos, ajudando-os em sua jornada para a nuvem.