Background Image
DÉVELOPPEMENT DE LOGICIELS

Défis et stratégies liés à la mise en œuvre d'un basculement intelligent dans les systèmes de bases de données

Sergiy Voshchykov

Développeur personnel senior

Aaron Congo

Développeur de logiciels senior

August 23, 2022 | 9 Lecture minute

Les bases de données sont un élément essentiel de tout système moderne et, à mesure que leur popularité s'accroît, les normes de performance, de disponibilité et de persistance augmentent elles aussi. Bien que les bases de données modernes offrent des améliorations significatives dans ces domaines, les défaillances éventuelles des bases de données sont inévitables.

Cet article de blog explore les différentes stratégies qui peuvent être utilisées pour corriger les défaillances des bases de données aussi rapidement que possible.

Image - Intelligent Failover -2

De nos jours, de nombreux types de bases de données sont utilisés. Parmi les plus courantes, citons

  • les bases de données relationnelles

  • les bases de données NoSQL

  • Bases de données graphiques

  • Stockage de clés/valeurs

  • Bases de données spécialisées pour :

    • Coordonnées géologiques

    • Lignes temporelles/séries chronologiques

Au cours des dernières décennies, les applications sont devenues plus grandes et plus lourdes. Elles fonctionnent avec des quantités massives de données et les bases de données ont dû s'adapter aux exigences qui en découlent. En conséquence, les bases de données à serveur unique ont été largement remplacées par des bases de données multi-serveurs hébergées dans le nuage. Ces systèmes sont communément appelés clusters de bases de données. Les bases de données en nuage offrent un avantage considérable en raison de leur capacité à évoluer rapidement, mais elles ajoutent également une complexité et des défis supplémentaires du point de vue de l'application client. En voici quelques exemples :

  • Accessibilité du réseau : les instances de la base de données peuvent tomber en panne ou devenir inaccessibles à tout moment, et les applications clientes doivent gérer ces défaillances spontanées de manière élégante.

  • Établissement de nouvelles connexions : les bases de données multi-instances introduisent une incertitude quant à l'instance à laquelle l'application doit se connecter. Quelles sont les instances les plus sollicitées ? De nouvelles instances ont-elles été ajoutées ? Toutes les instances sont-elles disponibles ? Les applications clientes doivent connaître la topologie de la base de données et suivre son état dans le temps.

Image - Intelligent Failover #1

Pour assurer la cohérence des données entre les instances, les grappes de bases de données partagent généralement les données entre chaque instance. Ils assurent également la tolérance aux pannes et l'évolutivité en exécutant des processus complexes qui ne sont pas pris en compte par l'application. Ces processus sont les suivants

  • la réplication des données entre les instances

  • la résolution des conflits de données

  • la sauvegarde et la récupération des données.

Lorsqu'elles utilisent des grappes de bases de données, les applications clientes doivent veiller à faire la distinction entre la lecture et l'écriture des données. Les topologies des grappes de bases de données peuvent prendre différentes formes, mais en général, elles contiennent souvent des instances de deux types : les écrivains et les lecteurs (également appelés répliques). Comme on peut s'y attendre, les auteurs peuvent modifier les données, tandis que les lecteurs ne peuvent que les récupérer. Les instances de lecteurs permettent d'équilibrer la charge des demandes de données et donc d'améliorer les performances. Dans ce cas, l'application cliente doit faire la distinction entre les requêtes de lecture et d'écriture, et les diriger vers les connexions de base de données appropriées en fonction du rôle de l'instance connectée (lecteur ou écrivain).

Topologies des grappes de bases de données

Il existe de nombreuses implémentations différentes de topologies de grappes de bases de données. Chaque implémentation a ses avantages et ses inconvénients, et les architectes de systèmes peuvent utiliser celle qui répond le mieux aux exigences de leur système. Certaines implémentations courantes sont présentées ci-dessous.

Image - Intelligent Failover #3

Que se passe-t-il lorsqu'une instance meurt ?

Que se passe-t-il réellement lorsqu'une instance de base de données meurt ? Prenons l'exemple de l'une des topologies de cluster les plus courantes : un seul auteur avec plusieurs répliques en lecture. Le diagramme ci-dessous montre un cluster contenant cinq instances. Dans cet exemple, la première instance de base de données (S1) subit une défaillance. Comment l'application cliente doit-elle réagir ?

Image - Intelligence Failover #4

Le scénario le plus simple serait que S1 soit une instance de lecture. Étant donné que la connexion a été établie avec une instance de lecteur, nous savons qu'elle n'a été utilisée que pour des déclarations en lecture seule. Lorsque l'application cliente détecte un problème avec la connexion, elle peut la remplacer par une nouvelle connexion à n'importe quelle autre instance disponible. Étant donné que la connexion fonctionnait en mode lecture seule, nous savons que seules des instructions en lecture seule étaient exécutées sur la connexion et que le passage d'un lecteur à un autre ne présentait aucun risque.

Dans l'autre scénario, celui illustré dans le diagramme ci-dessus, l'instance S1 était une instance d'écriture. Dans ce cas, côté serveur, la grappe de bases de données doit élire une nouvelle instance de scripteur et reconfigurer correctement la grappe. L'instance de scripteur nouvellement élue prend en charge les responsabilités de scripteur et devient la principale source de modification des données. Ce processus est appelé basculement. Le basculement d'une grappe s'accompagne inévitablement d'un temps d'arrêt, et les applications clientes doivent le gérer correctement. Dans ce scénario, l'application cliente devra disposer d'un moyen de se reconnecter au nouveau nœud de rédaction une fois qu'il sera disponible. Le mécanisme permettant d'effectuer cette action dépend de l'implémentation de la grappe utilisée. Examinons un exemple d'implémentation de grappe et la manière dont elle résout ce problème.

Image - Intelligence Failover #5

L'implémentation de la grappe ci-dessus présente quelques caractéristiques uniques :

  • Réplication : en règle générale, la réplication s'effectue par le biais d'une communication directe entre les instances de l'auteur et du lecteur. L'auteur envoie un journal des modifications aux instances de lecteur, et chaque lecteur applique ces modifications à sa propre copie des fichiers de la base de données. Cette implémentation prend un raccourci et applique les modifications de données directement aux fichiers de données du lecteur. Cette opération est sûre, car les connexions des clients ne peuvent pas modifier les données dans les instances de lecteur, et elle est plus rapide que l'approche habituelle. Le lecteur sert simplement les données mises à jour à l'application cliente.

  • Zones de disponibilité : les instances de la base de données sont déployées sur du matériel physique relié à différentes lignes électriques. Le centre de données est organisé de manière à ce qu'au moins deux zones de disponibilité survivent à une coupure de courant. Cette approche permet de minimiser les temps d'arrêt des clusters. La même approche s'applique à toutes les mises à jour/améliorations logicielles : une mise à jour peut être appliquée à une instance dans une zone de disponibilité particulière tandis que les instances dans les autres zones de disponibilité restent actives et utilisables.

Pour permettre l'accès aux différentes instances de la grappe, ce système de base de données expose des points d'extrémité spéciaux "grappe" et "lecteur". Les points de terminaison sont des noms de domaine qui ne changent jamais, mais les adresses IP sous-jacentes vers lesquelles ils pointent peuvent changer. Le point de terminaison "cluster" offre une fonction utile : il pointe toujours vers l'instance d'écriture actuelle. Si l'instance de rédacteur change au cours d'un processus de basculement, le point de terminaison de la grappe dirigera les connexions vers cette instance de rédacteur nouvellement élue. Cela résout le problème mentionné ci-dessus : en cas de défaillance d'une instance de rédacteur, l'application cliente peut utiliser le point de terminaison du cluster pour se connecter à la nouvelle instance de rédacteur.

Le point d'accès au lecteur fonctionne de la même manière, mais il fournit à l'application cliente une seule connexion de lecteur (aléatoire) à partir de la liste des instances de lecteur disponibles. Chaque fois que le client se connecte à l'aide du point d'accès lecteur, la connexion résultante peut être établie avec n'importe lequel des lecteurs disponibles. Cela simplifie l'accès aux instances de lecteurs et permet d'équilibrer la charge entre elles.

Image - Intelligence Failover #6

Avec ce système de points d'accès en place, l'application cliente n'a pas besoin de connaître les instances de bases de données individuelles (comme les adresses IP ou les noms DNS associés). Elle a simplement besoin d'un cluster ou d'un point d'extrémité de lecteur. À ce stade, on peut penser que la complexité liée à la sélection de l'instance à laquelle se connecter a été résolue. Cependant, il y a encore quelques aspects à prendre en compte.

L'utilisation de points de terminaison nous oblige à accepter que les noms de domaine soient résolus en adresses IP associées chaque fois que l'application cliente les utilise. La résolution DNS s'effectue par un appel au serveur DNS le plus proche, qui utilise des données mises en cache. Dans le cas du basculement du rédacteur, lorsque l'instance du rédacteur a changé, il n'est pas garanti que l'enregistrement DNS mis à jour soit propagé immédiatement. En d'autres termes, il peut arriver qu'un nouveau rédacteur soit élu, mais que l'application cliente ne puisse pas encore y accéder via le point de terminaison du cluster, qui est encore en cours de résolution vers la nouvelle adresse IP. Dans ce cas, l'application client pourrait être dirigée vers une adresse IP obsolète au lieu de l'instance de rédacteur qu'elle a demandée.

Mais que se passerait-il s'il existait, entre l'application cliente et le cluster de bases de données, un composant intelligent qui connaisse parfaitement la topologie et l'état du cluster ? Quelque chose comme ça :

Image - Intelligence Failover #7

Si tel était le cas, l'application client pourrait simplement se connecter au routeur à l'aide d'un point d'accès unique, sans nécessiter de configuration complexe. Le routeur connaîtrait la topologie actuelle de la grappe, l'instance qui écrit et celles qui sont en panne. Parce qu'il connaît la topologie et l'état de la grappe, il est en mesure de répartir la charge de manière uniforme entre les instances de lecteurs. En outre, il pourrait être utilisé par des applications totalement différentes pour accéder à la même grappe ou même à d'autres grappes de bases de données. Cela pourrait se faire sans que l'application cliente n'ait à réimplémenter la même logique pour chaque couple application/cluster.

Examinons cette idée sous un angle différent. Le diagramme ci-dessous présente un modèle de pilote de base de données. Dans ce modèle, l'application cliente utilise une interface commune pour accéder à une base de données - par exemple, l'interface JDBC pour une application Java. L'interface JDBC unifie l'accès à différentes bases de données en dissimulant les détails spécifiques à la base de données dans la logique du pilote.

Image - Intelligence Failover #9

Et si un pilote pouvait être utilisé pour la mise en œuvre du routeur dont nous avons parlé plus haut ? Un pilote qui, en plus de fournir une connectivité générale, est également conscient de la topologie actuelle de la grappe ? Appelons-le "pilote intelligent". Le pilote intelligent pourrait utiliser sa connaissance actualisée de la topologie pour fournir une connexion plus rapide au nouvel écrivain en cas de basculement. Voyons comment cela est possible.

Image - Intelligence Failover #10

Les pilotes servent une connexion logique à une application et l'associent en interne à une connexion physique à une instance de base de données. Avec ce modèle, nous pourrions facilement changer la connexion physique sous-jacente d'une instance à l'autre, sans que l'application cliente n'ait à intervenir. Pour permettre la fonctionnalité de basculement rapide que nous souhaitons, notre pilote intelligent doit suivre la topologie du cluster en utilisant la connexion actuelle à la base de données. Lorsqu'un basculement de la base de données est détecté, le pilote connaît la topologie actuelle, mais pas encore l'instance qui est le nouvel auteur. Pour résoudre ce problème, le pilote pourrait utiliser la liste des lecteurs disponibles pour établir une nouvelle connexion à la base de données. À l'aide de cette connexion, il récupère et analyse en permanence la topologie de la grappe. Dès qu'un nouveau rédacteur élu est disponible, le pilote remplace la connexion physique à l'ancien rédacteur par une connexion physique au nouveau. L'ensemble de ce processus peut même être exécuté sans interrompre l'application client.

Cependant, il y a un autre élément à prendre en compte pour que ce processus soit correctement isolé de l'application : chaque connexion à une instance de base de données est associée à un contexte de session spécifique.

Image - Intelligence Failover #11

Un contexte de session est un groupe de paramètres, de variables temporaires et d'objets de base de données temporaires qui peuvent être créés directement ou indirectement pendant la durée de vie d'une connexion. Une table ou une fonction temporaire, le dernier ID inséré à partir de la dernière instruction INSERT/UPDATE, les paramètres de fuseau horaire, les paramètres régionaux - tous ces éléments sont de bons exemples de contexte de session.

Lorsque le pilote modifie la connexion physique sous-jacente pendant le basculement, il perd aussi indirectement les informations liées au contexte de la session. Si le flux des instructions SQL dépend de ce contexte, l'application client peut subir des erreurs ou des pertes de données. Cette situation est évidemment loin d'être idéale. Comment résoudre ce problème ? Malheureusement, la solution est assez complexe. Une option consisterait à analyser les instructions SQL envoyées par le pilote et à suivre l'état de la session en conséquence. Cependant, la diversité des façons dont l'état de la session peut être défini rend cette tâche assez difficile, et l'étendue de la mise en œuvre de cette fonctionnalité dépasse le cadre de cet article. Une autre option serait de notifier l'application d'un changement de connexion et de laisser la responsabilité de la gestion de l'état de la session à l'application elle-même. D'une certaine manière, cette approche est logique, car c'est l'application qui a la perspective la plus complète de ce qui est tenté d'être réalisé par les exécutions des instructions SQL. Cependant, dans ce scénario, nous ne pouvons pas complètement abstraire le processus de l'application - une exception devra être levée pour alerter l'application du changement de connexion afin qu'elle puisse reconfigurer l'état de la session si nécessaire.

Et voilà ! Dans cet article, nous avons examiné les clusters de bases de données et leur fonctionnement, les défaillances de bases de données et la manière de les gérer, ainsi que quelques-uns des défis et des stratégies utilisés pour minimiser les temps d'arrêt lorsque des défaillances se produisent. Nous espérons que vous avez acquis de nouvelles connaissances sur le monde des clusters de bases de données et leur mode de fonctionnement. Si vous avez apprécié la lecture de cet article, n'hésitez pas à revenir dans le futur pour obtenir plus d'informations sur des sujets connexes ; nous espérons vous revoir bientôt !

Développement de logiciels
Platform Engineering
Données

Dernières réflexions

Explorez nos articles de blog et laissez-vous inspirer par les leaders d'opinion de nos entreprises.
Blog Image - Unveiling the Future of AI at Google Cloud Next 24 -1
AI/ML

Unveiling the Future of AI at Google Cloud Next ‘24

Get firsthand insights from Improving into the innovation brewing around artificial intelligence and cloud computing at Google Cloud Next '24.