This content originally appeared on DEV Community and was authored by Paulo Lôbo
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 pra pensar que estamos sendo cada vez mais exigidos com relação a performance das nossas aplicações?
A cada dia somos provocados a torná-las mais rápidas e com isso, somos levados a avaliar soluções e arquiteturas que nos possibilita alcançarmos o 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 pelo time da aws.
No momento ele é experimental e há esforços para tentar 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 do é 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 fazer 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 será 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:
Agora, vamos criar a função com o LLRT JS. Optei por utilizar a opção de layer.
E adicione essa layer a função LLRT JS criada:
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;
};
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;
};
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:
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 vermos a flexibilidade do JS e ver o quanto ele pode e ainda tem a nos entregar.
Eu espero que tenha gostado e te ajudado a melhorar a compreensão de algo ou até mesmo aberto caminhos para novos conhecimentos. Conto com você nas críticas e sugestões para irmos melhorando o conteúdo e mantendo sempre atualizado para a comunidade.
This content originally appeared on DEV Community and was authored by Paulo Lôbo
Paulo Lôbo | Sciencx (2024-08-20T12:42:53+00:00) Lamba LLRT. Retrieved from https://www.scien.cx/2024/08/20/lamba-llrt/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.