Pourquoi avez-vous besoin d'une réplication semi-synchrone?

Bonjour à tous. En contact avec Vladislav Rodin. J'enseigne actuellement des cours sur l'architecture logicielle et l'architecture logicielle à haute charge sur le portail OTUS. En prévision du début d'un nouveau volet du cours «Architecte de fortes charges», j'ai décidé d'écrire un petit matériel d'auteur, que je souhaite partager avec vous.




introduction


En raison du fait que seules 400 à 700 opérations par seconde peuvent être effectuées sur le disque dur (ce qui est incomparable avec les rps typiques qui tombent sur un système lourdement chargé), la base de données de disques classique est un col étroit d'architecture. Par conséquent, une attention particulière doit être accordée aux modèles de mise à l'échelle de ce référentiel.

À l'heure actuelle, il existe 2 modèles de mise à l'échelle de base: la réplication et le partitionnement. Le partage permet de mettre à l'échelle l'opération d'écriture et, par conséquent, de réduire les rps d'enregistrement pour un serveur de votre cluster. La réplication vous permet de faire de même, mais avec des opérations de lecture. Cet article est consacré à ce modèle même.

La réplication


Si vous regardez la réplication à un niveau très élevé, c'est une chose simple: vous aviez un serveur, les données s'y trouvaient, puis ce serveur s'est arrêté de faire face à la charge de lecture de ces données. Vous ajoutez quelques serveurs supplémentaires, synchronisez les données sur tous les serveurs et l'utilisateur peut lire à partir de n'importe quel serveur de votre cluster.

Malgré l'apparente simplicité, il existe plusieurs options pour classer les différentes implémentations de ce schéma:

  • Par rĂ´les dans le cluster (maĂ®tre-maĂ®tre ou maĂ®tre-esclave)
  • Par objets transfĂ©rĂ©s (basĂ©s sur des lignes, basĂ©s sur des instructions ou mixtes)
  • Selon le mĂ©canisme de synchronisation des nĹ“uds

Aujourd'hui, nous traiterons du 3ème point.

Comment la transaction est-elle engagée


Ce sujet ne se rapporte pas directement à la réplication, un article séparé peut y être écrit, cependant, car sans une meilleure compréhension du mécanisme de validation des transactions, une lecture supplémentaire est inutile, permettez-moi de vous rappeler les choses les plus élémentaires. Une transaction est engagée en 3 étapes:

  1. Écriture d'une transaction dans le journal de la base de données.
  2. Application d'une transaction dans un moteur de base de données.
  3. Retourner la confirmation au client de la bonne application de la transaction.

Des nuances peuvent survenir dans diverses bases de données de cet algorithme: par exemple, dans le moteur InnoDB de la base de données MySQL, il y a 2 journaux: un pour la réplication (journal binaire) et l'autre pour maintenir ACID (annuler / rétablir le journal), tandis que dans PostgreSQL, il y a un journal exécutant les deux fonctions (écrire le journal d'avance = WAL). Mais au-dessus, c'est précisément le concept général qui permet d'ignorer de telles nuances.

RĂ©plication synchrone (sync)


Ajoutons la logique de réplication des modifications reçues à l'algorithme de validation de transaction:

  1. Écriture d'une transaction dans le journal de la base de données.
  2. Application d'une transaction dans un moteur de base de données.
  3. Envoi de données à toutes les répliques.
  4. Recevez une confirmation de toutes les répliques sur la transaction.
  5. Retourner la confirmation au client de la bonne application de la transaction.

Avec cette approche, nous obtenons un certain nombre d'inconvénients:

  • le client attend que les modifications soient appliquĂ©es Ă  toutes les rĂ©pliques.
  • Ă  mesure que le nombre de nĹ“uds dans le cluster augmente, nous rĂ©duisons la probabilitĂ© que l'opĂ©ration d'Ă©criture rĂ©ussisse.

Si tout est plus ou moins clair avec le 1er paragraphe, alors les raisons du 2e paragraphe doivent être clarifiées. Si, pendant la réplication synchrone, nous n'obtenons pas de réponse d'au moins un nœud, nous annulons la transaction. Ainsi, en augmentant le nombre de nœuds dans le cluster, vous augmentez la probabilité que l'opération d'écriture échoue.

Pouvons-nous attendre la confirmation uniquement à partir d'une certaine fraction de nœuds, par exemple à partir de 51% (quorum)? Oui, nous le pouvons, mais dans la version classique, une confirmation est requise de tous les nœuds, car c'est ainsi que nous pouvons assurer la cohérence complète des données dans le cluster, ce qui est un avantage incontestable de ce type de réplication.

RĂ©plication asynchrone


Modifions l'algorithme précédent. Nous enverrons les données aux répliques «un peu plus tard», et «un peu plus tard» les modifications seront appliquées sur les répliques:

  1. Écriture d'une transaction dans le journal de la base de données.
  2. Application d'une transaction dans un moteur de base de données.
  3. Retourner la confirmation au client de la bonne application de la transaction.
  4. Envoi de données à des répliques et application de modifications à celles-ci.

Cette approche conduit au fait que le cluster est rapide, car nous ne gardons pas le client en attente que les données atteignent les répliques et soient même communiquées.

Mais la condition de déposer des données dans des répliques «un peu plus tard» peut entraîner la perte de la transaction et la perte de la transaction confirmée à l'utilisateur, car si les données n'ont pas eu le temps de se répliquer, une confirmation a été envoyée au client concernant le succès de l'opération et le nœud vers lequel les modifications sont arrivées s'est envolé. Disque dur, nous perdons la transaction, ce qui peut entraîner des conséquences très désagréables.

RĂ©plication semi-sync


Enfin, nous sommes arrivés à la réplication semi-synchrone. Ce type de réplication est peu connu et peu répandu, mais il présente un intérêt considérable, car il peut combiner les avantages de la réplication synchrone et asynchrone.

Essayons de combiner les 2 approches précédentes. Nous ne garderons pas le client longtemps, mais nous exigeons que les données soient répliquées:

  1. Écriture d'une transaction dans le journal de la base de données.
  2. Application d'une transaction dans un moteur de base de données.
  3. Envoi de données à des répliques.
  4. Réception d'une confirmation de la réplique concernant la réception des modifications (elles seront appliquées «un peu plus tard»).
  5. Retourner la confirmation au client de la bonne application de la transaction.

Veuillez noter qu'avec cet algorithme, la perte de transaction se produit uniquement en cas de chute du nœud acceptant les modifications et des nœuds de réplique. La probabilité d'un tel dysfonctionnement est considérée comme faible et ces risques sont acceptés.

Mais avec cette approche, le risque de lectures fantômes est possible. Imaginez le scénario suivant: à l'étape 4, nous n'avons reçu de confirmation d'aucune réplique. Nous devons annuler cette transaction et ne pas retourner la confirmation au client. Étant donné que les données ont été appliquées à l'étape 2, il existe un intervalle de temps entre la fin de l'étape 2 et l'annulation de transaction, pendant lequel les transactions parallèles peuvent voir les modifications qui ne devraient pas figurer dans la base de données.

RĂ©plication semi-synchrone sans perte


Si vous réfléchissez un peu, vous ne pouvez modifier les étapes de l'algorithme que par endroits pour résoudre le problème des lectures fantômes dans ce scénario:

  1. Écriture d'une transaction dans le journal de la base de données.
  2. Envoi de données de réplique.
  3. Réception d'une confirmation de la réplique concernant la réception des modifications (elles seront appliquées «un peu plus tard»).
  4. Application d'une transaction dans un moteur de base de données.
  5. Retourner la confirmation au client de la bonne application de la transaction.

Maintenant, nous n'engageons les modifications que si elles sont répliquées.

Conclusion


Comme toujours, il n'y a pas de solutions parfaites, il existe un ensemble de solutions, chacune ayant ses propres avantages et inconvénients et convenant à la résolution de différentes classes de problèmes. Cela est également vrai pour le choix d'un mécanisme de synchronisation des données d'une base de données répliquée. L'ensemble des avantages de la réplication semi-synchrone est suffisamment solide et intéressant pour être considéré comme méritant l'attention, malgré sa faible prévalence.

C'est tout. Rendez-vous sur le parcours !

All Articles