Ignite Service Grid - Redémarrer

Le 26 février, nous avons organisé une rencontre Apache Ignite GreenSource, au cours de laquelle les contributeurs au projet open source ont pris la parole. Apache Ignite. Un événement important dans la vie de cette communauté fut la restructuration de la composante Grille de services Ignite, qui vous permet de déployer des microservices personnalisés directement dans un cluster Ignite. Il a parlé de ce processus difficile lors du meetup Viatcheslav Daradur, ingénieur logiciel et contributeur Apache Ignite depuis plus de deux ans.

Ignite Service Grid - Redémarrer

Commençons par ce qu'est Apache Ignite en général. Il s'agit d'une base de données qui est un stockage clé/valeur distribué avec prise en charge de SQL, de la transactionnalité et de la mise en cache. De plus, Ignite vous permet de déployer des services personnalisés directement dans un cluster Ignite. Le développeur a accès à tous les outils fournis par Ignite : structures de données distribuées, messagerie, streaming, calcul et grille de données. Par exemple, lors de l'utilisation de Data Grid, le problème de l'administration d'une infrastructure distincte pour le stockage des données et, par conséquent, les frais généraux qui en résultent disparaissent.

Ignite Service Grid - Redémarrer

À l'aide de l'API Service Grid, vous pouvez déployer un service en spécifiant simplement le schéma de déploiement et, par conséquent, le service lui-même dans la configuration.

En règle générale, un schéma de déploiement indique le nombre d'instances qui doivent être déployées sur les nœuds du cluster. Il existe deux schémas de déploiement typiques. Le premier est Cluster Singleton : à tout moment, une instance d'un service utilisateur est garantie d'être disponible dans le cluster. Le second est Node Singleton : une instance du service est déployée sur chaque nœud du cluster.

Ignite Service Grid - Redémarrer

L'utilisateur peut également spécifier le nombre d'instances de service dans l'ensemble du cluster et définir un prédicat pour filtrer les nœuds appropriés. Dans ce scénario, Service Grid calculera lui-même la distribution optimale pour le déploiement des services.

De plus, il existe une fonctionnalité telle que Affinity Service. L'affinité est une fonction qui définit la relation entre les clés et les partitions et la relation entre les parties et les nœuds de la topologie. À l'aide de la clé, vous pouvez déterminer le nœud principal sur lequel les données sont stockées. De cette façon, vous pouvez associer votre propre service à un cache de clés et de fonctions d'affinité. Si la fonction d'affinité change, un redéploiement automatique se produira. De cette façon, le service sera toujours situé à proximité des données qu’il doit manipuler et, par conséquent, réduira les frais d’accès aux informations. Ce schéma peut être appelé une sorte d’informatique colocalisée.

Maintenant que nous avons compris quelle est la beauté de Service Grid, parlons de son historique de développement.

Qu'y avait-il avant

L'implémentation précédente de Service Grid était basée sur le cache système transactionnel répliqué d'Ignite. Le mot « cache » dans Ignite fait référence au stockage. Autrement dit, ce n’est pas quelque chose de temporaire, comme on pourrait le penser. Malgré le fait que le cache est répliqué et que chaque nœud contient l'intégralité de l'ensemble de données, à l'intérieur du cache, il a une représentation partitionnée. Cela est dû à l’optimisation du stockage.

Ignite Service Grid - Redémarrer

Que s'est-il passé lorsque l'utilisateur a souhaité déployer le service ?

  • Tous les nœuds du cluster se sont abonnés pour mettre à jour les données dans le stockage à l'aide du mécanisme de requête continue intégré.
  • Le nœud initiateur, dans le cadre d'une transaction en lecture validée, a créé un enregistrement dans la base de données contenant la configuration du service, y compris l'instance sérialisée.
  • Lorsqu'il est informé d'une nouvelle entrée, le coordinateur calcule la répartition en fonction de la configuration. L'objet résultant a été réécrit dans la base de données.
  • Si un nœud faisait partie de la distribution, le coordinateur devait le déployer.

Ce qui ne nous convenait pas

À un moment donné, nous sommes arrivés à la conclusion : ce n’est pas ainsi qu’il faut travailler avec les services. Il y avait plusieurs raisons.

Si une erreur se produisait lors du déploiement, elle ne pouvait être découverte qu'à partir des journaux du nœud où tout s'était passé. Il n'y avait qu'un déploiement asynchrone, donc après avoir rendu le contrôle à l'utilisateur à partir de la méthode de déploiement, un certain temps supplémentaire était nécessaire pour démarrer le service - et pendant ce temps, l'utilisateur ne pouvait rien contrôler. Afin de développer davantage Service Grid, de créer de nouvelles fonctionnalités, d’attirer de nouveaux utilisateurs et de faciliter la vie de chacun, quelque chose doit changer.

Lors de la conception du nouveau Service Grid, nous avons avant tout souhaité apporter une garantie de déploiement synchrone : dès que l'utilisateur reprenait le contrôle depuis l'API, il pouvait immédiatement utiliser les services. Je voulais également donner à l'initiateur la possibilité de gérer les erreurs de déploiement.

De plus, je souhaitais simplifier la mise en œuvre, à savoir s'éloigner des transactions et du rééquilibrage. Malgré le fait que le cache soit répliqué et qu'il n'y ait pas d'équilibrage, des problèmes sont survenus lors d'un déploiement à grande échelle avec de nombreux nœuds. Lorsque la topologie change, les nœuds doivent échanger des informations, et avec un déploiement à grande échelle, ces données peuvent peser lourd.

Lorsque la topologie était instable, le coordinateur devait recalculer la répartition des services. Et en général, lorsque vous devez travailler avec des transactions sur une topologie instable, cela peut conduire à des erreurs difficiles à prévoir.

Problèmes

Que sont les changements globaux sans problèmes associés ? Le premier d’entre eux était un changement de topologie. Vous devez comprendre qu'à tout moment, même au moment du déploiement du service, un nœud peut entrer ou sortir du cluster. De plus, si au moment du déploiement le nœud rejoint le cluster, il sera nécessaire de transférer systématiquement toutes les informations sur les services vers le nouveau nœud. Et nous ne parlons pas seulement de ce qui a déjà été déployé, mais aussi des déploiements actuels et futurs.

Ce n'est qu'un des problèmes qui peuvent être rassemblés dans une liste distincte :

  • Comment déployer des services configurés statiquement au démarrage du nœud ?
  • Quitter un nœud du cluster : que faire si le nœud héberge des services ?
  • Que faire si le coordinateur a changé ?
  • Que faire si le client se reconnecte au cluster ?
  • Les demandes d’activation/désactivation doivent-elles être traitées et comment ?
  • Et s’ils appelaient à la destruction du cache et que des services d’affinité y étaient liés ?

Et c'est loin d'être tout.

décision

Comme cible, nous avons choisi l’approche Event Driven avec la mise en œuvre d’une communication processus à l’aide de messages. Ignite implémente déjà deux composants qui permettent aux nœuds de transmettre des messages entre eux : communication-spi et Discovery-spi.

Ignite Service Grid - Redémarrer

Communication-spi permet aux nœuds de communiquer directement et de transmettre des messages. Il est bien adapté à l’envoi de grandes quantités de données. Discovery-spi vous permet d'envoyer un message à tous les nœuds du cluster. Dans l’implémentation standard, cela se fait à l’aide d’une topologie en anneau. Il existe également une intégration avec Zookeeper, dans ce cas une topologie en étoile est utilisée. Un autre point important à noter est que Discovery-spi garantit que le message sera définitivement transmis dans le bon ordre à tous les nœuds.

Regardons le protocole de déploiement. Toutes les demandes des utilisateurs pour le déploiement et le non-déploiement sont envoyées via Discovery-spi. Cela donne ce qui suit des garanties:

  • La demande sera reçue par tous les nœuds du cluster. Cela permettra à la demande de continuer à être traitée lorsque le coordinateur changera. Cela signifie également que dans un message, chaque nœud disposera de toutes les métadonnées nécessaires, telles que la configuration du service et son instance sérialisée.
  • Un ordre strict de livraison des messages permet de résoudre les conflits de configuration et les demandes concurrentes.
  • Étant donné que l'entrée du nœud dans la topologie est également traitée via Discovery-spi, le nouveau nœud recevra toutes les données nécessaires pour travailler avec les services.

Lorsqu'une requête est reçue, les nœuds du cluster la valident et créent des tâches de traitement. Ces tâches sont mises en file d'attente puis traitées dans un autre thread par un travailleur distinct. Il est mis en œuvre de cette manière car le déploiement peut prendre beaucoup de temps et retarder de manière intolérable le flux de découverte coûteux.

Toutes les demandes de la file d'attente sont traitées par le gestionnaire de déploiement. Il dispose d'un travailleur spécial qui extrait une tâche de cette file d'attente et l'initialise pour commencer le déploiement. Après cela, les actions suivantes se produisent :

  1. Chaque nœud calcule indépendamment la distribution grâce à une nouvelle fonction d'affectation déterministe.
  2. Les nœuds génèrent un message avec les résultats du déploiement et l'envoient au coordinateur.
  3. Le coordinateur regroupe tous les messages et génère le résultat de l'ensemble du processus de déploiement, qui est envoyé via Discovery-spi à tous les nœuds du cluster.
  4. Lorsque le résultat est reçu, le processus de déploiement se termine, après quoi la tâche est supprimée de la file d'attente.

Ignite Service Grid - Redémarrer
Nouvelle conception basée sur les événements : org.apache.ignite.internal.processors.service.IgniteServiceProcessor.java

Si une erreur survient lors du déploiement, le nœud inclut immédiatement cette erreur dans un message qu'il envoie au coordinateur. Après l'agrégation des messages, le coordinateur disposera d'informations sur toutes les erreurs lors du déploiement et enverra ce message via Discovery-spi. Les informations sur les erreurs seront disponibles sur n’importe quel nœud du cluster.

Tous les événements importants de Service Grid sont traités à l’aide de cet algorithme de fonctionnement. Par exemple, changer la topologie est également un message via Discovery-spi. Et en général, par rapport à ce qui existait auparavant, le protocole s'est avéré assez léger et fiable. De quoi gérer n’importe quelle situation lors du déploiement.

Que va-t-il se passer ensuite

Parlons maintenant des plans. Tout changement majeur apporté au projet Ignite est réalisé dans le cadre d'une initiative d'amélioration d'Ignite, appelée IEP. La refonte de Service Grid dispose également d'un IEP - PEI #17 avec le titre moqueur « Vidange d’huile dans le réseau de service ». Mais en fait, nous n’avons pas changé l’huile moteur, mais tout le moteur.

Nous avons divisé les tâches du PEI en 2 phases. La première est une phase majeure, qui consiste à retravailler le protocole de déploiement. Il est déjà inclus dans le master, vous pouvez essayer le nouveau Service Grid, qui apparaîtra dans la version 2.8. La deuxième phase comprend de nombreuses autres tâches :

  • Redéploiement à chaud
  • Gestion des versions des services
  • Tolérance aux pannes accrue
  • Client léger
  • Outils de surveillance et de calcul de diverses métriques

Enfin, nous pouvons vous conseiller sur Service Grid pour créer des systèmes tolérants aux pannes et à haute disponibilité. Nous vous invitons également à nous rendre visite au liste de développement и liste d'utilisateur partagez votre expérience. Votre expérience est vraiment importante pour la communauté ; elle vous aidera à comprendre où aller ensuite, comment développer le composant à l'avenir.

Source: habr.com

Ajouter un commentaire