59 votes

AWS lambda et la concurrence en Java

Il est connu qu'AWS lambda peut réutiliser les objets créés au préalable par les gestionnaires, et il le fait vraiment (voir FAQ ) :

Q : AWS Lambda réutilisera-t-il les instances de fonction ?

Pour améliorer les performances, AWS Lambda peut choisir de de votre fonction et de la réutiliser pour répondre à une demande ultérieure, plutôt que de créer une nouvelle copie. Votre code ne doit pas supposer que cela se produira toujours. toujours.


La question porte sur Java la concurrence. Si j'ai une classe pour un gestionnaire, disons :

public class MyHandler {
    private Foo foo;
    public void handler(Map<String,String> request, Context context) {
       ...
    }
}

L'accès et l'utilisation de la variable objet seront-ils sûrs pour les threads ? foo ici ou non ?

En d'autres termes : la fonction lambda d'AWS peut-elle utiliser le même objet simultanément pour différents appels ?

EDIT Ma fonction est traitée sur une source basée sur un événement, en particulier elle est invoquée par une méthode API Gateway.

EDIT-2 Ce type de question se pose lorsque l'on souhaite mettre en place une sorte de pool de connexion à des ressources externes, et que l'on souhaite conserver la connexion à la ressource externe en tant que variable objet. Cela fonctionne en fait comme souhaité, mais je crains des problèmes de concurrence.

EDIT-3 Plus précisément, je m'interroge : Les instances des gestionnaires d'AWS lambda peuvent-elles partager un tas commun (mémoire) ou non ? ? Je dois préciser ce détail supplémentaire afin d'éviter que les réponses énumèrent des choses évidentes et connues de tous sur les objets thread-safe de Java.

0 votes

IMO "conserver une instance de votre fonction et la réutiliser" est exactement la même chose que "utiliser le même objet". Et très probablement simultanément.

0 votes

@zapl Cela ne veut pas dire exactement en même temps. Il peut être utilisé comme les threads dans java ExecutorService - ils sont conservés, mais ne sont pas utilisés simultanément

0 votes

Bien sûr, ils pourraient créer de nouvelles instances de gestionnaires par thread ou s'assurer qu'ils ne sont pas utilisés simultanément, mais je ne vois nulle part de mention explicite à ce sujet. D'autre part, il y a des éléments comme "Le code doit être écrit dans un style "sans état" [...] les artefacts ne peuvent pas s'étendre au-delà de la durée de vie de la demande" dans la FAQ.

78voto

Leon Points 20011

Une agence lambda AWS peut-elle utiliser le même objet simultanément pour différents appels ?

Les instances des gestionnaires d'une lambda AWS peuvent-elles partager le même tas (mémoire) ou non ?

Un NON ferme et définitif. Les instances des gestionnaires d'AWS Lambda ne peuvent même pas partager des fichiers (en /tmp ).

Un conteneur AWS Lambda peut pas ne peut être réutilisée pour deux ou plusieurs invocations simultanées d'une fonction Lambda, car cela romprait l'exigence d'isolation :

Q : Comment AWS Lambda isole-t-il mon code ?

Chaque fonction AWS Lambda s'exécute dans son propre environnement isolé avec ses propres ressources et son propre système de fichiers.

La section " Comment AWS Lambda exécute-t-il mon code ? Le modèle de conteneur" dans la description officielle de comment fonctionnent les fonctions lambda États :

Après l'exécution d'une fonction Lambda, AWS Lambda conserve le fichier conteneur pendant un certain temps en prévision d'une autre invocation de la fonction Lambda. Lambda. En fait, le service gèle le conteneur après l'exécution d'une fonction Lambda, et le décongèle pour le réutiliser si AWS Lambda choisit de réutiliser le conteneur lorsque la fonction Lambda est à nouveau invoquée. invoquée à nouveau. Cette approche de réutilisation des conteneurs a les conséquences suivantes implications :

  • Toute déclaration dans le code de votre fonction Lambda reste initialisée, ce qui permet une optimisation supplémentaire lorsque la fonction est invoquée à nouveau. Par exemple, si votre fonction Lambda établit une base de données. au lieu de rétablir la connexion, la connexion d'origine est utilisée dans les invocations suivantes. Vous pouvez ajouter de la logique dans votre code pour vérifier si une connexion existe déjà avant d'en créer une.

  • Chaque conteneur fournit de l'espace disque dans le répertoire /tmp. Le contenu du répertoire Le contenu du répertoire est conservé lorsque le conteneur est gelé. un cache transitoire qui peut être utilisé pour de multiples invocations. Vous pouvez ajouter des fichiers du code supplémentaire pour vérifier si le cache contient les données que vous avez stockées.

  • Processus d'arrière-plan ou callbacks initiés par votre fonction Lambda. qui ne se sont pas terminés à la fin de la fonction reprennent si AWS Lambda choisit de réutiliser le conteneur. Vous devez vous assurer que tous les processus d'arrière-plan ou callbacks (dans le cas de Node.js) dans votre code sont terminés avant que le code ne se termine.

Comme vous pouvez le voir, il n'y a absolument aucun avertissement sur les conditions de course entre plusieurs invocations concurrentes d'une fonction Lambda lorsque l'on essaie de tirer parti de la réutilisation du conteneur. La seule note est "ne vous y fiez pas !".

0 votes

La prime sera attribuée dès que SO le permettra (22 heures restantes)

0voto

Farhan Haider Points 453

Tirer parti de la réutilisation du contexte d'exécution est définitivement une pratique lorsque l'on travaille avec AWS Lambda (Cf. Meilleures pratiques AWS Lambda ). Mais cela ne s'applique pas aux exécutions simultanées, car celles-ci créent un nouveau conteneur et donc un nouveau contexte. En bref, pour les exécutions concurrentes, si un gestionnaire modifie la valeur, les autres ne recevront pas la nouvelle valeur.

0voto

30thh Points 1662

Comme je le vois, il n'y a pas de concurrence les questions relatives à Lambda. Une seule invocation "possède" le conteneur. La deuxième invocation obtiendra un autre conteneur (ou devra peut-être attendre que le premier se libère).

MAIS je n'ai pas trouvé de garantie pour la mémoire Java. visibilité ne peuvent pas se produire. Dans ce cas, les modifications apportées par la première invocation peuvent rester invisibles pour la seconde. Ou bien les modifications de la première invocation seront écrites en mémoire vive après les modifications effectuées par la seconde invocation.

Dans la plupart des cas visibilité sont traitées de la même manière que les concurrence questions. C'est pourquoi je suggère de développer des fonctions Lambda thread-safe (ou synchronisées). Au moins tant qu'AWS ne nous donnera pas la garantie qu'ils font quelque chose de leur côté pour rincer l'état du CPU dans la mémoire après chaque invocation.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X