Article original : Just how expensive is the full AWS SDK?

Par Yan Cui

Si vous n'êtes pas familier avec le fonctionnement du cold start dans le contexte d'AWS Lambda, lisez d'abord cet article.

Lorsqu'une fonction Lambda Node.js démarre à froid, plusieurs choses se produisent :

  • le service Lambda doit trouver un serveur avec suffisamment de capacité pour héberger le nouveau conteneur
  • le nouveau conteneur est initialisé
  • le runtime Node.js est initialisé
  • votre module de gestionnaire est initialisé, ce qui inclut l'initialisation de toutes les variables globales et fonctions que vous déclarez en dehors de la fonction de gestionnaire

Si vous activez le traçage actif pour une fonction Lambda, vous pourrez voir combien de temps est consacré à ces étapes dans X-Ray. Malheureusement, le temps nécessaire pour initialiser le conteneur et le runtime Node.js n'est pas enregistré en tant que segments. Mais vous pouvez le déduire de la différence de durée.

Ici, Initialization fait référence au temps nécessaire pour initialiser le module de gestionnaire.

Image

La trace ci-dessus est pour la fonction ci-dessous, qui nécessite le SDK AWS et rien d'autre. Comme vous pouvez le voir, ce simple require a ajouté 147 ms au cold start.

const AWS = require('aws-sdk')module.exports.handler = async () => {}

Considérez cela comme le coût de faire des affaires lorsque votre fonction doit interagir avec des ressources AWS. Mais, si vous n'avez besoin d'interagir qu'avec un seul service (par exemple DynamoDB), vous pouvez économiser un peu de temps d'initialisation avec cette ligne unique.

const DynamoDB = require('aws-sdk/clients/dynamodb') const documentClient = new DynamoDB.DocumentClient()

Cela nécessite le client DynamoDB directement sans initialiser tout le SDK AWS. J'ai mené une expérience pour voir combien de temps de cold start vous pouvez économiser avec ce simple changement.

Le mérite revient à mon collègue Justin Caldicott pour avoir piqué ma curiosité et fait une grande partie de l'analyse initiale.

En plus du SDK AWS, nous nécessitons souvent le SDK XRay et l'utilisons pour auto-instrumenter le SDK AWS. Malheureusement, le package aws-xray-sdk a également quelques bagages supplémentaires dont nous n'avons pas besoin. Par défaut, il supporte les applications Express.js, MySQL et Postgres. Si vous êtes seulement intéressé par l'instrumentation du SDK AWS et des modules http/https, alors vous n'avez besoin que du aws-xray-sdk-core.

Image

Méthodologie

J'ai testé plusieurs configurations :

Chacune de ces fonctions est tracée par X-Ray. Le taux d'échantillonnage est fixé à 100 %, afin de ne rien manquer. Nous ne nous intéressons qu'à la durée du segment Initialization, car il correspond au temps nécessaire pour initialiser ces dépendances.

Image

Le cas no AWS SDK est notre groupe témoin. Nous pouvons voir combien de temps chaque dépendance supplémentaire ajoute à notre durée d'Initialization.

Pour collecter un ensemble de données statistiquement significatif, j'ai décidé d'automatiser le processus en utilisant Step Functions.

Image

  • La machine d'état prend une entrée { functionName, count }.
  • L'étape SetStartTime ajoute l'horodatage UTC actuel à l'état d'exécution. Cela est nécessaire car nous avons besoin de l'heure de début de l'expérience pour récupérer les traces pertinentes de X-Ray.
  • L'étape Loop déclenche le nombre souhaité de cold starts pour la fonction spécifiée. Pour déclencher des cold starts, je mets à jour programmatiquement une variable d'environnement avant d'invoquer la fonction. De cette manière, je m'assure que chaque invocation est un cold start.

Image

  • L'étape Wait30Seconds s'assure que toutes les traces sont publiées vers XRay avant que nous tentions de les analyser.
  • L'étape Analyze récupère toutes les traces pertinentes dans XRay et produit plusieurs statistiques autour de la durée d'Initialization.

Chaque configuration est testée sur 1000 cold starts. Parfois, les traces XRay sont incomplètes (voir ci-dessous). Ces traces incomplètes sont exclues dans l'étape Analyze.

Image où est le segment AWS::Lambda:Function ?

Chaque configuration est également testée avec WebPack (en utilisant le plugin serverless-webpack). Merci à Erez Rokah pour la suggestion.

Les Résultats

Voici les temps d'Initialization pour tous les cas de test.

Image

Image

Observations clés :

  • WebPack améliore le temps d'Initialization dans tous les cas.
  • Sans aucune dépendance, le temps d'Initialization moyenne seulement 1,72 ms sans WebPack et 0,97 ms avec WebPack.
  • L'ajout du SDK AWS comme seule dépendance ajoute en moyenne 245 ms sans WebPack. Cela est assez significatif. L'ajout de WebPack n'améliore pas significativement les choses non plus.
  • En nécessitant uniquement le client DynamoDB (le changement en une ligne discuté précédemment), on économise jusqu'à 176 ms ! Dans 90 % des cas, l'économie était de plus de 130 ms. Avec WebPack, l'économie est encore plus dramatique.
  • Le coût de la nécessité du SDK XRay est à peu près le même que celui du SDK AWS.
  • Il n'y a pas de différence statistiquement significative entre l'utilisation du SDK XRay complet et du SDK XRay Core. Avec ou sans WebPack.

Initialement publié sur theburningmonk.com le 23 mars 2019.