web-dev-qa-db-fra.com

Quand n'est-il PAS bon d'utiliser des acteurs en akka / erlang?

Je travaille avec akka depuis 7 à 8 mois maintenant tous les jours. Quand j'ai commencé, je travaillais sur des applications et je remarquais que les acteurs seraient utilisés pratiquement n'importe où une fois dans le système d'acteurs pour communiquer entre la plupart des objets. J'ai donc fait de même - faire tourner un autre acteur pour x/y/z.

Il me semble que cela peut être trop aveugle, ajoutant de la complexité là où cela n'est pas nécessaire - mais je ne trouve aucune discussion sur l'utilisation des acteurs par rapport à la logique simple synchrone ou même asynchrone via les futurs. J'ai commencé à réfléchir à ma position après que mon collègue ait mentionné quelque chose de similaire. Plus récemment, j'ai réalisé plusieurs cas où j'ai réfléchi à une tâche, puis j'ai évité de créer un autre acteur car je pouvais obtenir le même résultat en toute sécurité dans une implémentation immuable - par exemple, quelque chose comme obtenir des valeurs de configuration à partir d'une base de données ou d'un fichier quelque part où vous accédez très rarement et attendre que le résultat soit le cas d'utilisation réel.

En particulier, il me semble que dans tous les cas où vous jouez avec un état immuable, les acteurs créent de la complexité et limitent le débit - une fonction pure dans un objet, par exemple, peut être appelée simultanément sans risque avec n'importe quel niveau de concurrence, mais un acteur ne peut traiter qu'un seul message à la fois. L'autre considération est de garer le fil si vous devez attendre le résultat, sauf si vous commencez à utiliser des futures, mais dans les cas où vous n'avez pas à vous soucier de la messagerie asynchrone ou de la mise à l'échelle, il semble qu'il soit exagéré d'employer un acteur.

Donc ma question est - est-ce qu'il y a un mauvais moment pour utiliser des acteurs? Je suis curieux de voir à quoi ressemble Erlang et j'aimerais vraiment avoir les informations des autres. Ou s'il existe des principes concernant l'utilisation des acteurs.

61
JasonG

C'est une question qui m'intéresse et sur laquelle j'ai fait des recherches. Pour d'autres points de vue, voir ceci article de blog de Noel Walsh ou cette question sur Stack Overflow. J'ai quelques opinions que je voudrais offrir:

  • Je pense que Akka, parce qu'il fonctionne avec des messages, encourage un "état d'esprit Push". Souvent, pour la concurrence, je dirais que ce n'est pas ce que vous voulez. La traction est beaucoup plus sûre. Par exemple, un modèle courant pour les systèmes distribués consiste à avoir un ensemble de travailleurs traitant les informations dans une file d'attente . Évidemment c'est possible dans Akka mais cela ne semble pas nécessairement être le première approche que les gens essaient . Akka propose également boîtes aux lettres durables mais encore une fois cela dépend de la façon dont vous les utilisez - une seule file d'attente partagée est beaucoup plus flexible que les files d'attente par travailleur pour équilibrer/réaffecter le travail.
  • Il est facile de penser à remplacer vos classes par des acteurs. En fait, certaines personnes semblent même le préconiser en disant les acteurs ne devraient faire qu'une seule chose . Pris à sa conclusion logique, cela augmente la complexité du code comme le décrit Jason, car si chaque classe est un acteur, cela représente beaucoup de messages supplémentaires et des blocs de réception/envoi. Il est également plus difficile de comprendre et de tester le code car vous perdez la formalité des interfaces - et je ne suis pas convaincu que les commentaires sont une solution à cela . Malgré l'efficacité légendaire d'Akka , je soupçonne que la prolifération des acteurs n'est pas une bonne idée en termes de performances - lorsque nous utilisons des fils Java, nous savons qu'ils sont précieux et les conservons en conséquence.
  • C'est lié au point précédent, mais une autre gêne est la perte d'informations de type que Noel et Pino mettent en évidence, car pour beaucoup d'entre nous, c'est pourquoi nous utilisons Scala plutôt que d'autres langages tels que Python. Il existe des moyens de contourner cela, mais ils sont soit non standard , non recommandé ou expérimental .
  • Enfin, la simultanéité, même si vous avez un état d'esprit "laissez-le planter" , est difficile. Modèles de programmation alternatifs peut aider mais ils ne font pas disparaître les problèmes - ils les changent - c'est pourquoi il est bon de pensez-y formellement . C'est aussi pourquoi le développeur Joe Average recherche des outils prêts à l'emploi tels que RabbitMQ, Storm, Hadoop, Spark, Kafka ou bases de données NoSQL. Akka a quelques outils et composants prédéfinis, ce qui est cool, mais aussi se sent assez bas, donc des éléments communs plus prêts à construire des systèmes distribués aideraient les développeurs et garantiraient que les systèmes sont bien construits.

Comme Jason, je suis impatient d'entendre les idées des autres ici. Comment puis-je résoudre certains des problèmes ci-dessus et mieux utiliser Akka?

23
Mark Butler

Il convient de considérer à quoi sert le modèle d'acteur: le modèle d'acteur est

  1. un modèle de simultanéité
  2. qui évite l'accès simultané à un état mutable
  3. utiliser des mécanismes de communication asynchrones pour fournir la concurrence.

Cela est précieux car l'utilisation de l'état partagé à partir de plusieurs threads devient très difficile, surtout lorsqu'il existe des relations entre différents composants de l'état partagé qui doivent être synchronisés. Cependant, si vous avez des composants de domaine dans lesquels:

  • Vous n'autorisez pas la concurrence, OU
  • Vous n'autorisez pas l'état mutable (comme dans la programmation fonctionnelle), OU
  • Vous devez compter sur un mécanisme de communication synchrone,

alors le modèle d'acteur n'apportera pas beaucoup (le cas échéant) d'avantages.

J'espère que cela pourra aider.

21
Aidan Cully

Votre intuition est correcte, à mon humble avis. Utiliser des acteurs partout, c'est comme avoir le marteau proverbial et ne voir que des clous.

La meilleure pratique d'Erlang consiste à utiliser des processus/acteurs pour toutes les activités qui se déroulent simultanément. Autrement dit, comme dans la vraie vie. Parfois, il est difficile de trouver la bonne granularité, mais la plupart du temps, vous le savez simplement en regardant le domaine modélisé et en utilisant un peu de bon sens. J'ai bien peur de ne pas avoir de meilleure méthode que cela, mais j'espère que ça aide.

12
Vlad Dumitrescu

Dans l'ordre de messagerie d'entrée/sortie:

J'ai récemment rencontré une application basée sur akka où le modèle d'acteur a effectivement causé des problèmes de concurrence, un modèle plus simple aurait suffi mieux sous charge.

Le problème était que les messages entrants se déplaçaient dans différentes "voies" (à travers différents chemins d'acteurs) mais le code supposait que les messages arriveraient à leur destination finale dans le même ordre qu'ils sont arrivés. Tant que les données arrivaient avec des intervalles suffisamment grands, cela fonctionnait car il n'y aurait qu'un seul message conflictuel se précipitant vers la destination. Lorsque les intervalles ont diminué, ils ont commencé à arriver hors service et à provoquer un comportement étrange.

Le problème aurait pu être résolu correctement avec un peu moins d'acteurs, mais c'est une erreur facile à faire en les surutilisant.

0
DHa