Connexions persistantes aux bases de données

Qu'est-ce que les connexions persistantes ?

Les connexions persistantes aux bases de données SQL sont des connexions qui ne se referment pas à la fin du script. Lorsqu'une connexion persistante est demandée, PHP s'assure qu'il n'y a pas une autre connexion identique (qui serait ouverte précédemment, avec le même nom d'hôte, d'utilisateur et le même mot de passe), et si une telle connexion existe, elle est utilisée ; sinon, elle est créée. Une connexion identique est une connexion qui a ouvert le même hôte, avec le même nom et le même mot de passe (s'ils sont nécessaires).

Il n'y a pas de méthode pour demander une connexion spécifique, ou garantir que vous obtenez une connexion existante ou une toute nouvelle (si toutes les connexions sont utilisées, ou si la requête est servie par un autre processus, qui a un ensemble de connexions séparé).

Cela signifie que vous ne pouvez pas utiliser les connexions persistantes PHP pour, par exemple :

  • assigner une session de base de données spécifique à un utilisateur web spécifique
  • créer une grande transaction à travers plusieurs requêtes
  • initier une requête sur une demande et collecter les résultats sur une autre

Les connexions persistantes ne vous donnent aucune fonctionnalité qui n'était pas possible avec des connexions non persistantes.

Requêtes Web

Il existe deux façons pour votre serveur web d'utiliser PHP pour générer des pages web :

La première est d'utiliser PHP comme un CGI (Common Interface Gateway). Lorsque PHP fonctionne de cette manière, une instance de l'interpréteur PHP est créée puis détruite pour chaque page demandée. Étant donné que cet interpréteur est détruit après chaque requête, toutes les ressources acquises (comme une connexion à une base SQL), sont purement et simplement détruites. Dans ce cas vous ne gagnez rien à utiliser des connexions persistantes - elles ne persistent tout simplement pas.

La deuxième méthode, de loin la plus prisée, est d'exécuter PHP-FPM, ou PHP sous la forme d'un module sur un serveur multiprocessus, ce qui revient à dire : Apache. Ces configurations ont généralement un processus (le parent) qui coordonne un ensemble de processus fils, qui servent les fichiers. Lorsque les requêtes parviennent depuis un client, elles sont transmises à un fils disponible. Cela signifie que si un client fait une deuxième requête, il peut être servi par un processus client différent du premier. Les connexions persistantes vous permettent alors de ne vous connecter à une base SQL que la première fois. Lors des connexions ultérieures, les processus fils pourront réutiliser la connexion ouverte précédemment.

Note:

Vous pouvez vérifier quelle méthode vos requêtes web utilisent en vérifiant la valeur de "Server API" dans la sortie de phpinfo() ou la valeur de PHP_SAPI, exécutée depuis une requête web.

Si la valeur de Server API est "CGI" ou "CLI", alors les connexions persistantes ne seront pas utilisées entre les requêtes. Pour toute autre valeur, les connexions persistantes persisteront après chaque requête.

Processus en ligne de commande

Comme PHP en ligne de commande utilise un nouveau processus pour chaque script, les connexions persistantes ne sont pas partagées entre les scripts en ligne de commande, donc il n'y a aucun intérêt à les utiliser dans des scripts transitoires tels que les crons ou les commandes. Cependant, elles peuvent être utiles si, par exemple, vous écrivez un serveur d'applications de longue durée qui sert de nombreuses requêtes ou tâches et que chacune peut avoir besoin de sa propre connexion à la base de données.

Pourquoi les utiliser ?

Les connexions persistantes sont utiles si le coût de création d'une liaison vers votre serveur SQL est élevé. Que ce coût soit réellement élevé ou pas ceci dépend de nombreux facteurs : le type de base de données, cette base est-elle sur le même serveur ou pas, quelle est la charge du serveur de base de données, etc. Si le temps de connexion est long, les connexions persistantes seront bien utiles, car une fois ouverte par un processus fils, la connexion est réutilisable sans avoir à se reconnecter. Si vous avez 20 processus fils, il suffit d'avoir 20 connexions persistantes ouvertes, une par fils.

Inconvénients potentiels : limites de connexion

Notez que les connexions persistantes ont quelques inconvénients si vous hébergez une base de données dont le nombre maximal de connexion risque d'être atteint par les connexions persistantes. Si votre base de données accepte jusqu'à 16 connexions peut être rapidement submergée.

Les connexions persistantes augmenteront généralement le nombre de connexions ouvertes à un moment donné parce que les travailleurs inactifs conserveront les connexions pour les requêtes précédentes qu'ils ont servies. Si un grand nombre de travailleurs est lancé pour gérer un afflux de requêtes, les connexions qu'ils ont ouvertes resteront jusqu'à ce que le travailleur soit tué ou que le serveur de base de données ferme la connexion.

Assurez-vous que le nombre maximal de connexions autorisées par le serveur de base de données est supérieur au nombre maximal de travailleurs de requêtes web (plus toute autre utilisation telle que les crons ou les connexions administratives).

Vérifiez votre documentation de base de données pour des informations sur la gestion des connexions abandonnées ou inactives (timeouts). Des timeouts longs peuvent augmenter considérablement le nombre de connexions persistantes ouvertes à un moment donné.

Inconvénients potentiels : Maintien de l'état de connexion

Certaines extensions de base de données effectuent un nettoyage automatique lorsque la connexion est réutilisée ; d'autres laissent cette tâche à la discrétion du développeur d'application. En fonction de l'extension de base de données choisie et de la conception de l'application, un nettoyage manuel peut être nécessaire avant la fin du script. Les modifications qui peuvent laisser les connexions dans un état inattendu incluent :

  • Base de données sélectionnée / par défaut
  • Verrous de table
  • Transactions non commises
  • Tables temporaires
  • Paramètres ou fonctionnalités spécifiques à la connexion telles que le profilage

Les verrous de table et les transactions qui ne sont pas nettoyés ou fermés peuvent entraîner le blocage indéfini d'autres requêtes et/ou provoquer des modifications inattendues lors de la réutilisation ultérieure de la connexion.

Avoir la mauvaise base de données sélectionnée entraînera la réutilisation de la connexion incapable d'exécuter les requêtes suivantes comme prévu (ou de les exécuter sur la mauvaise base de données si les schémas sont suffisamment similaires).

Si les tables temporaires ne sont pas nettoyées, les requêtes suivantes ne pourront pas recréer la même table.

Vous pouvez implémenter le nettoyage en utilisant des destructeurs de classe ou register_shutdown_function(). Vous pouvez également envisager des proxies de mise en pool de connexions dédiés qui incluent cela dans leur fonctionnalité.

Derniers mots

Étant donné leur comportement et les inconvénients potentiels décrits ci-dessus, vous ne devez pas utiliser les connexions persistantes sans une réflexion approfondie. Elles ne doivent pas être utilisées sans mettre en œuvre des modifications supplémentaires dans votre application et une configuration soigneuse de votre serveur de base de données et de votre serveur web et/ou PHP-FPM.

Considérez des solutions alternatives telles que l'investigation et la correction des causes des surcoûts de création de connexion (par exemple, la désactivation des recherches DNS inverses sur le serveur de base de données), ou des proxies de mise en pool de connexions dédiés.

Pour les API web à fort volume, envisagez d'utiliser des runtimes alternatifs ou des serveurs d'applications de longue durée.