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

dans PDO, une connexion peut être rendue persistante en utilisant l'attribut PDO::ATTR_PERSISTENT . Selon le manuel php -

les connexions Persistantes ne sont pas fermées à la fin du script, mais sont mis en cache et réutilisés lorsqu'un autre script demande une connexion en utilisant les mêmes informations d'identification. Le cache de connexion persistant vous permet de éviter d'établir une nouvelle connexion à chaque fois un script a besoin de parler à une base de données, web plus rapide application.

le manuel recommande également de ne pas utiliser de connexion persistante lors de l'utilisation du pilote ODBC AOP, car cela pourrait entraver le processus de mise en commun de la connexion ODBC.

donc apparemment, il ne semble pas y avoir d'inconvénients à utiliser la connexion persistante dans AOP, 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 de résultats dans la dégradation des performances ou quelque chose comme ça.

161
demandé sur MD Sayem Ahmed 2010-07-26 07:42:19

8 réponses

s'il vous Plaît assurez-vous de lire cette réponse ci-dessous , qui détaille les moyens d'en atténuer les problèmes décrits ici.


les mêmes inconvénients existent en utilisant PDO comme avec toute autre interface de base de données PHP qui fait des connexions persistantes: si votre script se termine de manière inattendue au milieu des opérations de base de données, la prochaine requête qui obtient la connexion restante va ramasser où le script mort a laissé. La connexion est maintenu ouvert au niveau du gestionnaire de processus (Apache pour mod_php, le processus FastCGI actuel si vous utilisez FastCGI, etc), pas au niveau PHP, et PHP ne dit pas au processus parent de laisser la connexion mourir lorsque le script se termine anormalement.

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

si l'écriture morte était au milieu d'une transaction, qui peut bloquer une multitude de tables jusqu'à ce que le minuteur de blocage s'enclenche, et même alors, le minuteur de blocage peut tuer la nouvelle requête au lieu de l'ancienne requête qui cause le problème.

si le script mort était au milieu d'une transaction, le script suivant qui obtient cette connexion obtient aussi l'état de la transaction. Il est très possible (en fonction de la conception de votre application) que le prochain script n'essaie pas réellement 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 pointe de l'iceberg. Tout peut être atténué dans une certaine mesure en essayant toujours de nettoyer après une connexion sale sur chaque requête de script, mais cela peut être douloureux selon la base de données. Sauf si vous avez identifié la création de connexions de base de données comme la seule chose qui est un goulot d'étranglement dans votre script (cela signifie que vous avez fait le profilage de code en utilisant xdebug et / ou xhprof ), vous devriez pas envisager des connexions persistantes comme une solution à quoi que ce soit.

de plus, la plupart des bases de données modernes (y compris PostgreSQL) ont leurs propres méthodes préférées pour effectuer la mise en commun des connexions qui n'ont pas les inconvénients immédiats que les connexions continues simples basées sur PHP font.


Pour clarifier un point, nous utilisons des connexions persistantes à mon lieu de travail, mais pas par choix. Nous rencontrions weird comportement de connexion, où la connexion initiale de notre serveur app à notre serveur de base de données prenait exactement trois secondes, quand il aurait fallu une fraction d'une fraction de seconde. Nous pensons que c'est un bogue du noyau. Nous avons renoncé à essayer de résoudre le problème parce que cela s'est produit au hasard et ne pouvait pas être reproduit à la demande, et il n'avait pas la capacité concrète de le retrouver.

peu importe, quand les gens dans l'entrepôt traitent quelques centaines de pièces entrantes, et chaque pièce prend trois secondes et demie au lieu d'une demi-seconde, nous avons dû prendre des mesures avant qu'ils nous kidnappent tous et nous fassent aider. Nous avons donc fait un saut de quelques bits dans notre monstruosité ERP/CRM/CMS maison et nous avons fait l'expérience de toutes les horreurs des connexions persistantes de première main. Il nous a fallu semaines afin de traquer toutes les subtiles peu de problèmes et comportement bizarre qui s'est passé apparemment au hasard. Il s'est avéré que ces erreurs fatales une fois par semaine que nos utilisateurs ont soigneusement sorti de notre application laissaient des tables verrouillées, des transactions abandonnées et d'autres États fâcheux.

cette histoire triste a un point: elle a brisé des choses que nous ne nous attendions pas à briser, tout cela au nom de la performance. le le compromis n'en valait pas la peine, et nous attendons avec impatience le jour où nous pourrons revenir à des connexions normales sans émeute de la part de nos utilisateurs.

257
répondu Charles 2017-05-23 11:47:23

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

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

une plainte courante au sujet des connexions persistantes est que leur état n'est pas réinitialisé avant réutilisation. Par exemple, les transactions ouvertes et non terminées ne sont pas automatiquement reportées. Mais aussi, les changements d'autorisation qui se sont produits dans le temps entre la mise de la connexion dans la piscine et la réutilisation il ne sont pas pris en compte. Cela peut être considéré comme un effet secondaire indésirable. Au contraire, le nom persistant peut être interprété comme une promesse de persistance de l'état.

l'extension mysqli supporte les deux interprétations d'une connexion persistante: l'état persistait, et l'état reset before reuse. 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 connexion persistante apparaît à l'utilisateur comme si c'était tout juste d'ouvrir. Aucune trace d'une utilisation précédente sont visibles.

la fonction mysqli_change_user() est une opération coûteuse. Pour une meilleure performance, les utilisateurs peuvent vouloir recompiler l'extension avec le drapeau de compilation MYSQLI_NO_CHANGE_USER_ON_PCONNECT étant défini.

il appartient à l'utilisateur de choisir entre un comportement sûr et la meilleure performance. Les deux sont des objectifs d'optimisation valables. Pour la facilité d'utilisation, le comportement sécurisé a été fait par défaut au détriment de maximum performance.

41
répondu Prashant 2015-02-26 14:37:57

sur mes tests j'ai eu un temps de connexion de plus d'une seconde à mon hôte local, en supposant que je devrais utiliser une connexion persistante. D'autres tests ont montré qu'il s'agissait d'un problème avec "localhost":

résultats d'essai en secondes (mesurés par php microtime):

  • Web hébergé: connectDB: 0.0038912296295166
  • localhost: connectDB: 1.0214691162109 (plus d'une seconde: n'utilisez pas localhost!)
  • 127.0.0.1: connectDB: 0.00097203254699707

fait intéressant: le code suivant est tout aussi rapide que l'utilisation 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));
11
répondu Gunnar Bernstein 2013-04-26 09:58:18

les connexions persistantes sont une bonne idée seulement quand il faut un temps (relativement) long pour se connecter à votre base de données. Aujourd'hui, c'est presque jamais le cas. Le plus gros inconvénient des connexions persistantes est qu'il limite le nombre d'utilisateurs que vous pouvez avoir parcourant votre site: si MySQL est configuré pour n'autoriser que 10 connexions simultanées à la fois, puis quand une 11ème personne essaie de parcourir votre site, il ne fonctionnera pas pour eux.

PDO ne gère pas la persistance. Le MySQL driver. Il réutilise les connexions quand a) elles sont disponibles et la correspondance hôte/utilisateur/mot de passe/base de données. En cas de changement, la connexion ne sera pas réutilisée. Dans le meilleur des cas, l'effet net est que ces connexions que vous avez seront lancées et arrêtées si souvent parce que vous avez différents utilisateurs sur le site et les rendre persistantes ne fait pas de bien.

la principale chose à comprendre au sujet des connexions persistantes est que vous ne devez pas les utiliser dans la plupart des applications web. Ils semblent séduisants, mais ils sont dangereux et pratiquement inutiles.

je suis sûr qu'il y a d'autres fils à ce sujet, mais une connexion persistante est dangereuse parce qu'elle persiste entre les requêtes. Si, par exemple, vous verrouillez une table pendant une requête et que vous ne parvenez pas à déverrouiller cette table va rester verrouillée indéfiniment. Les connexions persistantes sont également pratiquement inutiles pour 99% de vos applications car vous n'avez aucun moyen de savoir si la même connexion sera utilisée entre différentes demandes. Chaque thread web aura son propre ensemble de connexions persistantes et vous n'avez aucun moyen de contrôler quel thread traitera quelles requêtes.

la bibliothèque mysql procédurale de PHP, a une fonctionnalité par laquelle les appels ultérieurs à mysql_connect retourneront le même lien, plutôt que d'ouvrir une connexion différente (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 manifeste pas un tel comportement


"151900920 Ressource sur le Lien : lien

en général, vous pouvez utiliser cela comme un "ensemble de règles" approximatif::

OUI , utiliser des connexions persistantes, si:

  • il n'y a que peu d'applications/utilisateurs accédant à la base de données, c'est-à-dire vous n'obtiendrez pas 200 connexions ouvertes (mais probablement inactives) , parce qu'il y a 200 utilisateurs différents le même hôte.
  • la base de données est en cours d'exécution sur un autre serveur que vous accédez sur le réseau

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

Non , n'utilisez pas de connexions persistantes, si:

  • votre application n'a besoin d'accéder à la base de données que 100 fois par heure.

  • vous avez beaucoup, beaucoup de serveurs web accédant à un serveur de base de données

L'utilisation de connexions persistantes est considérablement plus rapide, surtout si vous accédez à la base de données sur un réseau. Cela ne fait pas tellement de différence si la base de données tourne sur la même machine, mais c'est encore un peu plus rapide. Cependant - comme le nom l'indique, la connexion est persistante, c'est à dire qu'elle reste ouverte, même si elle est n'est pas utilisé.

le problème est que dans" default configuration", MySQL n'autorise que 1000"canaux ouverts" parallèles. Après cela, les nouvelles connexions sont refusées (Vous pouvez modifier ce paramètre). Donc, si vous avez - disons-20 serveurs Web avec chaque 100 Clients sur eux, et chacun d'eux a juste une page d'accès par heure, simple math vous montrera que vous aurez besoin de 2000 connexions parallèles à la base de données. Cela ne marchera pas.

Ergo: usage unique pour les applications avec beaucoup de demandes.

9
répondu Jhonathan H. 2017-05-23 12:34:28

connexions persistantes devrait donner un coup de pouce de performance considérable. Je ne suis pas d'accord avec l'assertion que vous devriez "éviter" la persistance..

il semble que les plaintes ci-dessus sont conduits par quelqu'un qui utilise des tables MyIASM et qui pirate leurs propres versions de transactions en saisissant des serrures de table.. Bien sûr, vous allez à l'impasse! Utilisez beginTransaction () de PDO et déplacez vos tables vers InnoDB..

6
répondu Stephen 2011-04-04 16:01:48

me semble avoir une connexion persistante mange plus de ressources système. Peut-être un montant insignifiant, mais quand même...

2
répondu Crayon Violent 2010-07-26 03:50:28

l'explication de l'utilisation de connexions persistantes est évidemment la réduction de la quantité de connexions qui sont plutôt coûteux, malgré le fait qu'ils sont considérablement plus rapides avec MySQL par rapport à d'autres bases de données.

le tout premier problème avec des connexions persistantes...

si vous créez des milliers de connexions par seconde, vous ne vous assurez normalement pas qu'elles restent ouvertes pendant très longtemps, mais le système D'exploitation le fait. Basé sur le protocole TCP/IP Les Ports ne peuvent pas être recyclés instantanément et doivent également investir un certain temps dans la phase" FIN " en attendant avant qu'ils ne puissent être recyclés.

le 2e problème... utiliser beaucoup de connexions de serveur MySQL.

beaucoup de gens ne se rendent tout simplement pas compte que vous êtes capable d'augmenter *max_connections* variable et d'obtenir plus de 100 connexions simultanées avec MySQL d'autres ont été battus par des problèmes Linux plus anciens de l'incapacité à transmettre plus de 1024 connexions avec MySQL.

permet de parler maintenant des raisons pour lesquelles les connexions persistantes ont été désactivées dans l'extension mysqli. Malgré le fait que vous pouvez abuser des connexions persistantes et obtenir de mauvaises performances qui n'était pas la raison principale. La vraie raison est – vous pouvez obtenir beaucoup plus de problèmes avec elle.

connexions persistantes ont été mis en PHP tout au long des occasions de MySQL 3.22/3.23 quand MySQL n'était pas si difficile ce qui signifie que vous pourriez recycler des connexions facilement sans problèmes. Plus tard versions quantité de problèmes cependant sont venus sur-Si vous recyclez la connexion qui a des transactions non engagées que vous prenez en difficulté. Si vous recyclez des connexions avec des configurations de jeu de caractères personnalisées, vous êtes à nouveau en danger, ainsi que sur des variables éventuellement transformées par session.

l'un des problèmes avec l'utilisation de connexions persistantes est qu'il n'est pas vraiment échelle que bien. Pour ceux qui ont 5000 personnes connectées, vous aurez besoin de 5000 connexions persistantes. De loin le exigence de persistance, vous pouvez avoir la capacité de servir 10000 personnes avec une quantité semblable de connexions parce qu'ils sont dans une position pour partager des connexions individuelles quand ils ne sont pas avec eux.

1
répondu Tony Stark 2013-04-03 09:01:13

je me demandais juste si une solution partielle serait d'avoir un pool de connexions d'utilisation-une fois. Vous pouvez passer du temps à créer un pool de connexion lorsque le système est à faible utilisation, jusqu'à une limite, les distribuer et les tuer quand soit ils ont terminé ou chronométré. Dans le fond, vous êtes en train de créer de nouvelles connexions qu'ils sont pris. Dans le pire des cas, cela devrait seulement être aussi lent que la création de la connexion sans le pool, en supposant que l'établissement de la liaison est la limite facteur?

0
répondu James 2014-07-03 09:21:31