Logo

dev-resources.site

for different kinds of informations.

Lamba LLRT(Low Latency Runtime Javascript)

Published at
8/20/2024
Categories
javascript
awslambda
node
lamballrt
Author
paulo_loboneto_80163ca4e
Author
24 person written this
paulo_loboneto_80163ca4e
open
Lamba LLRT(Low Latency Runtime Javascript)

Aviso: todo e qualquer conteúdo postado é com objetivo de relembrar ou manter os meus conhecimentos e espero que possa te ajudar na sua caminhada pelo aprendizado também.
Esse post é vivo e será atualizado periodicamente.
Caso você encontre alguma falha ou perceba que falta algo, me ajude a melhorar :)


Você já parou para pensar que estamos sendo cada vez mais exigidos em relação à performance das nossas aplicações? A cada dia, somos desafiados a torná-las mais rápidas, e, com isso, somos levados a avaliar soluções e arquiteturas que nos possibilitem alcançar esse resultado.


Portanto a ideia é trazer um post curto, informando sobre uma nova evolução que pode nos ajudar a ter um aumento considerável de performance em aplicações serverless no AWS Lambda. Essa solução é o LLRT Javascript.

LLRT Javascript(Low Latency Runtime Javascript)

Um novo runtime JavaScript está sendo desenvolvido pela equipe da AWS. No momento, ele é experimental, e há esforços para lançar uma versão estável até o final de 2024

veja a descrição que a AWS apresenta:

LLRT (Low Latency Runtime) is a lightweight JavaScript runtime designed to address the growing demand for fast and efficient Serverless applications. LLRT offers up to over 10x faster startup and up to 2x overall lower cost compared to other JavaScript runtimes running on AWS Lambda
It's built in Rust, utilizing QuickJS as JavaScript engine, ensuring efficient memory usage and swift startup.

Veja que eles pretendem entregar algo até 10x mais rápido do que outros runtimes JS.

Toda essa construção é feita utilizando o Rust, que é uma linguagem com alto poder de desempenho e o QuickJS, que é um motor de JavaScript leve e de alto desempenho, projetado para ser pequeno, eficiente e compatível com a especificação ECMAScript mais recente, incluindo recursos modernos como classes, async/await, e módulos. Além disso, é utilizada uma abordagem que não usa JIT. Com isso, ao invés de alocar recursos para compilação Just-In-Time, conserva esses recursos para a execução de tarefas do próprio código.

Mas calma que nem tudo são flores, são tradeoffs(trocadilho horrível, eu sei rsrs).
Portanto, há alguns pontos importantes para se avaliar antes de pensar em adotar o LLRT JS. Veja o que a AWS informa:

There are many cases where LLRT shows notable performance drawbacks compared with JIT-powered runtimes, such as large data processing, Monte Carlo simulations or performing tasks with hundreds of thousands or millions of iterations. LLRT is most effective when applied to smaller Serverless functions dedicated to tasks such as data transformation, real time processing, AWS service integrations, authorization, validation etc. It is designed to complement existing components rather than serve as a comprehensive replacement for everything. Notably, given its supported APIs are based on Node.js specification, transitioning back to alternative solutions requires minimal code adjustments.

Além disso, a ideia é que o LLRT JS não seja um substituto para o node.js e nem nunca será.

Veja:

LLRT only support a fraction of the Node.js APIs. It is NOT a drop in replacement for Node.js, nor will it ever be. Below is a high level overview of partially supported APIs and modules. For more details consult the API documentation.


Testes Avaliativos

Levando em consideração a aplicabilidade que foi citada pela própria AWS, vamos realizar dois testes para avaliar e comparar o LLRT com o NodeJS. Um dos testes será para o cálculo de números primos e o outro para uma chamada simples de API.

Porque utilizar o cálculo de números primos?
A resposta é que o alto processamento requerido para identificar números primos resulta da necessidade de realizar muitas operações matemáticas(divisões) para verificar a primalidade, da distribuição imprevisível dos primos, e da complexidade crescente com o tamanho dos números. Esses fatores combinam-se para tornar a verificação de primalidade e a busca por números primos uma tarefa computacionalmente intensa, especialmente em grandes escalas.


Mãos na massa então...

Crie a primeira função lambda com nodejs:

Image description

Agora, vamos criar a função com o LLRT JS. Optei por utilizar a opção de layer.

Crie a layer:
Image description

Depois crie a função:
Image description

E adicione essa layer a função LLRT JS criada:
Image description

Para o teste de números primos, vamos usar o seguinte código:

let isLambdaWarm = false
export async function handler(event)  {

    const limit = event.limit || 100000;  // Defina um limite alto para aumentar a complexidade
    const primes = [];
    const startTime = Date.now()
    const isPrime = (num) => {
        if (num <= 1) return false;
        if (num <= 3) return true;
        if (num % 2 === 0 || num % 3 === 0) return false;
        for (let i = 5; i * i <= num; i += 6) {
            if (num % i === 0 || num % (i + 2) === 0) return false;
        }
        return true;
    };

    for (let i = 2; i <= limit; i++) {
        if (isPrime(i)) {
            primes.push(i);
        }
    }

  const endTime = Date.now() - startTime

    const response = {
        statusCode: 200,
        body: JSON.stringify({
            executionTime: `${endTime} ms`,
            isLambdaWarm: `${isLambdaWarm}`
        }),
    };


    if (!isLambdaWarm) { 
        isLambdaWarm = true
    }

    return response;
};


Enter fullscreen mode Exit fullscreen mode

E para o teste de API, vamos usar o código abaixo:

let isLambdaWarm = false
export async function handler(event) {

  const url = event.url || 'https://jsonplaceholder.typicode.com/posts/1'
  console.log('starting fetch url', { url })
  const startTime = Date.now()

  let resp;
  try {
    const response = await fetch(url)
    const data = await response.json()
    const endTime = Date.now() - startTime
    resp = {
      statusCode: 200,
      body: JSON.stringify({
        executionTime: `${endTime} ms`,
        isLambdaWarm: `${isLambdaWarm}`
      }),
    }
  }
  catch (error) {
    resp = {
      statusCode: 500,
      body: JSON.stringify({
        message: 'Error fetching data',
        error: error.message,
      }),
    }
  }

  if (!isLambdaWarm) {
    isLambdaWarm = true
  }

  return resp;
};

Enter fullscreen mode Exit fullscreen mode

Resultados dos testes

O objetivo é mais educacional aqui, portanto nossa amostra para cada teste é constituído de 15 dados em warm start e 1 de cold start.

Consumo de memória

LLRT JS - para ambos os testes, houve o consumo da mesma quantidade de memória: 23mb.

NodeJS - para o teste de números primos, o nodejs começou consumindo 69mb e indo até 106mb.
Já para o teste de API, o mínimo foi 86mb e o máximo com 106mb.

Tempo de execução
após a remoção dos outliers, esse foi o resultado:

Image description

Image description

Relatório final

Consumo de memória - para o consumo de memória foi observado que o LLRT fez o melhor uso do recurso disponível se comparado ao nodejs.

Performance - percebemos que no cenário de alto processamento, o node manteve uma performance bem superior ao LLRT, tanto no cold start quanto warm start.
Para o cenário de menor processamento, o LLRT obteve uma certa vantagem, principalmente no cold start.

Vamos, então, aguardar os resultados finais e esperar que possamos ter ainda mais melhorias significativas. Mas é muito bom ver a flexibilidade do JavaScript e perceber o quanto ele pode e ainda tem a nos oferecer.


Espero que tenha gostado e que isso tenha ajudado a melhorar sua compreensão ou até mesmo aberto caminhos para novos conhecimentos. Conto com você para críticas e sugestões, para que possamos melhorar o conteúdo e mantê-lo sempre atualizado para a comunidade.

awslambda Article's
30 articles in total
Favicon
Build a Crypto Price Alert System with Telegram and AWS Lambda
Favicon
Leveraging Docker with AWS Lambda for Custom Runtimes and Large Deployments
Favicon
Docker for Serverless: Customizing Functions and Scaling Flexibly
Favicon
Inventory Management with AWS Lambda λ
Favicon
Lambda Power Tuning: Una comparativa entre arquitecturas x86_64 y arm64
Favicon
A Beginners Guide to Serverless API Gateway Authentication with Lambda Authorizer
Favicon
Serverless Functions: Unlocking the Power of AWS Lambda, Azure Functions, and More
Favicon
Mastering Serverless and Event-Driven Architectures with AWS: Innovations in Lambda, EventBridge, and Beyond
Favicon
Parse UserParameters sent from AWS CodePipeline to AWS Lambda in Go
Favicon
Leveraging Amazon Connect for Real-Time Incident Response Calls
Favicon
Lambda Code Execution Freeze/Thaw
Favicon
Efficiently Delete Inactive User Data Using TypeScript and AWS Lambda
Favicon
Unlocking Serverless: Build Your First Python AWS Lambda Function
Favicon
Lamba LLRT(Low Latency Runtime Javascript)
Favicon
Building Scalable Microservices with AWS Lambda and Serverless
Favicon
Serverless Architecture Best Practices
Favicon
Deep Dive on Writing and Reading Data to DynamoDB Table from Lambda Functions Using AWS Cloud Map Service Discovery
Favicon
AWS Lambda in Deno or Bun
Favicon
Lambda extension to cache SSM and Secrets Values for PHP Lambda on CDK
Favicon
Create a Fast Node.js Serverless Backend Using AWS Lambda and DynamoDB
Favicon
30-day Learning Challenge: Day 2— Learning AWS S3
Favicon
AWS Lambda Functions Failure Management
Favicon
Understanding Load Balancers: How They Work, Types, Algorithms, and Use Cases
Favicon
How to Deploy Dart Functions to AWS Lambda
Favicon
Using Custom Authorization - Request based for AWS Lambda
Favicon
How to generate a presigned url to upload images to S3
Favicon
Create an AppSync API using Terraform
Favicon
Creating a Cognito Trigger using CDK and TypeScript
Favicon
API Gateway REST API with Lambda Integration
Favicon
AWS Lambda Runtime debate

Featured ones: