On ne peut pas répartir la charge d'une écriture.
Des nœuds de base de données identiques ressemblent à une capacité d'écriture multipliée. Répartissez vos écritures entre eux et le cluster produit des deadlocks. La conception qui fonctionne.
Dans cet article 2 sections
- La configuration intuitive d'un cluster : des nœuds identiques, un load balancer, tout en round-robin. Cela ressemble à une capacité multipliée.
- Sous une charge parfaitement normale, elle livre des erreurs de deadlock à des rédacteurs en pleine publication, sans aucun bug de verrouillage où que ce soit dans le code. Deux rédacteurs, deux nœuds, une ligne chaude, et le contrôle de conflit du cluster en rejette un.
- La solution contre-intuitive : chaque écriture va vers un seul nœud élu, et seules les lectures sont réparties.
- Le retournement qui répond au « mais la distribution n'est-elle pas plus rapide ? » : le volume d'écriture est rarement la contrainte. La capacité de lecture est ce qui monte en charge, et les erreurs disparaissent.
Vous avez acheté un cluster de base de données. Personne n'achète plusieurs exemplaires d'une chose pour n'en utiliser qu'un, donc la configuration du load balancer s'écrit pratiquement toute seule : round-robin sur tout, vers chaque nœud. La croyance en dessous est simple : une requête isolée ne sera pas plus rapide, mais beaucoup le seront, réparties sur les machines. Cela semble évidemment juste. C'est aussi la façon la plus courante dont nous voyons cette classe de cluster mal utilisée.
Le bug qui n'est pas dans le code
Sous une charge ordinaire, les rédacteurs cliquent de temps en temps sur enregistrer et reçoivent en retour une erreur brute de base de données à travers le CMS : deadlock found. C'est intermittent et difficile à reproduire, et aucune relecture du code de l'application ne le trouvera, parce que le bug n'est pas dans le code.
La charge qui devient l'arme est ordinaire. Un CMS réécrit une poignée de lignes de configuration à nom global à presque chaque action. Un plugin SEO reconstruit son sitemap à chaque enregistrement. Les horodatages de connexion et les compteurs de vues touchent tous les mêmes lignes chaudes. Le round-robin disperse ces écritures concurrentes sur chaque nœud. Chaque nœud accepte sa propre écriture localement, puis l'étape de certification du cluster attrape la collision au moment du commit et la renvoie à un client qui n'a rien fait de mal. Deux rédacteurs, deux nœuds, la même ligne : erreur 1213.
Un deadlock sous une charge normale, sur un cluster, sans aucun motif de verrouillage où que ce soit dans l'application, est un symptôme de routage. La charge n'est pas en tort. La topologie l'est.
Un seul writer pour la sûreté, répartissez les lectures
Canaliser toutes les écritures vers un seul nœud gaspille-t-il les autres ? Non. Les lectures s'équilibrent uniformément sur tout le cluster et chaque écriture va vers le seul writer élu. L'instinct du round-robin a raison pour les lectures et tort pour les écritures ; le routage à writer unique garde la moitié qui est juste et supprime les erreurs que l'autre moitié génère. Si votre premier réflexe sur un cluster chargé est de monter en puissance, la leçon jumelle est que le bon geste est souvent l'inverse (dimensionner à la baisse, pas à la hausse).
1213
1
“Un cluster est multi-primary-capable et single-writer-safe. Ce sont deux phrases différentes.”
Si vous exploitez un cluster à lectures équilibrées, allez voir où vos écritures atterrissent réellement. Si la réponse est « là où le balancer les envoie par hasard », vous êtes à un après-midi chargé de fabriquer des deadlocks à partir de votre propre succès. La vérification coûte une lecture de configuration. La solution est une règle de routage, pas une réécriture.
Réponses directes
Pourquoi ai-je des erreurs de deadlock (1213) sur mon cluster Galera ou PXC sous une charge normale ?+
S'il n'y a pas de bug de verrouillage dans votre code, vérifiez le routage des écritures. Des écritures dispersées sur les nœuds entrent en collision sur des lignes chaudes au moment de la certification, et le cluster signale la collision comme un deadlock à un client innocent. Routez chaque écriture vers un seul nœud et toute la classe d'erreur disparaît.
Envoyer toutes les écritures vers un seul nœud ne gaspille-t-il pas mon cluster ?+
Les écritures ne sont presque jamais le goulot d'étranglement ; les lectures font le volume. Avec le routage à writer unique, les lectures s'équilibrent toujours sur chaque nœud et le débit d'écriture ne change pas, parce qu'en pratique un seul nœud faisait toujours tout le travail d'écriture.
Un cluster Galera peut-il faire des écritures multi-master ?+
Il est capable d'accepter des écritures sur chaque nœud, et il est sûr quand il n'a pas à certifier des écritures concurrentes sur des lignes chaudes venant de plusieurs d'entre eux à la fois. Multi-primary-capable, single-writer-safe. Utilisez la capacité pour le failover, pas pour la répartition de charge.
Comment faire monter en charge les écritures de base de données, alors ?+
Prouvez d'abord que vous en avez besoin : mesurez le volume d'écriture face à la marge du writer unique, qui est en général une erreur d'arrondi à côté des lectures. La vraie montée en charge des écritures relève du sharding ou de la refonte de la charge, pas d'un réglage de load balancer.
Qu'est-ce qui route les lectures et les écritures différemment ?+
Une couche proxy qui parle le protocole de la base peut les séparer : les lectures se répartissent, les écritures sont épinglées au writer élu, et le failover réélit un writer automatiquement. Nous exploitons ce schéma en production : ProxySQL devant Percona XtraDB Cluster.
Vous voyez des deadlocks que vous ne trouvez pas dans votre code ?
Envoyez-nous seulement l'erreur et la façon dont votre cluster est équilibré. Si c'est la topologie, nous vous le montrerons, et nous le corrigerons dans le routage, pas dans votre application.
Parler à un ingénieurVous êtes arrivé à la fin.
Mettez la lecture en pratique
Que faites-vous tourner ?
Parlez-nous de la charge de travail, du trafic et des exigences de reprise. Commencez par le configurateur de serveur, ou passez en revue les détails avec un ingénieur.
Écrit par les ingénieurs qui construisent et exploitent l'infrastructure qu'il décrit.Parler à un ingénieur
