188 votes

Quels sont les inconvénients de l'utilisation persistante de connexion en PDO

En PDO, une connexion peut être effectué de façon continue à l'aide de l' PDO::ATTR_PERSISTENT d'attribut. Selon le manuel php -

Les connexions persistantes ne sont pas fermées à la fin du script, mais sont mises en cache et ré-utilisé lorsqu'un autre script demande une connexion à l'aide les mêmes informations d'identification. La persistance de la cache de connexion vous permet de vous éviter d'établir une nouvelle connexion à chaque fois un script a besoin de parler à une base de données, résultant en un web plus rapide application.

Le manuel recommande de ne pas utiliser une connexion permanente tout en utilisant PDO pilote ODBC, car il peut nuire à la Connexion ODBC processus de mise en commun.

Donc, apparemment, il semble y avoir aucun inconvénients de l'utilisation persistante de connexion en PDO, sauf dans le dernier cas. Cependant., Je voudrais savoir si il y a d'autres inconvénients de l'utilisation de ce mécanisme, c'est à dire, une situation où ce mécanisme résulte en une dégradation des performances ou quelque chose comme ça.

303voto

Charles Points 33585

Veuillez vous assurer de lire cette réponse ci-dessous, qui décrit en détail les moyens d'en atténuer les problèmes décrits ici.


Les mêmes inconvénients existent pas utiliser PDO comme avec toutes les autres bases de données PHP interface qui ne les connexions persistantes: si votre script ne se termine de façon inattendue au milieu des opérations de base de données, la requête suivante qui obtient la gauche plus de connexion reprendra là où les morts script laissé. La connexion est tenu d'ouvrir dans le gestionnaire de processus de niveau (Apache pour mod_php, l'actuel processus FastCGI si vous êtes à l'aide de FastCGI, etc), pas au niveau PHP et PHP ne veut pas dire que le processus parent de laisser la connexion meurent lorsque le script se termine anormalement.

Si les morts script tables verrouillées, ces tables restera verrouillé jusqu'à ce que la connexion meurt ou le script suivant qui obtient la connexion déverrouille les tables de lui-même.

Si les morts script a été dans le milieu d'une transaction, qui peuvent bloquer une multitude de tables jusqu'à l'impasse de la minuterie de coups de pied dans, et même alors, le blocage de la minuterie peut tuer la plus récente demande de la place de l'ancienne demande qui est à l'origine du problème.

Si les morts script a été dans le milieu d'une transaction, le script suivant qui obtient la connexion obtient également l'état de la transaction. Il est très possible (en fonction de la conception de votre application) que le script suivant peut pas réellement jamais essayez de valider la transaction existante, ou de commettre un quand il ne devrait pas avoir, ou faire reculer quand il ne devrait pas avoir.

Ce n'est que la partie émergée de l'iceberg. Cela peut être atténué dans une certaine mesure, en essayant toujours de nettoyer après une sale connexion sur chaque demande de script, mais qui peut être une douleur selon la base de données. Sauf si vous avez identifié la création de connexions de base de données que la seule chose qui est un goulot d'étranglement dans votre script (ce qui signifie que vous avez fait de profilage de code à l'aide de xdebug et/ou de xhprof), vous ne devez pas considérer les connexions persistantes comme une solution à quoi que ce soit.

En outre, la plupart des bases de données modernes (y compris PostgreSQL) ont leurs propres moyens privilégiés d'effectuer le regroupement de connexions qui n'ont pas l'immédiat inconvénients de la plaine de vanille en PHP les connexions persistantes ne.


Pour clarifier un point, nous sommes d'utiliser des connexions persistantes sur mon lieu de travail, mais pas par choix. Nous avons été rencontrer bizarre le comportement de connexion, où la connexion initiale à partir de notre serveur d'application à notre serveur de base de données a été prise exactement trois secondes, quand il devait prendre une fraction d'une fraction de seconde. Nous pensons que c'est un bug du noyau. Nous avons renoncé à essayer de le dépanner car il s'est produit de façon aléatoire et ne peut être reproduit à la demande, et notre externalisée IL n'a pas eu le béton capacité à suivre.

Quand même, quand les gens dans le magasin sont de traitement de quelques centaines entrant parties, et chaque partie prend trois secondes et demie au lieu d'une demi-seconde, nous avons dû prendre des mesures avant qu'elles ne enlevé à nous tous et à nous aider. Ainsi, nous avons montré quelques morceaux sur le home-grown ERP/CRM/CMS monstruosité et connu toutes les horreurs de la persistance des connexions de première main. Il nous a fallu des semaines pour traquer les moindres petits problèmes et comportement bizarre qui s'est passé apparemment au hasard. Il s'est avéré que ces une fois par semaine erreurs fatales que nos utilisateurs avec diligence pressé de notre application ont été en laissant tables verrouillées, le nombre de transactions abandonnées et d'autres malheureux déglingués unis.

Cette sob-histoire a un point: Il a cassé des choses que nous n'avons jamais pensé à la pause, tout cela au nom de la performance. Le compromis n'était pas la peine, et nous attendons avec impatience le jour où nous pourrons revenir à la normale des connexions sans une émeute de nos utilisateurs.

50voto

Prashant Points 171

En réponse à Charles problème ci-dessus,

De : http://www.php.net/manual/en/mysqli.quickstart.connections.php -

Une commune se plaignent les connexions persistantes, c'est que leur état n'est pas réinitialisé avant de les réutiliser. Par exemple, les ouvrir et les transactions inachevées ne sont pas automatiquement annulées. Mais aussi, l'autorisation des modifications qui s'est passé entre le moment où la connexion est mise dans la piscine et en les réutilisant ne sont pas pris en compte. Cela peut être vu comme un effet non désiré. Au contraire, le nom persistante, peut être compris comme une promesse que l'état est persistant.

L'extension mysqli prend en charge deux interprétations d'une connexion persistante: l'état a persisté, et de l'état de réinitialisation avant de les réutiliser. La valeur par défaut est réinitialisé. Avant qu'une connexion persistante est réutilisé, l'extension mysqli appelle implicitement mysqli_change_user() pour réinitialiser l'état. La persistance de la connexion apparaît à l'utilisateur comme si elle venait juste d'être ouverte. Aucune trace d'une utilisation précédente sont visibles.

La fonction mysqli_change_user() est une opération coûteuse. Pour de meilleures performances, les utilisateurs peuvent vouloir compiler l'extension avec le drapeau de compilation MYSQLI_NO_CHANGE_USER_ON_PCONNECT.

Il est laissé à l'utilisateur de choisir entre un comportement sécuritaire et de meilleures performances. Les deux sont valables optimisation des objectifs. Pour la facilité d'utilisation, le comportement sécurisé a été fait par défaut au détriment de la performance maximale.

15voto

Kaii Points 2099

Les connexions persistantes sont une bonne idée seulement quand elle prend une (relativement) long temps de connexion à votre base de données. Aujourd'hui, c'est presque jamais le cas. Le plus grand inconvénient pour les connexions persistantes, c'est qu'il limite le nombre d'utilisateurs, vous pouvez avoir la navigation de votre site: si MySQL est configuré pour autoriser uniquement les 10 connexions simultanées à la fois, puis lors de la 11e personne essaie de parcourir votre site, il ne fonctionnera pas pour eux.

AOP ne pas gérer la persistance. Le pilote MySQL. Il réutilise les connexions lorsque: a) ils sont disponibles et le host/user/mot de passe/la base de données. Si aucun changement alors il ne sera pas réutiliser une connexion. Le meilleur des cas, l'effet net est que ces connexions que vous avez sera démarré et arrêté si souvent parce que vous avez plusieurs utilisateurs sur le site et de les rendre persistantes ne fait pas de bien du tout.

La chose à comprendre au sujet des connexions persistantes, c'est que vous ne devriez PAS les utiliser dans la plupart des applications web. Leur son est alléchant, mais ils sont dangereux et assez inutile.

Je suis sûr qu'il y a d'autres fils sur ce sujet, mais une connexion persistante est dangereux parce qu'il persiste entre les demandes. Si, par exemple, vous pouvez verrouiller une table lors d'une demande et ne parviennent pas à débloquer alors que la table va reste bloqué indéfiniment. Les connexions persistantes sont également assez inutile pour 99% de vos apps, car vous n'avez aucun moyen de savoir si la connexion même sera utilisé entre les différentes demandes. Chaque thread va avoir son propre ensemble de connexions persistantes et vous n'avez aucun moyen de contrôle sur le thread qui va gérer ce qui demandes.

La procédure bibliothèque mysql de PHP, dispose d'une fonction en vertu de laquelle les appels ultérieurs à mysql_connect sera de retour le même lien, plutôt que d'ouvrir une autre connexion (Comme on pourrait s'y attendre). Cela n'a rien à voir avec les connexions persistantes et est spécifique à la base de la bibliothèque. AOP ne présentent pas de tels comportements


Ressources Lien : lien

En Général, vous pouvez l'utiliser comme un brouillon "règles"::

OUI, utiliser des connexions persistantes, si:

  • Il y a seulement quelques applications/utilisateurs accédant à la base de données, c'est à dire vous n'entraînera pas de 200 ouverte (mais probablement ralenti) connexions, parce qu'il y a 200 différents utilisateurs partagés sur le même hôte.
  • La base de données est en cours d'exécution sur un autre serveur que vous accédez à plus de le réseau

  • Un (une) application accède à la base de données très souvent

PAS de, ne pas utiliser des connexions persistantes, si:

  • Votre demande nécessite un accès à la base de données 100 fois par heure.

  • Vous avez beaucoup, beaucoup de serveurs web d'accéder à un serveur de base de données

Utiliser des connexions persistantes sont considérables plus rapide, surtout si vous êtes accédant à la base de données sur un réseau. Il ne fait pas tellement de différence si la base de données est en cours d'exécution sur la même machine, mais il est encore un peu plus vite. Cependant - comme le nom l'indique, la connexion est persistante, c'est à dire qu'elle reste ouverte, même si elle n'est pas utilisée.

Le problème c'est que dans "configuration par défaut", MySQL ne permet de 1000 parallèle "des canaux à ciel ouvert". Après cela, les nouvelles connexions sont refusées (Vous pouvez modifier ce paramètre). Donc, si vous avez, disons, 20 Serveurs avec chacun de 100 Clients sur eux, et chacun d'eux a juste une page par heure, un simple calcul vous montrera que vous aurez besoin de 2000 connexions parallèles à la base de données. Cela ne marchera pas.

Ergo: Seule l'utilisation pour les applications avec beaucoup de demandes.

14voto

Gunnar Bernstein Points 853

Sur mes tests, j'ai eu un temps de connexion de plus d'une seconde à mon localhost, donc en supposant que je doit utiliser une connexion persistante. D'autres tests ont montré qu'il avait un problème avec "localhost":

Des résultats de Test en secondes (mesurée par php microtime):

  • hébergée sur le web: connectDB: 0.0038912296295166
  • localhost: connectDB: 1.0214691162109 (plus d'une seconde: ne pas utiliser localhost!)
  • 127.0.0.1: connectDB: 0.00097203254699707

Fait intéressant: Le code suivant est tout aussi rapide que d'utiliser 127.0.0.1:

$host = gethostbyname('localhost');
// echo "<p>$host</p>";
$db = new PDO("mysql:host=$host;dbname=" . DATABASE . ';charset=utf8', $username, $password,
    array(PDO::ATTR_EMULATE_PREPARES => false,
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));

6voto

Stephen Points 1699

Les connexions persistantes devrait donner un appréciable gain de performance. Je suis en désaccord avec l'examen que vous devriez Éviter "de" la persistance..

Il semble que les plaintes ci-dessus sont conduit par quelqu'un à l'aide de MyIASM tables et le piratage dans leurs propres versions de transactions en saisissant les verrous de table.. mais Bien sûr, vous allez à l'impasse! Utiliser PDO est beginTransaction() et déplacer vos tables à InnoDB..

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X