web-dev-qa-db-fra.com

Comprendre quand utiliser des services avec état et quand s'appuyer sur la persistance externe dans Azure Service Fabric

Je passe mes soirées à évaluer Azure Service Fabric en remplacement de notre pile WebApps/CloudServices actuelle, et je ne suis pas certain de savoir comment décider quand les services/acteurs avec état devraient être des acteurs avec état et quand ils devraient être des acteurs apatrides avec état à persistance externe (Azure SQL, Azure Storage et DocumentDB). Je sais que c'est un produit assez nouveau (pour le grand public au moins), donc il n'y a probablement pas encore beaucoup de meilleures pratiques à ce sujet, mais j'ai lu la plupart des documentation made disponible par Microsoft sans trouver de réponse définitive à cela.

Le domaine de problème actuel que j'approche est notre magasin d'événements; certaines parties de nos applications sont basées sur le sourcing d'événements et le CQRS, et j'évalue comment déplacer ce magasin d'événements vers la plate-forme Service Fabric. Le magasin d'événements va contenir beaucoup de données chronologiques, et comme c'est notre seule source de vérité pour les données qui y sont persistantes, il doit être cohérent, répliqué et stocké dans une forme de stockage durable.

Une façon dont j'ai envisagé de le faire est avec un acteur dynamique "EventStream"; chaque instance d'un agrégat utilisant le sourcing d'événements stocke ses événements dans un flux isolé. Cela signifie que l'acteur avec état pourrait suivre tous les événements pour son propre flux, et j'aurais répondu à mes exigences quant à la façon dont les données sont stockées (transactionnelles, répliquées et durables). Cependant, certains flux peuvent devenir très importants (des centaines de milliers, voire des millions d'événements), et c'est là que je commence à être incertain. Le fait d'avoir un acteur avec une grande quantité d'état aura, j'imagine, un impact sur les performances du système lorsque ces grands modèles de données doivent être sérialisés ou désérialisés à partir du disque.

Une autre option consiste à garder ces acteurs sans état et à les faire simplement lire leurs données à partir d'un stockage externe comme Azure SQL - ou simplement à utiliser des services sans état au lieu d'acteurs.

Fondamentalement, quand la quantité d'état pour un acteur/service est-elle "trop" et vous devriez commencer à envisager d'autres façons de gérer l'état?

En outre, cette section de la documentation Service Fabric Actors design pattern: Some anti-patterns me laisse un peu perplexe:

Traitez Azure Service Fabric Actors comme un système transactionnel. Azure Service Fabric Actors n'est pas un système basé sur la validation en deux phases offrant ACID. Si nous n'implémentons pas la persistance facultative et que la machine sur laquelle s'exécute l'acteur meurt, son état actuel l'accompagnera. L'acteur arrivera sur un autre nœud très rapidement, mais à moins que nous n'ayons implémenté la persistance du support, l'état sera parti. Cependant, entre la multiplication des tentatives, le filtrage des doublons et/ou la conception idempotente, vous pouvez atteindre un niveau élevé de fiabilité et de cohérence.

Que signifie "si nous n'implémentons pas la persistance facultative"? J'avais l'impression que tant que votre transaction modifiant l'état réussissait, vos données étaient conservées dans un stockage durable et répliquées sur au moins un sous-ensemble des répliques. Ce paragraphe me laisse me demander s'il y a des situations où l'état au sein de mes acteurs/services va se perdre, et si c'est quelque chose dont j'ai besoin pour me gérer. L'impression que j'ai eue du modèle avec état dans d'autres parties de la documentation semble contrecarrer cette affirmation.

58
Trond Nordheim

Une option que vous avez consiste à conserver `` une partie '' de l'état dans l'acteur (disons ce qui pourrait être considéré comme des données chaudes qui doivent être rapidement disponibles) et stocker tout le reste sur une infrastructure de stockage `` traditionnelle '' telle que SQL Azure , DocDB, .... Il est difficile d'avoir une règle générale sur trop d'état local mais, peut-être, cela aide à penser aux données chaudes vs froides. Les acteurs fiables offrent également la possibilité de personnaliser StateProvider afin que vous puissiez également envisager de mettre en œuvre un StateProvider personnalisé (en implémentant IActorStateProvider) avec les politiques spécifiques dont vous avez besoin pour être plus efficace avec les exigences que vous avez en termes de quantité de données, de latence , la fiabilité, etc.

À propos des anti-modèles: la note concerne davantage la mise en œuvre de transactions entre plusieurs acteurs. Reliable Actors offre une garantie complète sur la fiabilité des données dans les limites d'un acteur. En raison de la nature distribuée et faiblement couplée du modèle Actor, la mise en œuvre de transactions impliquant plusieurs acteurs n'est pas une tâche triviale. Si les transactions "distribuées" sont une exigence forte, le modèle de programmation Reliable Services est probablement mieux adapté.

24
clca

Je sais que cela a été répondu, mais je me suis récemment retrouvé dans la même situation difficile avec un système CQRS/ES et voici comment je l'ai fait:

  1. Chaque agrégat était un acteur avec uniquement l'état actuel stocké.
  2. Sur une commande, l'agrégat entraînerait un changement d'état et déclencherait un événement.
  3. Les événements eux-mêmes étaient stockés dans un DocDb.
  4. Lors de l'activation, les instances AggregateActor lisent les événements de DocDb s'ils sont disponibles pour recréer son état. Ceci n'est évidemment effectué qu'une seule fois par activation d'acteur. Cela a pris en charge le cas où une instance d'acteur est migrée d'un nœud à un autre.
5
Raghu

Pour répondre à la question sedcondaire de @ Trond qui est, " Qu'est-ce que" si nous n'implémentons pas la persistance facultative "indique ici?"

Un acteur est toujours un service avec état, et son état peut être configuré, à l'aide d'un attribut sur la classe d'acteur, pour fonctionner dans l'un des trois modes:

  1. Persisté. L'état est répliqué sur toutes les instances de réplicas et également écrit sur le disque. Cet état est conservé même si toutes les répliques sont arrêtées.
  2. Volatil. L'état est répliqué sur toutes les instances de réplique, en mémoire uniquement. Cela signifie que tant qu'une instance de réplique est active, l'état est conservé. Mais lorsque toutes les répliques sont arrêtées, l'état est perdu et ne peut pas être récupéré après leur redémarrage.
  3. Aucune persistance. L'état n'est pas répliqué sur d'autres instances de réplicas, ni sur le disque. Cela fournit la moindre protection de l'État.

Une discussion complète sur le sujet peut être trouvée dans la documentation Microsoft

2
Phillip Ngan