software

Comparando Nuclio e AWS Lambda

Com o serverless, você delega a responsabilidade de executar sua infraestrutura para um provedor de plataforma, tanto quanto possível. Isso libera seus engenheiros para se concentrarem em criar o que seus clientes querem de você – os recursos que diferenciam sua empresa da de seus concorrentes. Para que essa filosofia funcione, no entanto, a plataforma precisa não apenas fornecer as ferramentas para construir esses recursos, mas também fornecer o desempenho que manterá os engenheiros satisfeitos.

Sim, serviços como o AWS Lambda são poderosos, mas possuem várias limitações bem documentadas que os tornam inadequados para algumas cargas de trabalho. Esses incluem:

As partidas a frio e a alta latência as tornam inadequadas para aplicativos em tempo real que exigem tempos de resposta consistentes e em nível de milissegundos.
O modelo de pagamento por invocação os torna caros em cenários de alto rendimento.
O modelo orientado a eventos, associado a um tempo máximo de execução ou restrições de tamanho de dados, torna-os inadequados para tarefas de longa execução ou dados pesados ​​ou processamento de AI.
Eles estão limitados a acionadores e fontes de eventos que são específicos para o provedor de nuvem.
Digite Nuclio, uma plataforma sem servidor de código aberto que é construída sobre o Kubernetes e vem em versões gerenciadas de plataforma como serviço (PaaS) e auto-hospedadas. Neste post, vamos comparar o Nuclio com o AWS Lambda, ver como o Nuclio aborda as limitações acima e explorar os novos casos de uso que o Nuclio está desbloqueando, como:

Pipelines de processamento de dados de alto rendimento ou ETL.
Servindo modelos de aprendizado de máquina em tempo real.
Aplicativos em tempo real, como jogos multiplayer.
Trabalhos e serviços de longa duração.
Nuclio vs AWS Lambda
Concorrência
Uma das maiores mudanças do desenvolvimento tradicional de aplicativos para o AWS Lambda é como a simultaneidade é gerenciada. Um aplicativo da web Express.js em execução em um contêiner / VM pode manipular várias solicitações simultaneamente. Em outras palavras, seu aplicativo gerencia sua própria simultaneidade. Você dimensiona o aplicativo aumentando o número de solicitações simultâneas que ele pode manipular (aumentando a escala) e aumentando o número de contêineres (dimensionando para fora).

Figura 1: Os aplicativos tradicionais aumentam a moeda dentro do aplicativo e dimensionam o número de nós que executam o aplicativo.
Com o AWS Lambda, a simultaneidade é gerenciada pela plataforma e uma execução simultânea processaria apenas uma solicitação por vez – muito semelhante a um ator no modelo do agente, que processaria uma mensagem por vez. O aplicativo pode ser dimensionado aumentando o número de execuções simultâneas da função.

O modelo de concorrência da Lambda tem suas vantagens:

Simplifica o desenvolvimento de aplicativos. A simultaneidade é uma fonte constante de bugs e problemas de desempenho, pois os desenvolvedores lutam para escrever aplicativos altamente simultâneos.
Ele permite que você classifique cada chamada individualmente porque você não tem contenção de recursos ao lidar com solicitações simultâneas. Isso permite o modelo de preços de pagamento por uso e é um dos pilares da findev.
Ainda assim, o Lambda também tem algumas desvantagens:

Você não pode fazer uso de ciclos de CPU inativos quando uma função está aguardando o IO. Como a maioria das funções são IO-heavy, isso resulta em ineficiências significativas.
Requer mais escalonamento, o que significa mais partidas a frio. Para lidar com X solicitações simultâneas, você precisa de X execuções simultâneas, o que equivale a X cold starts. Isso torna quase impossível alcançar um desempenho previsível.
Nuclio, por outro lado, pode aumentar ou diminuir a escala. Um processador de funções (análogo a um contêiner) pode hospedar vários funcionários de função. Cada trabalhador pode processar uma mensagem por vez. Esse sistema suporta simultaneidade no mesmo processador e, em seguida, dimensiona automaticamente o número de réplicas do processador com base na carga.

Outra diferença interessante entre Lambda e Nuclio é que o Nuclio permite que você especifique o número mínimo e máximo de réplicas. E como um aparte, o Nuclio também suporta GPUs.

Figura 3: O Nuclio permite configurar o número mínimo e máximo de réplicas.
Com o Lambda, você pode configurar uma simultaneidade reservada para uma função, que (contra-intuitivamente) define suas execuções máximas simultâneas. Mas não há como dizer ao sistema para manter sempre um certo número de execuções simultâneas em execução em todos os momentos. O sistema sempre é escalonado para zero quando não há tráfego – comportamento altamente indesejável para sistemas que experimentam picos regulares no tráfego.

Por exemplo, meu empregador, DAZN, está no ramo de streaming de esportes. Nós vemos grandes picos de tráfego o tempo todo, enquanto milhões de usuários inunda em segundos antes de um evento esportivo começar.

Figura 4: Plataformas de streaming de esportes, como a DAZN, experimentam enormes picos de tráfego pouco antes do início de um evento esportivo.
Sem a capacidade de configurar o número mínimo de execuções simultâneas, esses picos resultam em um grande número de partidas a frio. Além disso, nesses casos, o Lambda precisa dimensionar rapidamente o número de execuções simultâneas para atender ao aumento da demanda. Aqui, também encontramos o limite de 500 / minuto na rapidez com que o Lambda é capaz de se expandir. Como tal, atualmente não podemos usar o Lambda no caminho crítico do nosso sistema, que tem que suportar esses picos.

Com o Nuclio, você pode atualizar programaticamente a contagem mínima de réplicas antes do evento para que, quando os picos surgirem, você não tenha que se preocupar em atingir limites de escala ou resistir ao impacto no desempenho de partidas a frio. Você também pode dizer ao Nuclio para escalar para zero imediatamente por meio de chamadas de API, o que economiza recursos.

Figura 5: Ajustar o número mínimo de réplicas permite lidar com picos previsíveis no tráfego.
Tempo esgotado
Outra grande diferença entre Lambda e Nuclio é como o tempo limite é tratado. Com o Lambda, uma chamada pode ser executada por até 15 minutos. Embora seja possível usar funções recursivas ou funções de etapas para estender esse limite, as duas abordagens têm seus próprios problemas. Assim, as funções do Lambda são ótimas para arquiteturas orientadas a eventos e para executar tarefas efêmeras e curtas.

Com o Nuclio, não há tempo de execução máximo. Os contêineres podem continuar em execução, o que, por sua vez, permite que você vá além das restrições do modelo orientado a eventos. Agora você pode transformar uma função em um serviço de longa duração, o que desbloqueia alguns casos de uso interessantes, como trabalhos ETL de longa duração e modelos de aprendizado de máquina de treinamento (ML).

Estado de Cache entre Invocações
Ambas as funções Lambda e Nuclio aceitam um evento e contexto durante uma chamada.

Figura 6: As funções Nuclio e Lambda aceitam um evento de invocação e contexto como argumentos.
Com o Lambda, o objeto de contexto é efêmero e não persiste entre invocações. Se você quiser persistir os dados entre invocações (por exemplo, configurações estáticas, conexões de banco de dados), será necessário declará-las como variáveis ​​globais fora do manipulador de funções.

Com o Nuclio, o próprio contexto de execução é persistido entre invocações e pode ser usado para armazenar em cache o estado. O objeto de contexto também inclui um criador de logs interno, que suporta o log estruturado com JSON e quatro níveis de log: DEBUG, INFO, WARN e ERROR.

Você pode configurar o nível de log padrão para uma função e até mesmo substituir esse nível de log padrão por chamada – o que é muito útil para depuração. Você também pode exportar seus registros para serviços externos, como o Elasticsearch.

Figura 7: Com o Nuclio, você pode selecionar o nível de registro padrão para cada função.

Figura 8: Você também pode substituir o nível de log padrão de uma chamada.
Além disso, há ganchos para executar a inicialização de contexto, que é chamada antes da primeira chamada na função. Isso permite que você execute a lógica de inicialização antes que o contêiner seja colocado em uso ativo e remova o temido problema de partida a frio do qual o Lambda sofre.

Volumes de Dados e Conexões de Dados Persistentes
Com o Lambda, as funções só são executadas quando são acionadas por eventos. Além disso, as execuções simultâneas são coletas de lixo quando ficam inativas por alguns minutos. Esse comportamento dificulta a vida quando você está trabalhando com sistemas de gerenciamento de banco de dados relacional (RDBMS) e outros sistemas que exigem conexões persistentes. De fato, um conjunto de diretrizes foi desenvolvido para ajudá-lo a evitar as muitas armadilhas de usar o Lambda com o RDBMS. Além disso, o Lambda não permite que você use dados persistentes em montagens de sistema de arquivos padrão, o que obriga a copiar para / de armazenamento de objetos antes de trabalhar em arquivos grandes, como imagens, registros, modelos ML etc.

Com o Nuclio, no entanto, você pode usar o objeto de contexto para manter conexões persistentes com bancos de dados. Como o contexto é mantido no nível do processador, você obtém uma melhor reutilização, pois eles são compartilhados entre invocações. Você também pode cuidar de outros aspectos da coleta de dados com vinculações de dados, incluindo o envio em lote e o armazenamento em cache, o que ajuda a melhorar o desempenho de E / S do aplicativo. Além disso, você pode montar volumes em funções, o que é útil para trabalhar com modelos ML ou Tensorflow, e você pode montar segredos do Kubernetes como volumes. De fato, o Nuclio suporta todos os tipos de volume suportados pelo Kubernetes.

Tempos de execução
Tanto o Lambda quanto o Nuclio suportam linguagens populares como Go, Node.js, Python, .Net Core, Java e Ruby. Além disso, ambas as plataformas oferecem uma maneira de personalizar o tempo de execução da execução.

Com o Lambda, você pode criar um tempo de execução personalizado e distribuí-lo por meio do AWS Lambda Layers. Isso permite que você introduza tempos de execução de idioma adicionais que não são suportados nativamente pela plataforma Lambda. Vários fornecedores publicaram tempos de execução para PHP, Rust, Erlang e Elixir, para citar alguns.

Com o Nuclio, você pode executar funções em sua própria imagem do Docker (veja a Figura 9), que pode vir de um repositório de imagens privadas. Isso permite que você personalize o próprio ambiente de execução.

Você também pode suportar tempos de execução adicionais por meio de uma função Shell, que permite manipular eventos de invocação com qualquer binário executável. Veja este exemplo para mais detalhes.

Figura 9: O Nuclio permite executar funções sobre sua própria imagem do Docker, que pode vir de um repositório de imagens privado.
Gatilhos
O Lambda é suportado por uma ampla variedade de fontes de eventos.

Nuclio vem com 13 triggers, incluindo cron, HTTP, Kafka, Kinesis e RabbitMQ. Como o Nuclio é de código aberto, você também pode criar seu próprio gatilho para serviços com os quais deseja se integrar e alavancar as contribuições de outras pessoas. O gatilho HTTP oferece uma maneira fácil de integrar o Nuclio a outras fontes de eventos que suportam HTTP como destino, como o SNS. Além disso, como o Nuclio suporta o padrão CNCE CloudEvents, pode-se argumentar que ele suporta muito mais fontes de eventos que são compatíveis com o CloudEvents.

Os triggers Nuclio são todos normalizados para o mesmo objeto Event. Isso elimina a necessidade de entender a assinatura específica do evento para cada fonte de evento, o que muitas vezes é confuso ao trabalhar com o Lambda. Também facilita a troca de uma função entre diferentes gatilhos.

Gatilho HTTP incorporado
Com o Lambda, você precisa usar o API Gateway para criar um endpoint HTTP para suas funções. O API Gateway é um serviço rico em recursos, mas também é complicado e muitas vezes custa mais para ser executado do que o próprio Lambda. Ele também adiciona outra fonte de latência à sua API, que, no mínimo, gira em torno de 5 a 10 ms, e pode sobrecarga para mais de 100 ms. Essa sobrecarga de custo e latência o torna inadequado para aplicativos com alto rendimento ou requisitos rígidos em tempo real.

Com o Nuclio, cada função recebe uma interface HTTP privada por padrão. Para expor o terminal publicamente, você precisa especificar um gatilho HTTP semelhante ao API Gateway. No entanto, ao contrário do API Gateway, esse gatilho HTTP não incorre em custos extras e tem um mínimo de sobrecarga de latência.

Figura 10: Com o Nuclio, cada função obtém uma interface HTTP privada por padrão.
Desbloqueio de novos casos de uso com o Nuclio
Como você pode ver em nossa comparação, o Nuclio difere do Lambda em várias áreas importantes, como seu modelo de simultaneidade e que não tem tempo de execução máximo. Isso abre a porta para toda uma gama de casos de uso. Vamos dar uma olhada para alguns.

Pipelines ou APIs de processamento de dados de alto rendimento
Para uma API de alto rendimento, o custo do API Gateway e do Lambda é drasticamente mais alto do que um aplicativo equivalente em execução em contêineres. Essa discrepância de custo levou muitos a reescreverem seus aplicativos.

O modelo de concorrência de Nuclio faz uso mais eficiente dos recursos disponíveis, o que reduz significativamente o custo operacional quando executado em escala. As funções têm interfaces HTTP incorporadas, para que você também não precise pagar por um serviço de API Gateway caro.

A capacidade de montar um volume para sua função também permite ler e gravar dados em / de um volume montado em alta velocidade e permite a criação de aplicativos com estado. Novamente, você não pode fazer isso com o Lambda hoje, já que ele não permite anexar volumes do Amazon Elastic File System (Amazon EFS) às funções.

Esses recursos tornam economicamente viável a execução de APIs de alto rendimento e alto desempenho em funções Nuclio. O mesmo também pode ser dito sobre os pipelines de processamento de dados de alto rendimento que precisam processar vários terabytes de dados por hora.

APIs com picos previsíveis no tráfego
O Nuclio oferece a capacidade de configurar um número mínimo de réplicas. Isso permite que os sistemas que experimentam picos previsíveis no tráfego reservem recursos suficientes antecipadamente e evitem degradar a experiência do usuário quando os picos ocorrerem. Os exemplos incluem serviços de pedidos de alimentos, como o Just Eat ou o Deliveroo, ou serviços de streaming de esportes, como o DAZN.

Ao mesmo tempo, o Nuclio ainda permite que você se torne zero, configurando o número mínimo de réplicas como zero. Ele lhe dá o controle para otimizar o uso de recursos ou a latência, dependendo da situação.

Aplicações em Tempo Real
O Nuclio não sofre de cold starts e é capaz de fornecer tempos de resposta consistentes e sub-milissegundos em invocações. Isso faz com que seja uma solução adequada para aplicativos com requisitos rígidos em tempo real, como jogos com vários participantes e bots em tempo real.

Servindo Modelos de Aprendizado de Máquina em Tempo Real
Para fornecer modelos ML em tempo real, você precisa ter latência de API forte e previsível e a capacidade de carregar e trabalhar com modelos ML que geralmente são grandes em tamanho (GBs).

O Nuclio permite anexar volumes do Kubernetes às suas funções, e não há limites de tamanho para esses volumes. Combinado com as características de desempenho, é possível implementar essas cargas de trabalho exigentes com as funções do Nuclio.

O Nuclio também possui integração nativa com o Jupyter e permite que você implante automaticamente os notebooks Jupyter e modelos ML como funções Nuclio.

Empregos e serviços de longa duração
O Nuclio não impõe um tempo limite máximo de execução em invocações de função. Isso permite transformar suas funções em serviços de longa duração e executar tarefas ETL de longa execução.

O gancho init_context () do Nuclio permite criar serviços de longa duração, como um aplicativo que lê constantemente um feed do Twitter (por exemplo, carrega o TwythonStreamer com o contexto, que está pesquisando um serviço externo, versus se tornando acionado por um evento).

Conclusão
Como discutimos, o Nuclio é uma das poucas soluções de código aberto que também são viáveis ​​para os negócios. Ele possui vantagens arquitetônicas importantes para aplicativos de alto desempenho ou orientados a dados, incluindo:

Nuclio é agnóstico em nuvem. Pode ser usado em cenários de nuvem múltipla / híbrida. Você também pode executar o Nuclio em um laptop usando o Docker simples, o que facilita a depuração.
O modelo de simultaneidade do Nuclio e a capacidade de montar volumes de arquivos permitem criar APIs de alto desempenho e pipelines de processamento de dados de alto rendimento.
O Nuclio oferece maior controle sobre a simultaneidade de seu aplicativo, o que o torna viável mesmo para aplicativos com tráfego muito espinhoso.
Os contextos de execução do Nuclio são persistidos entre invocações e não impõe um tempo máximo de execução nas invocações. Isso permite que você crie aplicativos com estado de execução longa, como trabalhos ETL.
O Nuclio permite anexar volumes do Kubernetes às suas funções e não tem limitações quanto ao tamanho do volume. Isso possibilita que você trabalhe com grandes modelos ML que geralmente têm tamanho GB. O Nuclio também possui integração nativa com o Jupyter e pode implementar automaticamente seus notebooks e modelos Jupyter como funções.
O Nuclio oferece uma boa experiência de desenvolvedor pronta para uso. Ele possui um registrador integrado com suporte de registro estruturado e você pode exportar facilmente seus registros para um serviço de agregação de logs externo.
Se você estiver procurando por uma plataforma sem servidor que não esteja vinculada a um provedor de nuvem específico, o Nuclio vale a pena dar uma olhada.

Endereço: R. Quinze de Novembro, 61 - Centro, Barbacena - MG, 36200-074