Utilisation AWS Lambda des fonctions dans Amazon Neptune - Amazon Neptune

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Utilisation AWS Lambda des fonctions dans Amazon Neptune

AWS Lambda les fonctions ont de nombreuses utilisations dans les applications Amazon Neptune. Nous fournissons ici des conseils généraux sur l'utilisation des fonctions Lambda avec l'un des pilotes et variantes de langage Greminda les plus courants, ainsi que des exemples spécifiques de fonctions Lambda écrites en Java et Python. JavaScript

Note

La meilleure façon d'utiliser les fonctions Lambda avec Neptune a changé avec les récentes versions du moteur. Neptune avait l'habitude de laisser les connexions inactives ouvertes longtemps après le recyclage d'un contexte d'exécution Lambda, ce qui pouvait entraîner une fuite de ressources sur le serveur. Pour pallier ce problème, nous avions l'habitude de recommander l'ouverture et la fermeture d'une connexion à chaque invocation Lambda. À partir de la version 1.0.3.0 du moteur, le délai d'inactivité des connexions a toutefois été réduit afin que les connexions ne provoquent plus de fuite après le recyclage d'un contexte d'exécution Lambda inactif. Nous recommandons donc désormais d'utiliser une connexion unique pendant toute la durée du contexte d'exécution. Cela devrait inclure une certaine gestion des erreurs et un back-off-and-retry code standard pour gérer les fermetures inattendues de connexions.

Gestion des WebSocket connexions G705 dans les fonctions AWS Lambda

Si vous utilisez une variante du langage Gremlin pour interroger Neptune, le pilote se connecte à la base de données par le biais d'une connexion. WebSocket WebSockets sont conçus pour prendre en charge des scénarios de connexion client-serveur de longue durée. AWS Lambda, d'autre part, est conçu pour soutenir les exécutions apatrides et de courte durée. Cette différence de philosophie de conception peut entraîner des problèmes inattendus lors de l'utilisation de Lambda pour interroger Neptune.

Une AWS Lambda fonction s'exécute dans un contexte d'exécution qui l'isole des autres fonctions. Le contexte d'exécution est créé la première fois que la fonction est invoquée et peut être réutilisé pour les invocations ultérieures de la même fonction.

Cependant, aucun contexte d'exécution n'est jamais utilisé pour gérer plusieurs invocations simultanées de la fonction. Si la fonction est invoquée simultanément par plusieurs clients, Lambda crée un contexte d'exécution supplémentaire pour chaque instance de cette fonction. Tous ces nouveaux contextes d'exécution peuvent à leur tour être réutilisés pour les invocation suivantes de la fonction.

À un moment donné, Lambda recycle les contextes d'exécution, en particulier s'ils sont inactifs depuis un certain temps. AWS Lambda expose le cycle de vie du contexte d'exécution, y compris les Shutdown phases Invoke etInit, via les extensions Lambda. À l'aide de ces extensions, vous pouvez écrire du code qui nettoie les ressources externes telles que les connexions aux bases de données lorsque le contexte d'exécution est recyclé.

Une bonne pratique courante consiste à ouvrir la connexion à la base de données en dehors de la fonction du gestionnaire Lambda afin qu'elle puisse être réutilisée à chaque appel du gestionnaire. Si la connexion à la base de données est interrompue à un moment donné, vous pouvez vous reconnecter depuis le gestionnaire. Cependant, cette approche présente un risque de fuite de connexion. Si une connexion inactive reste ouverte longtemps après la destruction d'un contexte d'exécution, les scénarios d'invocation Lambda intermittents ou en paquets peuvent progressivement provoquer des fuites de connexions et épuiser les ressources de la base de données.

Les limites et délais de connexion de Neptune ont changé avec les nouvelles versions du moteur. Auparavant, chaque instance prenait en charge jusqu'à 60 000 WebSocket connexions. Désormais, le nombre maximum de WebSocket connexions simultanées par instance Neptune varie en fonction du type d'instance.

De plus, à partir de la version 1.0.3.0 du moteur, Neptune a réduit le délai d'inactivité des connexions d'une heure à environ 20 minutes. Si un client ne ferme pas la connexion, celle-ci est automatiquement fermée après un délai d'inactivité de 20 à 25 minutes. AWS Lambda ne documente pas les durées de vie des contextes d'exécution, mais les expériences montrent que le nouveau délai de connexion Neptune correspond bien aux délais d'expiration des contextes d'exécution Lambda inactifs. Au moment où un contexte d'exécution inactif est recyclé, il est très probable que sa connexion ait déjà été fermée par Neptune ou qu'elle le soit peu après.

Recommandations d'utilisation AWS Lambda avec Amazon Neptune G705

Nous recommandons désormais d'utiliser une seule source de connexion et de traversée de graphes pendant toute la durée de vie d'un contexte d'exécution Lambda, plutôt qu'une pour chaque invocation de fonction (chaque invocation de fonction ne gère qu'une seule demande client). Comme les demandes simultanées des clients sont traitées par différentes instances de fonction exécutées dans des contextes d'exécution distincts, il n'est pas nécessaire de gérer un pool de connexions pour traiter les demandes simultanées au sein d'une instance de fonction. Si le pilote Gremlin que vous utilisez possède un pool de connexions, configurez-le pour n'utiliser qu'une seule connexion.

Pour gérer les échecs de connexion, utilisez une logique de nouvelle tentative pour chaque requête. Même si l'objectif est de maintenir une connexion unique pendant toute la durée de vie d'un contexte d'exécution, des événements réseau inattendus peuvent entraîner une interruption abrupte de cette connexion. Ces échecs de connexion se traduisent par des erreurs différentes selon le pilote que vous utilisez. Vous devez coder la fonction Lambda pour gérer ces problèmes de connexion et tenter une reconnexion si nécessaire.

Certains pilotes Gremlin gèrent automatiquement les reconnexions. Le pilote Java, par exemple, tente automatiquement de rétablir la connectivité à Neptune pour le compte du code client. Avec ce pilote, le code de la fonction n'a qu'à exécuter un backoff et une nouvelle tentative de la requête. Les pilotes Python JavaScript et Python, en revanche, n'implémentent aucune logique de reconnexion automatique. Ainsi, avec ces pilotes, votre code de fonction doit essayer de se reconnecter après avoir reculé, et ne réessayer la requête qu'une fois la connexion rétablie.

Les exemples de code présentés ici incluent la logique de reconnexion au lieu de supposer que le client s'en occupe.

Recommandations pour l'utilisation des demandes d'écriture Gremlin dans Lambda

Si votre fonction Lambda modifie les données du graphe, envisagez d'adopter une back-off-and-retry stratégie pour gérer les exceptions suivantes :

  • ConcurrentModificationException : la sémantique des transactions Neptune signifie que les demandes d'écriture échouent parfois avec une exception ConcurrentModificationException. Dans ces situations, essayez un mécanisme de back-off-based nouvelle tentative exponentielle.

  • ReadOnlyViolationException : comme la topologie du cluster peut changer à tout moment en raison d'événements planifiés ou imprévus, les responsabilités d'écriture peuvent être transférées d'une instance du cluster à une autre. Si le code de la fonction tente d'envoyer une demande d'écriture à une instance qui n'est plus l'instance principale (d'enregistreur), cette demande échouera avec une exception ReadOnlyViolationException. Dans ce cas, fermez la connexion existante, reconnectez-vous au point de terminaison du cluster, puis retentez la demande.

De plus, si vous utilisez une back-off-and-retry stratégie pour gérer les problèmes de demande d'écriture, envisagez d'implémenter des requêtes idempotentes pour les demandes de création et de mise à jour (par exemple, en utilisant fold () .coalesce () .unfold ().

Recommandations pour l'utilisation des demandes de lecture Gremlin dans Lambda

Si votre cluster possède un ou plusieurs réplicas en lecture, il est conseillé d'équilibrer les demandes de lecture entre ces réplicas. L'une des options consiste à utiliser le point de terminaison du lecteur. Le point de terminaison du lecteur équilibre les connexions entre les réplicas, même si la topologie du cluster change lorsque vous ajoutez ou supprimez des réplicas, ou lorsque vous promouvez un réplica pour en faire la nouvelle instance principale.

Cependant, l'utilisation du point de terminaison du lecteur peut entraîner une utilisation inégale des ressources du cluster dans certaines circonstances. Le point de terminaison du lecteur fonctionne en modifiant périodiquement l'hôte vers DNS lequel pointe l'entrée. Si un client ouvre de nombreuses connexions avant que l'DNSentrée ne soit modifiée, toutes les demandes de connexion sont envoyées à une seule instance Neptune. Cela peut être le cas dans un scénario Lambda à haut débit dans lequel un grand nombre de demandes simultanées adressées à la fonction Lambda entraîne la création de plusieurs contextes d'exécution, chacun avec sa propre connexion. Si ces connexions sont toutes créées presque simultanément, elles sont susceptibles de toutes pointer vers le même réplica du cluster et de continuer à pointer vers lui jusqu'à ce que les contextes d'exécution soient recyclés.

L'un des moyens de répartir les demandes entre les instances consiste à configurer la fonction Lambda pour qu'elle se connecte à un point de terminaison d'instance, choisi au hasard dans une liste de points de terminaison d'instance de réplica, plutôt qu'au point de terminaison du lecteur. L'inconvénient de cette approche est qu'elle nécessite que le code Lambda gère les modifications de la topologie du cluster en surveillant le cluster et en mettant à jour la liste des points de terminaison chaque fois que l'appartenance au cluster change.

Si vous écrivez une fonction Lambda Java qui doit équilibrer les demandes de lecture entre les instances de votre cluster, vous pouvez utiliser le client Gremlin pour Amazon Neptune, un client Java Gremlin qui connaît la topologie de votre cluster et qui répartit équitablement les connexions et les demandes entre un ensemble d'instances d'un cluster Neptune. Ce billet de blog inclut un exemple de fonction Lambda Java qui utilise le client Gremlin pour Amazon Neptune.

Facteurs susceptibles de ralentir les démarrages à froid des fonctions Lambda Neptune Gremlin

La première fois qu'une AWS Lambda fonction est invoquée, on parle de démarrage à froid. Plusieurs facteurs peuvent augmenter la latence d'un démarrage à froid :

  • Assurez-vous d'affecter suffisamment de mémoire à la fonction Lambda.   — La compilation pendant un démarrage à froid peut être nettement plus lente pour une fonction Lambda qu'elle ne le serait lorsqu'elle est activée, EC2 car elle AWS Lambda alloue les CPU cycles de manière linéaire proportionnellement à la mémoire que vous attribuez à la fonction. Avec 1 769 Mo de mémoire, une fonction reçoit l'équivalent d'un v complet CPU (une v CPU seconde de crédits par seconde). L'impact du fait de ne pas affecter suffisamment de mémoire pour recevoir des CPU cycles adéquats est particulièrement prononcé pour les fonctions Lambda volumineuses écrites en Java.

  • Sachez que l'activation de l'authentification de IAM base de données peut ralentir un démarrage à froid. AWS Identity and Access Management (IAM) L'authentification de base de données peut également ralentir les démarrages à froid, en particulier si la fonction Lambda doit générer une nouvelle clé de signature. Cette latence n'affecte que le démarrage à froid et non les demandes suivantes, car une fois que l'IAMauthentification de base de données a établi les informations d'identification de connexion, Neptune ne fait que valider périodiquement qu'elles sont toujours valides.