Cold start em serverless: o problema superado que ainda gera preconceito

Cold start em serverless: o problema superado que ainda gera preconceito

Até cerca de 4 anos atrás, o cold start em serverless computing realmente representava um problema, especialmente para aplicações que não permitiam tempo de espera para a sua inicialização.

🛂 English Version

Hoje, esta deficiência já foi superada e o cold é praticamente insignificante. Mas, mesmo assim, ele ainda é apontado como um “problema do serverless”, principalmente por pessoas que apenas leram sobre o assunto e não utilizam essa tecnologia no dia a dia.

Neste artigo, vamos apresentar o conceito de cold start em serviços serverless, veremos as suas principais causas, como funciona o cold start nas Lambdas da AWS, no Microsoft Azure e na Google Cloud Platform (GCP), quais são as linguagens de programação mais eficientes e quais tecnologias têm sido usadas para a superação do problema.

O que é cold start em serverless?

cold start em serverless

O serverless computing é uma das principais tendências da tecnologia atualmente, e um dos maiores benefícios desse tipo de computação é a escalabilidade automática, que permite que as empresas e desenvolvedores criem serviços altamente escaláveis ​​sem se preocupar com a infraestrutura subjacente.

No entanto, até uns 4 anos atrás, os desenvolvedores em serverless enfrentavam um problema chamado cold start, que ocorre quando uma função serverless é ativada pela primeira vez e há uma latência perceptível até que a função seja executada completamente.

O cold start é um termo utilizado para descrever o tempo que um serviço serverless leva para iniciar após ficar um período sem atividade. Quando um serviço está em "modo de espera", seu ambiente é desligado para economizar recursos e diminuir custos. Quando uma solicitação é recebida após um período de inatividade, o ambiente precisa ser reiniciado, o que pode levar a um atraso inicial.

O cold start afetava diretamente o desempenho do serviço e, portanto, a experiência do usuário, que era obrigado a esperar alguns segundos até que o serviço fosse executado completamente - o que era um problema crítico em algumas situações, como em transações financeiras, por exemplo.

O que é o cold start de Lambda da AWS?

O cold start de Lambda acontece quando uma função serverless é ativada pela primeira vez, ou após um período de inatividade, e precisa ser inicializada pelo serviço de computação da AWS. Isso pode levar a um atraso perceptível no tempo de execução da função, já que a infraestrutura precisa ser preparada para executar a função completamente.

As principais causas do cold start em uma Lambda da AWS incluem:

  • Ausência de instâncias em execução: quando uma função é ativada e não há nenhuma instância em execução, o serviço precisa criar uma nova instância e prepará-la para executar a função. Esse processo pode levar alguns segundos e resultar em um atraso perceptível na sua execução.

  • Tempo de vida da instância: as instâncias que executam funções serverless na AWS têm um tempo de vida limitado e podem ser desativadas após um período de inatividade. Quando uma função é ativada após esse período, pode ser necessário criar uma nova instância, resultando em um cold start.

  • Tamanho da função: funções serverless grandes ou complexas podem levar mais tempo para inicializar e, portanto, levar a um cold start mais perceptível.

  • Linguagem de programação: Algumas linguagens de programação podem levar mais tempo para inicializar. É o que veremos agora.

Qual é a melhor linguagem de programação para o cold start de Lambda?

A escolha da linguagem de programação pode ser um fator importante ao lidar com o cold start em serviços serverless. Algumas linguagens tendem a ter tempos de inicialização mais rápidos do que outras, o que pode influenciar a eficiência de uma função.

As linguagens de programação mais comuns em serviços serverless são o Node.js, Python, Java, Go e C#. Cada uma dessas linguagens tem suas vantagens e desvantagens em relação ao cold start.

🖳 Node.js⇗ é conhecido por ter tempos de inicialização mais rápidos do que outras linguagens. Isso se deve em parte ao fato de que o Node.js é executado em um único thread, o que simplifica a inicialização e reduz o tempo necessário para carregar módulos.

🖳 Python⇗ também é uma boa escolha para o cold start de Lambda, pois é uma linguagem interpretada que não requer a compilação de código antes da execução. No entanto, o tempo de inicialização pode ser afetado pelo tamanho do código e pela complexidade do ambiente de execução.

🖳 Java⇗ é uma linguagem compilada que pode levar mais tempo para ser inicializada, mas é conhecida por ser eficiente em termos de desempenho uma vez que a inicialização é concluída. Além disso, a JVM⇗ (Java Virtual Machine) tem uma ampla variedade de ferramentas de otimização e depuração disponíveis.

🖳 Go⇗ é uma linguagem que foi projetada para ter tempos de inicialização rápidos e é conhecida por ser eficiente em termos de desempenho. É uma boa escolha para serviços serverless que precisam de um alto nível de desempenho e baixa latência.

🖳 C#⇗ é uma linguagem que oferece suporte à compilação just-in-time (JIT) e pode ter tempos de inicialização mais longos. No entanto, o C# é conhecido por ser uma linguagem de programação poderosa e flexível.

💡 Em resumo, não há uma resposta definitiva sobre qual é a melhor linguagem para lidar com o cold start em serviços serverless. Cada linguagem tem suas próprias vantagens e desvantagens e a escolha dependerá do contexto específico e das necessidades do projeto.

Como lidar com cold start de Lambda?

Ao lidar com o cold start de Lambda, existem várias técnicas e tecnologias disponíveis. Uma abordagem comum é o pré-aquecimento do ambiente, que consiste em manter uma instância da função sempre em execução, para que não ocorra o tempo de inicialização quando houver uma solicitação.

Outra técnica é o uso de hot functions, que envolve manter as funções em um estado “quente” para evitar que elas sejam desativadas e precisem ser reiniciadas. Isso pode ser feito através do uso de eventos programados ou chamadas de função regulares.

O uso de ferramentas de monitoramento e análise de desempenho também pode ser útil para identificar gargalos em suas funções e fazer ajustes para reduzir o tempo de inicialização.

💡 É importante lembrar que essas técnicas e tecnologias podem ser usadas em conjunto para obter o melhor desempenho possível ao lidar com o cold start de Lambda.

O que é o cold start das Azure Functions?

Em primeiro lugar, é preciso fazer a distinção entre os dois tipos principais de Azure Functions da Microsoft: plano de consumo e plano dedicado.

O plano de consumo é o modelo serverless: o código reage a eventos, escala efetivamente para atender a qualquer carga e reduz quando o código não está em execução - e você é cobrado apenas pelo que usa. É nesse plano que acontece o cold start.

Já no plano dedicado, que envolve o aluguel do controle de uma máquina virtual, disponível 24 horas por dia, 7 dias por semana, não há cold starts - mas você paga por essa disponibilidade.

Assim como nas Lambdas da AWS, o cold start nas Azure Functions é o tempo total que um usuário deve esperar desde quando um evento acontece para iniciar uma função até que essa função conclua a resposta ao evento.

O que acontece durante um cold start em Functions da Azure?

  • A Azure aloca um servidor pré-configurado do pool de workers “mornos” para seu aplicativo. Este servidor já possui o tempo do Functions em execução, mas não é especializado.

  • Esse worker torna-se especializado configurando o tempo de execução da Function de maneiras específicas para seu aplicativo. Algumas coisas acontecem para fazer essa especialização:

    • A infraestrutura da Azure Functions monta seu conteúdo de arquivos para o worker que lhe foi atribuído.

    • As configurações do aplicativo específicas para seu aplicativo de Function são aplicadas ao worker.

  • O tempo de execução das Functions é redefinido e todas as extensões necessárias são carregadas no worker. Para descobrir quais extensões carregar, o tempo de execução lê os arquivos ``function.json`` de qualquer função no aplicativo de Functions. Por exemplo, isso acontece se você estiver usando Durable Functions ou se tiver chamadas de entrada ou saída.

  • As próprias funções são carregadas na memória pelos provedores de idioma. Isso levará uma quantidade variável de tempo com base no tamanho do seu aplicativo.

  • Seu código é executado.

Se você executou sua função recentemente, as etapas 1 a 4 já ocorreram, os recursos já estão alocados e seu site está aquecido. Como você pode imaginar, neste cenário as coisas são consideravelmente mais rápidas.

A Azure desaloca recursos após aproximadamente 20 minutos de inatividade, após os quais sua próxima chamada será um cold start e todo esse processo acontecerá novamente.

Quais são as melhores linguagens de programação para o cold start da Azure?

A Microsoft aconselha as linguagens geralmente disponíveis, como C#, F# e JavaScript (há várias linguagens experimentais que não são totalmente suportadas e otimizadas, as quais geram um novo processo a cada execução, o que afeta bastante a latência).

Como evitar totalmente o cold start na Microsoft Azure?

Assinando o plano dedicado você controla o que acontece em sua máquina virtual. Isso é um pouco mais caro e não é serverless, mas se sua solução tiver um requisito rígido de baixa latência em cada chamada individual, essa é a melhor saída.

Se a sua aplicação tem tolerância a uma pequena latência, saiba que as Azure Functions evoluíram o suficiente para que o cold start não seja mais um problema.

O que é o cold start nas Google Cloud Functions?

Assim como nas Lambdas da AWS e nas Azure Functions, o cold start nas Google Cloud Functions ocorre quando a primeira solicitação chega após o deploy.

Depois do processamento desta solicitação, a instância permanece ativa por 15 minutos. Depois deste período, as instâncias são recicladas.

Com relação às principais linguagens de programação para as Google Cloud Functions no que tange os cold starts, esta é a sequência (da melhor para a pior performance, apesar de as diferenças serem mínimas): JavaScript, Go e Python.

O tamanho do pacote é outro fator que influencia o cold start nas Google Cloud Functions. Adicionar dependências, aumentando assim o tamanho do pacote implementado, aumentará as durações dos cold starts.

As funções com muitas dependências podem ser 5 vezes mais lentas para iniciar.

Como o problema do cold start em serverless foi superado?

Nos últimos anos, várias tecnologias e abordagens foram desenvolvidas para a superação do problema do cold start em serviços serverless. Aqui estão as principais:

  • Node.js V8 Engine⇗**:** o uso do Node.js com o engine V8 pode ajudar a reduzir o tempo de inicialização e melhorar o desempenho geral de uma função Lambda.

  • Runtime Customization: essa abordagem permite a personalização do ambiente de execução de uma função Lambda, permitindo o pré-carregamento de bibliotecas e módulos específicos que são necessários para a função.

  • Estratégias de cache: o uso de cache pode ajudar a reduzir o tempo de inicialização e ocorrência de cold start em funções lambda, principalmente quando se trata de requisições de rede e armazenamento de dados.

  • AWS Lambda Provisioned Concurrency⇗**:** essa tecnologia permite pré-alocar um número específico de instâncias de uma função Lambda, reduzindo o tempo de inicialização e o risco de cold start (essa merece um capítulo próprio).

AWS Provisioned Concurrency e o fim do cold start

Provisioned Concurrency (“simultaneidade provisionada”, em tradução literal) é um recurso da AWS que oferece mais controle sobre o desempenho de aplicativos serverless. Com ele, você ganha a habilidade de evitar o cold start nas funções Lambda.

A simultaneidade provisionada permite criar aplicativos serverless escalonáveis com latência previsível. Você pode definir a simultaneidade desejada para todas as versões ou aliases de uma função.

A AWS Lambda prepara containers para suas funções, garantindo que eles possam ser invocados com latência de milissegundos de dois dígitos após serem chamados. Isso significa que as funções serverless podem se adaptar a picos repentinos de tráfego ou eventos de dimensionamento significativos sem aumentar a latência.

⚠️ No entanto, a simultaneidade provisionada tem um custo: você é cobrado a partir do momento em que a habilita, arredondada para os 5 minutos mais próximos. O preço é calculado de acordo com a quantidade de simultaneidade (número de chamadas de função simultâneas que podem ser executadas sem latência) e a quantidade de memória alocada.

Isso significa que você deve definir a simultaneidade provisionada com cuidado, especificando apenas o suficiente para suas cargas de trabalho, para evitar incorrer em custos desnecessários.

Conclusão

Ao longo deste artigo, apresentamos o conceito de cold start em serviços serverless e como ele pode afetar o desempenho de uma aplicação. Vimos também as principais causas do cold start em Lambdas da AWS e nas Functions da Azure e da Google Cloud Platform e estratégias para lidar com esse problema, como o pré-aquecimento do ambiente, o uso de hot functions, a escolha de linguagens de programação mais eficientes e o uso de ferramentas de monitoramento e análise de desempenho.

Além disso, discutimos a possibilidade de minimizar a latência e abordamos tecnologias recentes que têm sido usadas para a superação do problema do cold start.

Em resumo, foi-se o tempo em que lidar com o cold start em serviços serverless era um problemão para os desenvolvedores. A tecnologia evoluiu, e não só nos softwares. Surgiram novidades de hardware como SSDs e dispositivos de storage de alta velocidade. Tudo isso causou impactos positivos nas Lambdas e nas Functions. Os próprios computadores pessoais evoluíram, ocasionando melhores performances das aplicações.

Além disso, todas as plataformas citadas estão constantemente trabalhando para mitigar os efeitos do cold start, cada uma à sua maneira.

Assim, com hardwares e softwares evoluindo em conjunto, conseguimos diminuir a latência das aplicações, o que resultou no aprimoramento da experiência do usuário.

Embora (ainda) não seja possível evitar completamente o cold start em serviços serverless, hoje sua latência é tão pequena que fica até feio tentar justificar a não adesão a essa tecnologia usando o cold start como exemplo.

Então, se esse era o seu receio, pode abraçar os benefícios do serverless computing sem medo! 🚀