FaaS vs Container
Qual modelo usar para suportar os códigos?
Por diversas vezes, em diversas companhias e para diversos cenários, encontramos o dilema entre utilizar um modelo FaaS ou um modelo baseado em Container para suportar os códigos. Hoje, vamos falar um pouco sobre os conceitos que vão auxiliar na escolha do melhor caminho para seguir.
O que é FaaS (Functions as a Service)?
FaaS é um conceito que se baseia no uso de funções (partes de software que resolvem um problema do negócio) de forma orientada a eventos. Esse modelo abstrai o gerenciamento de qualquer infraestrutura, o que o classifica como um modelo Serverless.
E o que é Serverless?
Como o próprio nome diz, Serverless significa "sem servidor", ou seja, a execução ocorre sem ter qualquer tipo de infraestrutura gerenciada para suportá-la. Quando usamos o conceito de FaaS (que trabalha no modelo Serverless) a execução de cada função acontece de forma paralelizada, ou seja, para cada chamada a uma função é criada uma nova "instância" dela para atender a essa chamada.
No caso da AWS, o serviço que provê esse tipo de solução é chamado de "Lambda" e é cobrado basicamente por quantidade de execuções, tempo de execução e em alguns casos pela quantidade de memória dedicada.
O que é Container?
Um container, por sua vez, é uma virtualização de um Sistema Operacional que usa isolamento de recursos e compartilhamento de Kernel para suportar as execuções do código, e por isso são mais leves que VM's. Em um container é instanciado um SO para suportar a aplicação de forma completamente apartada do host desse container. Sendo assim, pode-se ter "N" containers para "N" aplicações, cada container com o setup necessário para a aplicação que está dentro dele executar perfeitamente. No caso da AWS, o principal serviço que provê esse tipo de solução é o "AWS ECS" e é cobrado de forma similar ao "AWS Lambda", porém, será cobrado também pelo uso de recursos de hardware (CPU e memória).
Quando escolher algum dos dois?
Bom, essa é uma ótima dúvida! Para respondê-la, antes vamos precisar entender duas estratégias que fazem a separação entre os dois modelos: Stateless e Stateful.
Stateless
Como o próprio nome já diz, Stateless significa "Sem estado", ou seja, é uma estratégia de design de código que faz com que todas as chamadas desse código sejam tratadas como se fossem a primeira e, assim, não existe nenhum armazenamento de valores em memória que possa ser reutilizado por chamadas posteriores.
Stateful
É o contrario do conceito de Stateless, ou seja, é uma estratégia de design de código que permite armazenar valores em memória que possam ser resgatados e reutilizados em próxima chamadas.
Boa! Agora que entendemos de forma resumida os dois conceitos podemos notar que o modelo de código em FaaS atende somente à estratégia Stateless, pelo simples fato de que cada chamada é tratada por uma nova "instância" daquele código, ou seja, é tratada como se fosse a primeira chamada. E claramente podemos utilizar as duas estratégias no caso do código em Container, porque ele compartilha da mesma instância para receber requisições e possui uma infraestrutura com memória compartilhada entre essas requisições (Stateful), e também porque um código não necessariamente precisa trabalhar com essa memória (Stateless).
Ok! Mas se o Container resolve as duas estratégias, então por que utilizar FaaS? Como já foi dito, no modelo FaaS não existe infraestrutura para gerenciar, então é uma estrutura muito mais fácil de manter e provisionar.
Não perca de vista o conceito de FaaS
Não é recomendado ter grandes soluções com muitas funções executando dentro do que deveria ser uma única função.
E no caso da performance?
O modelo FaaS inicia o código apenas quando ele é chamado, logo, deve-se levar em consideração que o seu código tem um tempo de subida, e esse tempo vai impactar na resposta do seu cliente, ou seja:
tempoTotal=tempoDeSubida+tempoDeProcessamento
- Para o serviço “AWS Lambda” existe uma forma de resolver esse problema ativando o modo de simultaneidade, que vai deixar o seu código pré-pronto para executar, mas essa é uma feature que custa um valor à parte.
No modelo de Container o código já está em execução e preparado para receber as requisições, sem ter a necessidade de subir uma nova instância dele para processar cada uma. Porém, pelo fato de compartilhar da mesma instância para as requisições, os recursos de hardware desse container são compartilhados também, ou seja, quanto mais requisições, mais threads serão abertas e consequentemente haverá um maior consumo de CPU e memória para processar todas em paralelo, mas é possível escalar containers de forma horizontal para distribuir as requisições.
E para processos Batch?
No modelo de Container pode-se trabalhar muito bem com processamentos batch, porque ele não possui restrição de tempo de execução e possui os recursos da máquina Host compartilhado entre eles. Sendo assim, é possível ter uma máquina com uma quantidade alta de recursos e dentro dela executar containers que façam processos batch agendados em períodos diferentes um do outro para otimizar o tempo de processamento e utilização de recursos da máquina.
Para o modelo de código em FaaS podem haver alguns impedimentos… Em alguns serviços de nuvem, como o AWS Lambda, existe um limite de tempo de execução e de recursos de hardware, ou seja, se o código faz um processamento pesado em cima de GB's de dados, então possivelmente não será possível finalizar a execução até que o tempo limite de execução acabe,e assim o seu processo vai ficar incompleto.
Também é possível usar ambos os modelos, juntos, para resolver um processo batch de forma mais performática e segura. Por exemplo, usando o container para buscar os dados e colocá-los em um serviço de fila (por exemplo o AWS SQS) e um processo FaaS ser acionado por esse evento na fila para tratar esses dados de forma paralelizada.
Resumindo…
Foi possível notar que cada um dos modelos atendem tipos de aplicações com finalidades e funcionalidades diferentes, ou seja, nenhum dos dois é melhor que o outro para resolver qualquer problema. No final das contas, é tudo uma questão de arquitetura, na qual outros serviços podem auxiliar os dois modelos na resolução do problema.
Para usar o código em um modelo FaaS é recomendado que a aplicação respeite algumas "regras", sendo elas:
- Tenha um processamento "curto", ou seja, requisições leves com processamento rápido.
- Não dependa de recursos de "terceiros" (fora de seu domínio) em momento de processamento (ex: API's).
- Design Stateless.
Enquanto que para usar o código no modelo de Container:
- Recebimento de centenas de requisições por segundo com um processamento mais "pesado" em cada uma, talvez maior do que 2 ou 3 segundos.
- Funcionalidades com persistência em recursos de servidor (ex: Disco rígido, memória e etc).
- Processamentos com muito uso de recursos de hardware em uma grande quantidade de dados.
E é isso! Se ficou alguma dúvida ou tem algo a dizer, é só deixar um comentário. E se você quiser trabalhar com um time que está sempre compartilhando conhecimento, clique aqui, saiba mais sobre a Concrete e Vamos Aprender Juntos! Até a próxima.