Mysql
 sql >> Base de données >  >> RDS >> Mysql

Mise à l'échelle automatique avec Amazon Aurora Serverless

Amazon Aurora Serverless fournit une base de données relationnelle à la demande, auto-évolutive et hautement disponible qui ne vous facture que lorsqu'elle est utilisée. Il offre une option relativement simple et économique pour les charges de travail peu fréquentes, intermittentes ou imprévisibles. Ce qui rend cela possible, c'est qu'il démarre automatiquement, adapte la capacité de calcul en fonction de l'utilisation de votre application, puis s'arrête lorsqu'il n'est plus nécessaire.

Le schéma suivant montre l'architecture de haut niveau d'Aurora Serverless.

Avec Aurora Serverless, vous obtenez un point de terminaison (par opposition à deux points de terminaison pour la base de données provisionnée Aurora standard). Il s'agit essentiellement d'un enregistrement DNS composé d'une flotte de proxys qui se trouve au-dessus de l'instance de base de données. À partir d'un point de serveur MySQL, cela signifie que les connexions proviennent toujours de la flotte de proxy.

Auto-scaling Aurora sans serveur

Aurora Serverless n'est actuellement disponible que pour MySQL 5.6. Vous devez essentiellement définir l'unité de capacité minimale et maximale pour le cluster de bases de données. Chaque unité de capacité équivaut à une configuration de calcul et de mémoire spécifique. Aurora Serverless réduit les ressources du cluster de bases de données lorsque sa charge de travail est inférieure à ces seuils. Aurora Serverless peut réduire la capacité au minimum ou augmenter la capacité jusqu'à l'unité de capacité maximale.

Le cluster évoluera automatiquement si l'une des conditions suivantes est remplie :

  • L'utilisation du processeur est supérieure à 70 % OU
  • Plus de 90 % des connexions sont utilisées

Le cluster se réduira automatiquement si les deux conditions suivantes sont remplies :

  • L'utilisation du processeur tombe en dessous de 30 % ET
  • Moins de 40 % des connexions sont utilisées.

Certaines choses à savoir sur le flux de mise à l'échelle automatique d'Aurora :

  • Il n'évolue à la hausse que lorsqu'il détecte des problèmes de performances qui peuvent être résolus par une mise à l'échelle.
  • Après la mise à l'échelle, le délai de récupération pour la mise à l'échelle est de 15 minutes.
  • Après la réduction d'échelle, le temps de recharge pour la prochaine réduction d'échelle est de 310 secondes.
  • Il passe à une capacité nulle lorsqu'il n'y a pas de connexion pendant une période de 5 minutes.

Par défaut, Aurora Serverless effectue la mise à l'échelle automatique de manière transparente, sans couper les connexions de base de données actives au serveur. Il est capable de déterminer un point de mise à l'échelle (un moment auquel la base de données peut lancer en toute sécurité l'opération de mise à l'échelle). Dans les conditions suivantes, cependant, Aurora Serverless peut ne pas être en mesure de trouver un point de mise à l'échelle :

  • Des requêtes ou transactions de longue durée sont en cours.
  • Des tables temporaires ou des verrous de table sont en cours d'utilisation.

Si l'un des cas ci-dessus se produit, Aurora Serverless continue d'essayer de trouver un point de mise à l'échelle afin de pouvoir lancer l'opération de mise à l'échelle (sauf si « Forcer la mise à l'échelle » est activé). Il le fait aussi longtemps qu'il détermine que le cluster de bases de données doit être mis à l'échelle.

Observation du comportement de mise à l'échelle automatique d'Aurora

Notez que dans Aurora Serverless, seul un petit nombre de paramètres peut être modifié et max_connections n'en fait pas partie. Pour tous les autres paramètres de configuration, les clusters Aurora MySQL Serverless utilisent les valeurs par défaut. Pour max_connections, il est contrôlé dynamiquement par Aurora Serverless à l'aide de la formule suivante : 

max_connections =PLUS GRAND({log(DBInstanceClassMemory/805306368)*45},{log(DBInstanceClassMemory/8187281408)*1000})

Où, log est log2 (log base-2) et "DBInstanceClassMemory" est le nombre d'octets de mémoire alloués à la classe d'instance de base de données associée à l'instance de base de données actuelle, moins la mémoire utilisée par les processus Amazon RDS qui gèrent l'instance. Il est assez difficile de prédéterminer la valeur qu'Aurora utilisera, il est donc bon de faire quelques tests pour comprendre comment cette valeur est mise à l'échelle en conséquence.

Voici notre résumé de déploiement Aurora Serverless pour ce test :

Pour cet exemple, j'ai sélectionné au moins 1 unité de capacité Aurora, ce qui équivaut à 2 Go de RAM jusqu'à l'unité de capacité maximale de 256 avec 488 Go de RAM.

Les tests ont été effectués à l'aide de sysbench, en envoyant simplement plusieurs threads jusqu'à ce qu'il atteigne la limite des connexions à la base de données MySQL. Notre première tentative d'envoi simultané de 128 connexions simultanées à la base de données s'est soldée par un échec :

$ sysbench \
/usr/share/sysbench/oltp_read_write.lua \
--report-interval=2 \
--threads=128 \
--delete_inserts=5 \
--time=360 \
--max-requests=0 \
--db-driver=mysql \
--db-ps-mode=disable \
--mysql-host=${_HOST} \
--mysql-user=sbtest \
--mysql-db=sbtest \
--mysql-password=password \
--tables=20 \
--table-size=100000 \
run

La commande ci-dessus a immédiatement renvoyé l'erreur "Trop de connexions" :

FATAL: unable to connect to MySQL server on host 'aurora-sysbench.cluster-cdw9q2wnb00s.ap-southeast-1.rds.amazonaws.com', port 3306, aborting...
FATAL: error 1040: Too many connections

En examinant les paramètres max_connection, nous avons obtenu ce qui suit :

mysql> SELECT @@hostname, @@max_connections;
+----------------+-------------------+
| @@hostname     | @@max_connections |
+----------------+-------------------+
| ip-10-2-56-105 |                90 |
+----------------+-------------------+

Il s'avère que la valeur de départ de max_connections pour notre instance Aurora avec une capacité de base de données (2 Go de RAM) est de 90. C'est en fait bien inférieur à notre valeur anticipée si elle est calculée à l'aide de la formule fournie pour estimer le valeur max_connections :

mysql> SELECT GREATEST({log2(2147483648/805306368)*45},{log2(2147483648/8187281408)*1000});
+------------------------------------------------------------------------------+
| GREATEST({log2(2147483648/805306368)*45},{log2(2147483648/8187281408)*1000}) |
+------------------------------------------------------------------------------+
|                                                                     262.2951 |
+------------------------------------------------------------------------------+

Cela signifie simplement que DBInstanceClassMemory n'est pas égal à la mémoire réelle de l'instance Aurora. Ça doit être bien plus bas. Selon ce fil de discussion, la valeur de la variable est ajustée pour tenir compte de la mémoire déjà utilisée pour les services du système d'exploitation et le démon de gestion RDS.

Néanmoins, changer la valeur max_connections par défaut en quelque chose de plus élevé ne nous aidera pas non plus puisque cette valeur est contrôlée dynamiquement par le cluster Aurora Serverless. Ainsi, nous avons dû réduire la valeur des threads de démarrage de sysbench à 84 car les threads internes d'Aurora réservaient déjà environ 4 à 5 connexions via 'rdsadmin'@'localhost'. De plus, nous avons également besoin d'une connexion supplémentaire pour nos besoins de gestion et de surveillance.

Nous avons donc exécuté la commande suivante à la place (avec --threads=84) :

$ sysbench \
/usr/share/sysbench/oltp_read_write.lua \
--report-interval=2 \
--threads=84 \
--delete_inserts=5 \
--time=600 \
--max-requests=0 \
--db-driver=mysql \
--db-ps-mode=disable \
--mysql-host=${_HOST} \
--mysql-user=sbtest \
--mysql-db=sbtest \
--mysql-password=password \
--tables=20 \
--table-size=100000 \
run

Une fois le test ci-dessus terminé en 10 minutes (--time=600), nous avons réexécuté la même commande et à ce moment-là, certaines variables et certains statuts notables avaient changé, comme indiqué ci-dessous :

mysql> SELECT @@hostname AS hostname, @@max_connections AS max_connections, 
(SELECT VARIABLE_VALUE FROM global_status WHERE VARIABLE_NAME = 'THREADS_CONNECTED') AS threads_connected, 
(SELECT VARIABLE_VALUE FROM global_status WHERE VARIABLE_NAME = 'UPTIME') AS uptime;
+--------------+-----------------+-------------------+--------+
| hostname     | max_connections | threads_connected | uptime |
+--------------+-----------------+-------------------+--------+
| ip-10-2-34-7 |             180 | 179               | 157    |
+--------------+-----------------+-------------------+--------+

Notez que le max_connections a maintenant doublé jusqu'à 180, avec un nom d'hôte différent et une petite disponibilité comme si le serveur venait juste de démarrer. Du point de vue de l'application, il semble qu'une autre "instance de base de données plus grande" ait repris le point de terminaison et configurée avec une variable max_connections différente. En ce qui concerne l'événement Aurora, voici ce qui s'est passé :

Wed, 04 Sep 2019 08:50:56 GMT The DB cluster has scaled from 1 capacity unit to 2 capacity units.

Ensuite, nous avons lancé la même commande sysbench, créant 84 autres connexions au point de terminaison de la base de données. Une fois le test de résistance généré terminé, le serveur évolue automatiquement jusqu'à une capacité de 4 DB, comme indiqué ci-dessous :

mysql> SELECT @@hostname AS hostname, @@max_connections AS max_connections, 
(SELECT VARIABLE_VALUE FROM global_status WHERE VARIABLE_NAME = 'THREADS_CONNECTED') AS threads_connected,
(SELECT VARIABLE_VALUE FROM global_status WHERE VARIABLE_NAME = 'UPTIME') AS uptime;
+---------------+-----------------+-------------------+--------+
| hostname      | max_connections | threads_connected | uptime |
+---------------+-----------------+-------------------+--------+
| ip-10-2-12-75 |             270 | 6                 | 300    |
+---------------+-----------------+-------------------+--------+

Vous pouvez le savoir en regardant les différents nom d'hôte, max_connection et valeur de disponibilité par rapport au précédent. Une autre instance plus grande a "repris" le rôle de l'instance précédente, où la capacité de la base de données était égale à 2. Le point de mise à l'échelle réel est lorsque la charge du serveur a chuté et a presque atteint le sol. Dans notre test, si nous gardions la connexion pleine et la charge de la base de données constamment élevée, la mise à l'échelle automatique n'aurait pas lieu.

En regardant les deux captures d'écran ci-dessous, nous pouvons dire que la mise à l'échelle ne se produit que lorsque notre Sysbench a terminé son test de résistance pendant 600 secondes, car c'est le point le plus sûr pour effectuer une mise à l'échelle automatique.

Capacité de base de données sans serveur   Utilisation du processeur Utilisation du processeur

En regardant les événements Aurora, les événements suivants se sont produits :

Wed, 04 Sep 2019 16:25:00 GMT Scaling DB cluster from 4 capacity units to 2 capacity units for this reason: Autoscaling.
Wed, 04 Sep 2019 16:25:05 GMT The DB cluster has scaled from 4 capacity units to 2 capacity units.

Enfin, nous avons généré beaucoup plus de connexions jusqu'à presque 270 et avons attendu qu'il se termine, pour entrer dans la capacité de 8 DB :

mysql> SELECT @@hostname as hostname, @@max_connections AS max_connections, 
(SELECT VARIABLE_VALUE FROM global_status WHERE VARIABLE_NAME = 'THREADS_CONNECTED') AS threads_connected,
(SELECT VARIABLE_VALUE FROM global_status WHERE VARIABLE_NAME = 'UPTIME') AS uptime;
+---------------+-----------------+-------------------+--------+
| hostname      | max_connections | threads_connected | uptime |
+---------------+-----------------+-------------------+--------+
| ip-10-2-72-12 |            1000 | 144               | 230    |
+---------------+-----------------+-------------------+--------+

Dans l'instance de 8 unités de capacité, la valeur MySQL max_connections est maintenant de 1000. Nous avons répété des étapes similaires en maximisant les connexions à la base de données et jusqu'à la limite de 256 unités de capacité. Le tableau suivant résume l'unité de capacité globale de la base de données par rapport à la valeur max_connections dans nos tests jusqu'à la capacité maximale de la base de données :

Mise à l'échelle forcée

Comme mentionné ci-dessus, Aurora Serverless n'effectuera une mise à l'échelle automatique que lorsqu'il est sûr de le faire. Cependant, l'utilisateur a la possibilité de forcer la mise à l'échelle de la capacité de la base de données à se produire immédiatement en cochant la case Forcer la mise à l'échelle sous l'option "Configuration de la mise à l'échelle supplémentaire" :

Lorsque la mise à l'échelle forcée est activée, la mise à l'échelle se produit dès que le délai d'attente est écoulé atteint qui est de 300 secondes. Ce comportement peut entraîner une interruption de la base de données de votre application où les connexions actives à la base de données peuvent être supprimées. Nous avons observé l'erreur suivante lorsque la mise à l'échelle automatique forcée s'est produite après l'expiration du délai :

FATAL: mysql_drv_query() returned error 1105 (The last transaction was aborted due to an unknown error. Please retry.) for query 'SELECT c FROM sbtest19 WHERE id=52824'
FATAL: `thread_run' function failed: /usr/share/sysbench/oltp_common.lua:419: SQL error, errno = 1105, state = 'HY000': The last transaction was aborted due to an unknown error. Please retry.

Ce qui précède signifie simplement qu'au lieu de trouver le bon moment pour évoluer, Aurora Serverless force le remplacement de l'instance à avoir lieu immédiatement après avoir atteint son délai d'expiration, ce qui entraîne l'abandon et la restauration des transactions. Réessayer la requête abandonnée pour la deuxième fois résoudra probablement le problème. Cette configuration peut être utilisée si votre application est résistante aux interruptions de connexion.

Résumé

La mise à l'échelle automatique sans serveur d'Amazon Aurora est une solution de mise à l'échelle verticale, dans laquelle une instance plus puissante prend le contrôle d'une instance inférieure, en utilisant efficacement la technologie de stockage partagé Aurora sous-jacente. Par défaut, l'opération de mise à l'échelle automatique est effectuée de manière transparente, Aurora trouvant un point de mise à l'échelle sûr pour effectuer le changement d'instance. On a la possibilité de forcer la mise à l'échelle automatique avec des risques d'abandon des connexions de base de données actives.