Resultando em Lambdas menores em tamanho final
Se você não está familiarizado com o início frio (cold start) no contexto do AWS Lambda, leia esta postagem primeiro.
Atualização 24/03/2019: Os testes agora incluem o serverless-webpack.
Quando uma função Lambda do Node.js é iniciada a frio (cold start), várias coisas acontecem:
- o serviço Lambda precisa encontrar um servidor com capacidade suficiente para hospedar o novo contêiner
- o novo contêiner é inicializado
- o ambiente de execução do Node.js é inicializado
- seu módulo/manipulador é inicializado, o que inclui a inicialização de quaisquer variáveis e funções globais que você declara fora da função manipuladora
Se você ativar o rastreamento para uma função Lambda, poderá ver quanto tempo é gasto nessas etapas no X-Ray. Infelizmente, o tempo necessário para inicializar o contêiner e o tempo de execução do Node.js não são registrados como segmentos. Mas você pode calcular a diferença de durações.
Abaixo, o Initialization
refere-se ao tempo necessário para inicializar o módulo/manipulador:
O rastreamento acima é para a função abaixo, que requer o AWS SDK e nada mais. Como você pode ver, este simples require
adicionou 147ms ao início frio.
const AWS = require("aws-sdk");
module.exports.handler = async () => {};
Considere esse o custo de fazer negócios quando sua função precisar interagir com os recursos da AWS. Porém, se você precisar interagir apenas com um serviço (por exemplo, DynamoDB), poderá economizar algum tempo de inicialização com recursos de linha única:
const DynamoDB = require("aws-sdk/clients/dynamodb");
const documentClient = new DynamoDB.DocumentClient();
Acima importamos o cliente DynamoDB diretamente, sem inicializar todo o AWS SDK. Fiz um experimento para ver quanto tempo de inicialização fria você pode economizar com essa alteração simples.
O crédito é dado ao meu colega Justin Caldicott por despertar meu interesse e fazer muitas análises iniciais.
Além do AWS SDK, geralmente também precisamos do XRay SDK e o usamos para instrumentar automaticamente o AWS SDK. Infelizmente, o pacote aws-xray-sdk
também possui algumas bagagens adicionais que não precisamos. Por padrão, ele suporta aplicativos Express.js, MySQL e Postgres. Se você estiver interessado apenas em instrumentar o AWS SDK e módulos http
/https
, precisará apenas do aws-xray-sdk-core
.
Metodologia
Eu testei várias configurações:
- sem SDK da AWS
- importando apenas o cliente DynamoDB
- importando o AWS SDK completo
- importando apenas o XRay SDK (sem AWS SDK)
- importando o XRay SDK e instrumentando o AWS SDK
- importando o XRay SDK Core e instrumentando o AWS SDK
- importando o XRay SDK Core e instrumentando apenas o cliente DynamoDB
Cada uma dessas funções é rastreada pelo X-Ray. Taxa de amostragem (sample rate) definida para 100%, para não perdermos nada. Estamos interessados apenas na duração do segmento Initialization
, pois corresponde ao tempo para inicializar essas dependências.
O caso sem SDK da AWS
é o nosso grupo de controle. Podemos ver quanto tempo cada dependência adicional adiciona à duração de Initialization
.
Para coletar um conjunto de dados estatisticamente significantes, decidi automatizar o processo usando as Funções de Etapa (Step Functions).
- A máquina de estado recebe uma entrada
{ functionName, count }
. - A etapa
SetStartTime
adiciona o registro de data e hora UTC atual ao estado de execução. Isso é necessário, pois precisamos da hora de início do experimento para buscar os traços relevantes do X-Ray. - A etapa
Loop
aciona o número desejado de chamadas frias para a função especificada. Para executar chamadas frias, eu atualizo programaticamente uma variável de ambiente antes de chamar a função. Dessa forma, garanto que toda chamada tenha um começo frio.
- A etapa
Wait30Seconds
garante que todos os rastreamentos sejam publicados no X-Ray antes de tentarmos analisá-los. - A etapa
Analyze
busca todos os rastreamentos relevantes no X-Ray e gera várias estatísticas em torno da duraçãoInitialization
.
Cada configuração é testada em torno de 1000 chamadas frias. Ocasionalmente, os rastreamentos do X-Ray estão incompletos (veja abaixo). Esses rastreamentos incompletos são excluídos na etapa Analyze
.
Onde está o segmento AWS::Lambda:Function?
Cada configuração também é testada com o WebPack (usando o plugin serverless-webpack). Obrigado a Erez Rokah pela sugestão nos comentários.
Os Resultados
Abaixo está a análise do Initialization
para todos os casos de teste:
Observações chave:
- O WebPack melhora o tempo do Initialization` em geral.
- Sem nenhuma dependência, o tempo médio do
Initialization
é de apenas 1,72ms sem o WebPack e 0,97 ms com o WebPack. - Adicionar o AWS SDK como a única dependência adiciona uma média de 245ms sem o WebPack. Isso é bastante significativo. Adicionar WebPack também não melhora significativamente as coisas.
- Exigir apenas o cliente DynamoDB (a alteração de uma linha discutida anteriormente) economiza até 176ms! Em 90% dos casos, a economia foi superior a 130ms. Com o WebPack, a economia é ainda mais dramática.
- O custo de importar o X-Ray SDK é quase o mesmo que o AWS SDK.
- Não há diferença estatisticamente significativa entre o uso do X-Ray SDK completo e do X-Ray SDK Core. Com ou sem WebPack.
Créditos
- Just how expensive is the full AWS SDK?, escrito originalmente por @theburningmonk
Top comments (0)