24. Haute disponibilité et répartition de charge

Les serveurs de bases de données peuvent travailler ensemble pour permettre à un second serveur de prendre rapidement la main si le serveur principal échoue (haute disponibilité, high availability), ou pour permettre à plusieurs serveurs de servir les mêmes données (répartition de charge load balancing). Idéalement, les serveurs de bases de données peuvent travailler ensemble sans jointure. Les serveurs web traitant des pages web statiques peuvent travailler ensemble assez facilement en répartissant la charge des requêtes web sur plusieurs machines. De même, les serveurs de bases de données en lecture seule peuvent aussi travailler ensemble assez facilement. Malheureusement, la plupart des serveurs de bases de données ont des requêtes de lecture/écriture et ce type de serveurs sont bien plus difficile à faire travailler ensemble. Ceci est dû au fait qu'il faut placer une seule fois sur chaque serveur les données en lecture seule et qu'une écriture sur un serveur doit être propagée à tous les serveurs pour que les futures lectures sur ces serveurs renvoient des résulats cohérents.

Ce problème de synchronisation est la difficulté fondamentale pour les serveurs travaillant ensemble. Comme il n'existe pas qu'une seule solution qui élimine l'impact du problème de synchronisation pour tous les cas pratiques, il existe plusieurs solutions. Chaque solution répond à ce problème d'une façon différente et minimise cet impact pour une charge spécifique.

Certaines solutions gèrent la synchronisation en autorisant les modifications des données sur un seul serveur. Les serveurs qui peuvent modifier les données sont appelés serveurs lecture/écriture ou serveurs maîtres. Les serveurs qui peuvent répondre aux requêtes en lecture seule sont appelés des serveurs esclaves. Les serveurs qui ne sont pas accessibles tant qu'ils ne se sont pas transformés en serveurs maîtres sont appelées des serveurs en attente (standby servers).

Certaines solutions de failover et de répartition de charge sont synchrones, signifiant qu'une transaction de modification de données n'est pas considérée validée tant que tous les serveurs n'ont pas validés la transaction. Ceci garantie qu'un failover ne perdra pas de données et que tous les serveurs en répartition de charge renverront des résultats cohérents quel que soit le serveur interrogé. En contraste, les solutions asynchrones autorisent un délai entre le moment de la validation et sa propagation aux autres serveurs, ceci qui comporte le risque que certaines transactions soient perdues dans le basculement à un serveur de sauvegarde et que les serveurs en répartition de charge pourraient renvoyer des données obsolètes. La communication asynchrone est utilisée quand la version synchrone est trop lente.

Les solutions peuvent aussi être catégorisées par leur granularité. Certaines solutions peuvent seulement gérer un serveur de bases entier alors que d'autres autorisent un contrôle par table ou par base.

Les performances doivent être considérées dans tout choix d'une solution de failover ou de répartition de charges. Il y a généralement un compromis à trouver entre les fonctionnalités et les performances. Par exemple, une solution complètement synchrone sur un réseau lent pourrait diviser les performances par plus que deux alors qu'une solution asynchrone pourrait avoir un impact minimal sur les performances.

Le reste de cette section souligne différentes solutions de failover, de réplication et de répartition de charge.

Failover sur disque partagé

Le failover sur disque partagé évite la surcharge dûe à la synchronisation en ayant seulement une copie de la base de données. Cela utilise un seul ensemble de disques partagé entre plusieurs serveurs. Si le serveur principal échoue, le serveur en attente est capable de monter et lancer la base comme s'il récupérait après un d'un arrêt brutal. Ceci permet un failover rapide sans perte de données.

Cette fonctionnalité de matériel partagé est commune aux périphériques de stockage en réseau. Utiliser un système de fichiers réseau est aussi possible bien qu'une grande attention doit être portée au système de fichiers pour s'assurer qu'il a un comportement POSIX complet. Une limitation significative de cette méthode est que si les disques ont un problème ou sont corrompus, les serveurs primaire et en attente sont tous les deux non fonctionnels. Un autre problème est que le serveur en attente ne devra jamais accéder au stockage partagé tant que le serveur principal est en cours d'exécution.

Il est aussi possible d'utiliser cette fonctionnalité d'une autre façon avec une réplication du système de fichiers, où toutes les modifications d'un système de fichiers sont renvoyées sur un système de fichiers situé sur un autre ordinateur. La seule restriction est que ce miroir doit être construit d'une façon qui assure le fait que le serveur en attente a une version cohérente du système de fichiers -- spécifiquement, les écritures sur le serveur en attente doivent être réalisées dans le même ordre que celles sur le maître. DRBD est une solution populaire de réplication de systèmes de fichiers pour Linux.

Warm Standby en utilisant PITR

Un serveur warm standby (voir Section 23.4, « Serveurs de secours semi-automatique (Warm Standby) pour la haute disponibilité ») peut conserver sa cohérence en lisant un flux d'enregistrements de WAL. Si le serveur principal échoue, le serveur warm standby contient pratiquement toutes les données du serveur principal et peut rapidement devenir le nouveau serveur maître. Ceci est asynchrone et peut seulement se faire pour le serveur de bases entier.

Réplication maître/esclave

Une configuration de réplication maître/esclave envoie toutes les requêtes de modification de données au serveur maître. Ce serveur envoie les modifications de données de façon asynchrone au serveur esclave. L'esclave peut répondre aux requêtes en lecture seule alors que le serveur maître est en cours d'exécution. Le serveur esclave est idéal pour les requêtes vers un entrepôt de données.

Slony-I est un exemple de ce type de réplication, avec une granularité par table et un support des esclaves multiple. Comme il met à jour le serveur esclave de façon asynchrone (par lots), il existe une possibilité de perte de données pendant un failover.

Middleware de réplication basés sur les instructions

Avec les middleware de réplication basés sur les instructions, un programme intercepte chaque requête SQL et l'envoie à un ou tous les serveurs. Chaque serveur opère indépendamment. Les requêtes en lecture/écriture sont envoyées à tous les serveurs alors que les requêtes en lecture seule peuvent seulement être envoyées à un seul serveur permettant la distribution du vrai travail.

Si les requêtes sont envoyées sans modification, les fonctions comme random(), CURRENT_TIMESTAMP ainsi que les séquences auront des valeurs différentes sur des serveurs différents. Ceci est dû au fait que chaque serveur opère indépendamment et que les requêtes SQL sont envoyées à tous (et non pas les données modifiées). Si ceci est inacceptable, soit le middleware soit l'application doivent demander ces valeurs à partir d'un seul serveur, puis les utiliser dans des requêtes d'écriture. De plus, une attention doit être portée à ce que toutes les transactions soient validées soit annulées sur tous les serveurs par exemple en utilisant la validation en deux phases (PREPARE TRANSACTION et COMMIT PREPARED. Pgpool et Sequoia sont un exemple de ce type de réplication.

Réplication synchrone multi-maîtres

Dans les réplications synchrones multi-maîtres, chaque serveur peut accepter les requêtes en écriture. Les données modifiées sont transmises du serveur original à tous les autres serveurs avant validation de chaque transaction. Une activité importante en écriture peut être la cause d'un verrouillage excessif conduisant à un effondrement des performances. En fait, la performance en écriture est souvent pis que celle d'un simple serveur. Les requêtes en lecture peuvent être envoyées à tous les serveurs. Certaines implantations utilisent les disques partagés pour réduire la surcharge de communication. La réplication synchrone multi-maîtres est bien meilleure principalement pour de grosses charges de travail en lecture bien que son gros avantage est que tout serveur peut accepter des requêtes d'écriture -- il n'est pas nécessaire de partitionner les travaux entre les serveurs maîtres et esclaves et, comme les modifications de données sont envoyées d'un serveur à un autre, il n'y a pas de problème avec les fonctions non déterministiques comme random().

PostgreSQL™ n'offre pas ce type de réplication, bien que la validation en deux phases de PostgreSQL™ (PREPARE TRANSACTION et COMMIT PREPARED) peut être utilisée pour implémenter cela dans une application ou un middleware.

Réplication asynchrone à plusieurs maîtres

Pour les serveurs qui ne sont pas connectés en permanence, comme les portables ou les serveurs distants, garder la cohérence des données entre les serveurs est un challenge. En utilisant la réplication asynchrone à plusieurs maîtres, chaque serveur fonctionne indépendamment et communique périodiquement avec les autres serveurs pour identifier les transactions en conflit. Les conflits peuvent être résolus par les utilisateurs ou par des règles de résolution.

Partitionnement de données

Le partitionnement des données divise les tables en ensemble de données. Chaque ensemble peut être modifié par un seul serveur. Par exemple, les données peuvent être partitionnées par bureaux, par exemple Londres et Paris avec un serveur dans chaque bureau. Si les requêtes combinant les données de Londres et de Paris sont nécessaures, une application peut envoyer des requêtes sur les deux serveurs ou la réplication maître/esclave peut être utilisée pour conserver sur chaque serveur une copie en lecture seule des données de l'autre bureau.

Exécution de requêtes en parallèle sur plusieurs serveurs

Un grand nombre des solutions ci-dessus permettent à plusieurs serveurs de répondre à plusieurs requêtes mais aucune ne permet à une seule requête d'être exécutée sur plusieurs serveurs pour se terminer plus rapidement. Cette solution autorise le travail en commun de plusieurs serveurs sur une seule requête. Ceci s'accomplit habituellement en divisant les données entre les serveurs et en ayant chaque serveur qui exécute une partie de la requête pour renvoyer les résultats à un serveur central qui les combinera et les renverra à l'utilisateur. Pgpool-II a cette capacité.

Solutions commerciales

Comme PostgreSQL™ est libre et facilement extensible, certaines sociétés ont pris PostgreSQL™ et créé des solutions propriétaires avec leur propres fonctionnalités de failover, réplication et répartition de charges.