PolarDB prend en charge deux stratégies d’équilibrage de charge pour répartir la charge entre plusieurs nœuds en lecture seule : Connections-based Load Balancing et Active Request-based Load Balancing.
Stratégies d’équilibrage de charge
Connections-based Load Balancing : cette stratégie est idéale pour les scénarios haute performance qui ne nécessitent pas de fonctionnalités avancées telles que les niveaux de cohérence ou le fractionnement des transactions.
Active Request-based Load Balancing : les requêtes en lecture sont automatiquement acheminées vers les différents nœuds en lecture seule d’un endpoint de cluster en fonction du nombre de requêtes actives. Cette stratégie prend en charge des fonctionnalités avancées telles que les niveaux de cohérence, le fractionnement des transactions et la persistance des connexions, et elle équilibre la charge en se basant sur l’état en temps réel de chaque nœud.
Les endpoints de cluster PolarDB en mode Read-only prennent en charge à la fois Connections-based Load Balancing et Active Request-based Load Balancing. Les endpoints de cluster en mode Read/Write (Automatic Read/Write Splitting) ne prennent en charge que Active Request-based Load Balancing.
Le tableau suivant compare ces deux stratégies.
|
Nom de la stratégie |
Différences |
Similarités |
|
Connections-based Load Balancing |
|
Pour un endpoint de cluster en mode Read-only, aucune requête n’est transférée vers le nœud principal, quelle que soit la stratégie d’équilibrage de charge utilisée. |
|
Active Request-based Load Balancing |
|
Le nœud principal accepte les requêtes en lecture
Si vous définissez Primary Node Accepts Read Requests sur No, PolarProxy n’envoie plus de requêtes en lecture classiques au nœud principal. Toutefois, les requêtes en lecture au sein d’une transaction qui nécessitent une cohérence sont toujours envoyées au nœud principal afin de respecter les exigences métier. De plus, si tous les nœuds en lecture seule échouent, les requêtes en lecture sont également envoyées au nœud principal. Si votre activité impose des exigences de cohérence faibles, vous pouvez définir le niveau de cohérence sur la cohérence à terme pour réduire le nombre de requêtes en lecture adressées au nœud principal. Vous pouvez également utiliser la fonctionnalité de fractionnement des transactions pour réduire les requêtes en lecture envoyées au nœud principal avant le début effectif de la transaction. Les requêtes de diffusion, telles que SET ou PREPARE, sont toujours envoyées au nœud principal.
Vous ne pouvez configurer le paramètre Primary Node Accepts Read Requests que lorsque l’option Read/Write est définie sur Read/Write (Automatic Read/Write Splitting). Pour savoir comment modifier le paramètre Primary Node Accepts Read Requests, consultez Configurer PolarProxy.
Si votre version de PolarProxy est la 1.x.x ou la 2.5.1 (ou ultérieure), les modifications apportées au paramètre Primary Node Accepts Read Requests prennent effet immédiatement.
Si votre version de PolarProxy est la 2.x.x antérieure à la 2.5.1, les modifications apportées au paramètre Primary Node Accepts Read Requests ne prennent effet qu’après le réétablissement des connexions persistantes. Pour les connexions éphémères, les modifications prennent effet immédiatement.
Fractionnement des transactions
Lorsque vous utilisez un endpoint de cluster PolarDB en mode Read/Write (Automatic Read/Write Splitting), PolarProxy distribue les requêtes en lecture et en écriture vers le nœud principal et les nœuds en lecture seule. Afin de garantir la cohérence transactionnelle au sein d’une session, PolarProxy envoie toutes les requêtes effectuées pendant une transaction au nœud principal. Par exemple, certains pilotes de client de base de données, tels que JDBC, encapsulent par défaut les requêtes dans des transactions. Par conséquent, toutes les requêtes de l’application sont envoyées au nœud principal, ce qui peut entraîner une charge élevée sur le nœud principal tandis que les nœuds en lecture seule sont sous-utilisés, comme illustré dans la figure suivante :
Pour résoudre ce problème, PolarDB propose la fonctionnalité de fractionnement des transactions au niveau d’isolation Read Committed. Cette fonctionnalité envoie les requêtes en lecture au sein d’une transaction vers les nœuds en lecture seule afin de réduire la charge sur le nœud principal, tout en garantissant la cohérence en lecture/écriture pour vos services. Vous pouvez décharger la pression en lecture du nœud principal vers les nœuds en lecture seule et améliorer la stabilité du nœud principal sans modifier le code ou les configurations de votre application. Pour obtenir des instructions détaillées sur l’activation du fractionnement des transactions, consultez Configurer PolarProxy.
PolarDB for MySQL propose deux niveaux de fractionnement des transactions : Fractionnement des requêtes en lecture avant la première requête en écriture (par défaut, la fonctionnalité de fractionnement des transactions d’origine) et Fractionnement complet des transactions (fractionnement des requêtes en lecture avant et après la première requête en écriture).
-
Fractionnement des requêtes en lecture avant la première requête en écriture
PolarProxy envoie les requêtes en lecture qui précèdent la première requête en écriture d’une transaction vers les nœuds en lecture seule, ce qui réduit la charge sur le nœud principal.
-
Fractionnement complet des transactions (fractionnement des requêtes en lecture avant et après la première requête en écriture)
Avec le fractionnement des requêtes en lecture avant la première requête en écriture, les requêtes en lecture qui surviennent après une écriture sont toujours routées vers le nœud principal, ce qui peut entraîner un déséquilibre de la charge. Pour résoudre entièrement les problèmes d’équilibrage de charge causés par les transactions, PolarDB for MySQL introduit le fractionnement complet des transactions. Cette fonctionnalité permet de router toutes les opérations de lecture au sein d’une transaction vers les nœuds en lecture seule tout en garantissant des résultats corrects, réduisant ainsi davantage la pression sur le nœud principal.
Une requête de lecture après écriture ne peut être routée vers un nœud en lecture seule que si les données de l’opération d’écriture précédente dans la transaction ont été synchronisées avec ce nœud. Si vous avez configuré la cohérence de session, PolarProxy vérifie d’abord si le nœud en lecture seule de la session actuelle a synchronisé les écritures précédentes avant de router la requête de lecture après écriture. Si c’est le cas, la requête est routée vers le nœud en lecture seule ; sinon, elle est routée vers le nœud principal. De même, si vous avez configuré la cohérence globale, PolarProxy vérifie si les transactions de toutes les sessions actuelles ont été synchronisées avec le nœud en lecture seule. Si c’est le cas, la requête y est routée ; sinon, elle est routée vers le nœud principal. Le fractionnement complet des transactions ne prend pas en charge la cohérence à terme.
Versions et limites
Pour utiliser la fonctionnalité de fractionnement complet des transactions, votre cluster PolarDB for MySQL doit répondre aux exigences suivantes :
-
**Version du moteur** :
PolarDB for MySQL 5.6, révision 5.6.1.0.29 ou ultérieure.
PolarDB for MySQL 5.7, révision 5.7.1.0.9 ou ultérieure.
PolarDB for MySQL 8.0.1, révision 8.0.1.1.18 ou ultérieure.
PolarDB for MySQL 8.0.2, toute révision.
-
Paramètre du moteur :
Le paramètre
loose_query_cache_typedoit être défini sur OFF. PolarDB for MySQL 5.6, 5.7 et 8.0.1 utilisent OFF par défaut. La version 8.0.2 utilise ON par défaut. La modification de ce paramètre nécessite un redémarrage du cluster PolarDB.
RemarqueLe fractionnement des transactions est pris en charge uniquement pour les sessions au niveau d’isolation Read Committed et est activé par défaut.
En raison des contraintes de cohérence en lecture/écriture, les requêtes en lecture ne sont pas routées vers un nœud en lecture seule si son niveau de cohérence ne répond pas aux exigences.
Si votre version de PolarProxy est antérieure à la 2.4.14, seul le fractionnement des requêtes en lecture avant la première requête en écriture est pris en charge. Le fractionnement complet des transactions n’est pas pris en charge.
Si votre version de PolarProxy est la 2.4.14 ou ultérieure et que le fractionnement des transactions est configuré pour le fractionnement complet des transactions, vous devez réétablir les connexions persistantes pour que la modification prenne effet. Pour les connexions éphémères, la modification prend effet immédiatement.
-
-
Désactiver le fractionnement des transactions
Lorsque le fractionnement des transactions est désactivé, toutes les requêtes au sein d’une transaction sont routées vers le nœud principal.
Équilibrage de charge basé sur les poids
Par défaut, le PolarProxy de PolarDB for MySQL route les requêtes vers le nœud ayant le moins de requêtes actives (concurrentes). Cette stratégie équilibre généralement le trafic entre les nœuds backend en fonction de leur charge. Elle offre également de bonnes performances lorsque les nœuds backend ont des spécifications différentes. Toutefois, les charges de travail de production et les exigences de distribution du trafic varient.
Pour mieux répondre à ces besoins, PolarDB for MySQL introduit l’équilibrage de charge basé sur les poids. Vous pouvez configurer des poids différents pour chaque nœud. Pendant le processus de routage, le poids et le nombre de requêtes concurrentes sont utilisés comme critères pour ajuster dynamiquement la décision de routage finale. Actuellement, les poids peuvent être configurés aux deux niveaux suivants :
-
Dimension globale
Cette configuration s’applique à tous les endpoints.
-
Dimension de l’endpoint
Le poids au niveau de la dimension de l’endpoint s’applique uniquement à l’équilibrage de charge de cet endpoint et remplace le paramètre global. Par exemple, si vous configurez d’abord un poids au niveau global, puis un poids distinct pour un endpoint spécifique, l’équilibrage de charge pour cet endpoint sera basé sur la configuration au niveau de l’endpoint.
Notes
Cette fonctionnalité nécessite PolarProxy 2.8.3 ou ultérieur.
Étant donné que la stratégie de routage prend en compte à la fois la charge actuelle du nœud et le poids défini par l’utilisateur, le ratio global du trafic peut s’écarter légèrement du ratio configuré. Avec le temps, il convergera progressivement vers le ratio configuré.
Les clusters Serverless ne prennent pas en charge la configuration des poids au niveau de la dimension de l’endpoint.
Fonctionnement
Pendant le processus de routage des requêtes, le poids final de chaque nœud est calculé dynamiquement en fonction du poids configuré et du nombre actuel de requêtes concurrentes sur le nœud. La formule simplifiée est la suivante :
Poids dynamique = Poids configuré / Nombre de requêtes concurrentes
Plus le poids dynamique est élevé, plus la priorité du nœud est grande. La stratégie d’équilibrage de charge par poids dynamique offre une méthode de routage flexible. En pratique, le trafic se déplace progressivement selon les poids configurés, ce qui peut prendre plus de temps qu’une approche simple de type round-robin pondéré.
Procédure
Initialement, chaque nœud backend possède le même poids par défaut de 1.
La plage configurable pour les poids est de 0 à 100.
Lorsqu’un poids est défini sur 0, PolarProxy ne route pas les requêtes vers ce nœud dans des circonstances normales. Le nœud n’est sélectionné que si tous les autres nœuds sont indisponibles.
Si un cluster ne contient qu’un seul nœud column store en lecture seule, son poids peut être ignoré. Si un cluster contient plusieurs nœuds column store en lecture seule, les requêtes column store sont équilibrées en fonction des poids de ces nœuds.
Configurer les poids dans la dimension globale
Connectez-vous à la console PolarDB。
Dans le coin supérieur gauche, sélectionnez la région où le cluster est déployé.
Recherchez le cluster cible et cliquez sur son ID.
Sur la page Basic Information, dans la section Standard Enterprise Edition ou Dedicated Enterprise Edition, cliquez sur Database Proxy Settings.
-
Dans la boîte de dialogue Database Proxy Settings, définissez un poids pour chaque nœud en fonction de vos exigences métier.
La boîte de dialogue affiche le Role de chaque nœud (nœud principal ou nœud en lecture seule) ainsi qu’une zone de saisie Weight. Un message en haut indique que les décisions de routage sont ajustées dynamiquement en fonction à la fois des poids et des requêtes concurrentes. Une fois les poids définis, cliquez sur OK.
Après avoir configuré les poids, cliquez sur OK.
Configurer les poids dans la dimension de l’endpoint
Connectez-vous à la console PolarDB。
Dans le coin supérieur gauche, sélectionnez la région où le cluster est déployé.
Recherchez le cluster cible et cliquez sur son ID.
Sur la page Basic Information, dans la section Standard Enterprise Edition ou Dedicated Enterprise Edition, cliquez sur Configure dans le coin supérieur droit de l’endpoint de cluster ou de l’endpoint personnalisé.
-
Sur la page Modify Endpoint Settings, dans la zone des nœuds de service, activez Configure Node Weight et définissez un poids pour chaque nœud.
Déplacez le nœud cible, tel qu’un nœud column store en lecture seule, de la liste Available Nodes vers la liste Selected Nodes. Ensuite, définissez un poids pour le nœud sélectionné, par exemple
1, et cliquez sur OK. Après avoir défini les poids, cliquez sur OK.
Données de test
Les données de test réelles après configuration des poids des nœuds sont présentées ci-dessous.
Le ratio de poids des trois nœuds utilisés dans le test est de 1:2:3 (le nœud principal a un poids de 1). Les résultats du test de charge correspondent aux attentes (en utilisant la suite de tests Sysbench oltp_read_only).

Les deux nœuds internes, pi-bp1d1mtcobuzv et pcbp14vvpolardbma23957, ne participent pas au routage, leurs métriques peuvent donc être ignorées.
Connexions à la demande
Contexte
Pour les endpoints qui utilisent Active Request-based Load Balancing, PolarProxy crée par défaut des connexions complètes. Après l’établissement d’une session client via PolarProxy, celui-ci établit une session (connexion) avec tous les nœuds de base de données au sein de cet endpoint, créant ainsi une relation de connexion 1:N. Les requêtes en lecture normales dans cette session sont routées vers différents nœuds de base de données en fonction de leur charge active actuelle, tandis que les requêtes de diffusion (telles que les instructions SET) sont routées vers tous les nœuds de base de données. Lorsqu’il y a de nombreux nœuds de base de données, l’efficacité globale est considérablement réduite en raison de la surcharge liée à l’établissement des connexions et à la diffusion.
Fonctionnement
Avec les connexions à la demande, PolarProxy établit des connexions avec les bases de données backend uniquement selon les besoins. Il minimise le nombre de connexions backend tout en respectant les exigences de cohérence et de charge en lecture/écriture. Cela réduit la surcharge de la base de données causée par les connexions proxy et l’exécution de diffusions. Dans la plupart des cas, une session établit des connexions avec au maximum un nœud principal et un nœud en lecture seule (en supposant une cohérence à terme). Cela peut améliorer considérablement les performances pour les connexions éphémères ou les charges de travail comportant de nombreuses instructions de diffusion.
Comme illustré dans la figure ci-dessus, supposons qu’un cluster PolarDB dispose d’un nœud principal (RW) et de trois nœuds en lecture seule (RO). Si la cohérence n’est pas un facteur, le routage des requêtes et l’efficacité de la lecture des données dans les trois scénarios sont les suivants :
-
Connexions complètes
Une seule session utilisateur via PolarProxy établit des connexions avec les quatre nœuds de base de données, et les instructions de diffusion sont routées vers les quatre nœuds.
-
Connexions à la demande, session en lecture seule
Une seule session utilisateur via PolarProxy établit une connexion avec un seul nœud RO. Les requêtes en lecture (y compris les diffusions) sont routées uniquement vers ce seul nœud RO, améliorant considérablement l’efficacité de la lecture des données.
-
Connexions à la demande, session en lecture/écriture
Une seule session utilisateur via PolarProxy établit des connexions avec un seul nœud RO et un nœud RW. Les requêtes de diffusion sont routées uniquement vers ces deux nœuds de base de données, améliorant également considérablement l’efficacité de la lecture des données.
Cas d’utilisation
Clusters comportant un grand nombre de nœuds RO.
Connexions éphémères.
Scénarios comportant de nombreuses instructions de diffusion (par exemple, dans les scénarios de connexions éphémères PHP, la première instruction d’une session est souvent similaire à
set names utf8mb4).Charges de travail comportant de nombreuses requêtes utilisant de courtes instructions PREPARE.
Limites
PolarProxy 2.8.34 ou ultérieur est requis. Pour savoir comment vérifier la version de PolarProxy de votre cluster, consultez Vérifier le numéro de version.
Lorsque vous utilisez
SHOW PROCESSLISTSpour afficher le nombre de connexions à la base de données, il se peut que le nombre total de connexions à toutes les bases de données ne s’affiche pas.Lorsque vous utilisez la commande KILL pour terminer une connexion spécifique, il se peut que la commande ne termine pas la connexion spécifiée dans toutes les bases de données.
Test de performance
Environnement de test
Nœuds de base de données : un nœud en lecture/écriture (RW), sept nœuds en lecture seule (RO)
SQL utilisé pour les tests :
SET NAMES utf8mb4,SELECT 1Outil de test : Sysbench, avec le même nombre de connexions simultanées pour chaque test
Scénarios de test : le test a couvert trois scénarios : sans pool de connexions, avec un pool de connexions au niveau de la session et avec un pool de connexions au niveau de la transaction. Chaque test a été divisé en deux parties : la première moitié sans activation des connexions à la demande, et la seconde moitié avec activation des connexions à la demande.
Résultats des tests
-
Résultats des tests de performance pour le scénario sans pool de connexions :
-
La figure ci-dessous montre la consommation CPU des nœuds de base de données. Après l’activation des connexions à la demande, la consommation CPU de la base de données a diminué de plus de 60 % :

-
La figure ci-dessous montre l’évolution du nombre total de connexions aux nœuds de base de données. Après l’activation des connexions à la demande, le nombre total de connexions a diminué de plus de 80 % :

-
La figure ci-dessous montre l’évolution du QPS global. Après l’activation des connexions à la demande, le QPS global a augmenté de 35 % :

-
-
Résultats des tests de performance pour le scénario avec pool de connexions au niveau de la session :
-
La figure ci-dessous montre la consommation CPU des nœuds de base de données. Après l’activation des connexions à la demande, la consommation CPU de la base de données a diminué de 50 % à 60 % :

-
La figure ci-dessous montre l’évolution du nombre total de connexions aux nœuds de base de données. Après l’activation des connexions à la demande, le nombre total de connexions a diminué de 60 % :

-
La figure ci-dessous montre l’évolution du QPS global. Après l’activation des connexions à la demande, le QPS a augmenté de 30 % :

-
-
Résultats des tests de performance pour le scénario avec pool de connexions au niveau de la transaction :
-
La figure ci-dessous montre la consommation CPU des nœuds de base de données. Après l’activation des connexions à la demande, la consommation CPU de la base de données a diminué de 60 % :

-
La figure ci-dessous montre l’évolution du nombre total de connexions aux nœuds de base de données. Après l’activation des connexions à la demande, le nombre total de connexions a diminué de 50 % :

-
La figure ci-dessous montre l’évolution du QPS global. Après l’activation des connexions à la demande, le QPS a augmenté de 260 % :

-