Mission Mysql : base temps réel

Cette mission s’est étalée sur plusieurs mois et concerne autant les migration que les opérations de performance.

Le client utilise deux bases principales de tailles assez importante (un peu plus de 1 milliard de rangs chacune) constituées de nombreuses tables accumulant des données en temps réel et implantées sur deux serveurs avec un système de fail over. Certaines des tables devenaient délicates à gérer du fait de leur volume (plusieurs centaines de millions de rangs) et leur taille globale pénalisait les performances. La purge de ces tables était "manuelle" et obligeait à des manoeuvres complexes pendant le peu d'heures creuses pour ne pas altérer le service aux clients.

La première activité a été de mesurer la charge des différents éléments des serveurs qui dataient un peu :

  • Mémoire → 64 Go seulement et totalement saturée.

  • Disques → des disques classiques en RAID 10 qui arrivent à saturation en IO/s.

  • Processeurs → 16 coeurs (32 threads) à 2 GHz dont la charge arrivait assez souvent à dépasser 80 %.

  • Réseau → cette partie n’était pas un point de saturation et les quatre cartes réseau (10GB/s) ne présentaient aucun signe de saturation.

Une première action rapide a été de « gonfler » la mémoire pour pouvoir augmenter la taille du cache de Mysql/MariaDB. Le passage à 192Go (maximum possible sur ce type de machine) de mémoire a été assez rapidement exécuté et a permis de soulager les accès disques grâce à l’efficacité du cache.

La deuxième action entreprise a été d’éclater les plus grosses tables en :

  • Une partie « vivante » (celle utilisée en temps réel) limitée à environ 5/8 jours de données.

  • Une partie « historique » destinée principalement à la gestion. Cette partie est elle même éclatée en deux tables,

    • une partie « gestion » avec une conservation de 4 à 12 semaines

    • une partie "archives" conservée sous forme de table active pendant deux à 6 mois. Les données sont ensuite exportées vers des machines d’archivage pour exploitation ultérieure (marketing, statistiques, analyse de données ...)

Des procédures automatiques de purge journalières reportent les données des tables actives vers les tables de gestion, d’autres procédures hebdomadaires reportent les données de gestion vers les tables d’archivage. Enfin une action mensuelle exporte les données "désuètes" des tables d'archivage vers des machines spécialisées dans l'archivage. Ces données sont d'ailleurs exploitées par l'équipe des "data scientists".
Les traitements hebdomadaires sont répartis sur tous les jours de la semaine afin d'obtenir une charge régulière.
Ces procédures (Sql) sont déclenchées par l'ordonnanceur propre à la base de données par l'intermédiaire d'Events. Ce point a été modifié par la suite en utilisant des scripts assurant le passage en séquentiel des traitements car leur durée peut être assez variable et qu'il est bon d'éviter une trop grosse charge instantanée provoquée par le recouvrement dans le temps de deux traitements "lourds".

L’utilisation de tables partitionnées permet de gérer assez rapidement les données qui sont « rangées » par date dans des partitions différentes à l'aide de fonctions dédiées déclenchées par des triggers "ON INSERT". Après le report des données vers le niveau « inférieur » la « purge » d’une période, effectuée par troncature de la partition concernée est donc quasiment immédiate et ne nécessite que peu d'écritures dans les logs ce qui est favorable au fonctionnement en mode cluster maître/maître avec gestion automatique du basculement en cas d'incident (utilisation de keepalived).
Ceci présente par ailleurs un intérêt au niveau de la performance car les données dans les partitions n’ont pas le temps de « vieillir » et de se désorganiser puisqu'elles sont tronquées et recréées périodiquement.

La troisième décision a été d'étudier et de lancer la mise en place de nouveaux serveurs plus rapides avec des SSD NVME en RAID10 pour obtenir une performance maximale. On est arrivé ainsi sur ces machines "de course" à dépasser largement 1 Go/seconde en écriture sur les disques, les logs de Mysql ne sont donc plus un goulot d'étranglement. Un seul de ces serveurs doit être capable d'assurer le service aux clients.

Au passage il a été décidé de migrer de Mysql 5.5 (qui date un peu) vers MariaDB 10.1 en mode maître/maître sur deux serveurs placés dans deux hébergements différents reliés par un lien à 10Gb/s pour assurer tant la sécurité des données que la qualité du service au client.
De même toutes les cartes réseau sont redondées et fonctionnent en agrégats.

L’un des deux serveurs est utilisé en lecture/écriture, l’autre essentiellement en lecture pour répondre aux besoins de la gestion (surtout de gros flots de lecture). Cette méthode permet de préserver les performances des utilisateurs "temps réel" sans interdire les aux gestionnaires et aux commerciaux de renoncer à leurs tableaux de bord friands de "grosses requêtes" .
La sécurité est assurée par la possibilité de « basculer » l’adresse virtuelle donnant l’accès en lecture/écriture d'un système à l'autre

Un nouveau système de backup a été mis en place avec report systématique des éléments nécessaires à une reprise sur des machines différentes dédiées au stockage des archives (transport des données effectué par Netbackup) afin de pouvoir "repartir" le plus rapidement possible en cas de problème grave sur un serveur. Par ailleurs un système de sauvegarde "semi-online" utilisant les propriétés des "snapshots" a été mis en place; l'interruption de service est ainsi très limitée, un blocage par "lock" lors de la prise du snapshot, unlock dès que le snapshot est OK (durée inférieure à une minute), est suivi du démarrage d'une instance MariaDB "auxiliaire" (démarrée sur le snapshot) qui réalise l'export de données figées.
J'ai d'ailleurs effectué une seconde mission pour reconstituer un serveur crashé, la reconstruction n'a duré que quelques heures. Cette deuxième mission a été prolongée afin de compléter les modules de "mise en historique" pour quelques nouvelles tables ayant une croissance importante, l'une d'entre elles comportait des années de données et dépassait les 200 GO avec un énorme "blob" json dans une colonne.
Une autre partie de la mission a été d'effectuer un déplacement des serveurs vers un nouvel hébergement sans interrompre le service au client ni rester "longtemps" sans la sécurité apportée par le deuxième serveur en mode maître/maî
tre.