web-dev-qa-db-fra.com

MySQL - Connexion persistante vs regroupement de connexions

Afin d'éviter la surcharge d'établissement d'une nouvelle connexion à chaque fois qu'une requête doit être déclenchée contre MySQL, deux options sont disponibles:

  1. Connexions persistantes, par lesquelles une nouvelle connexion est demandée, une vérification est effectuée pour voir si une connexion "identique" est déjà ouverte et si oui, utilisez-la.
  2. Pool de connexions, par lequel le client conserve un pool de connexions, de sorte que chaque thread qui a besoin d'utiliser une connexion en extrait un du pool et le renvoie au pool une fois terminé.

Donc, si j'ai une application serveur multithread censée gérer des milliers de requêtes par seconde, et que chaque thread doit lancer une requête sur la base de données, quelle est la meilleure option?

D'après ma compréhension, avec des connexions persistantes, tous les threads de mon application essaieront d'utiliser la même connexion persistante à la base de données car ils utilisent tous des connexions identiques. Il s'agit donc d'une connexion partagée entre plusieurs threads d'application - en conséquence, les demandes seront bientôt bloquées côté base de données.

Si j'utilise un mécanisme de regroupement de connexions, tous les threads d'application partageront un pool de connexions. Il y a donc moins de possibilité d'une demande de blocage. Cependant, avec le pool de connexions, un thread d'application doit-il attendre pour acquérir une connexion à partir du pool ou doit-il envoyer une demande sur les connexions dans le pool de toute façon de manière circulaire et laisser la file d'attente, le cas échéant, se produire sur la base de données?

43
user1259642

Avoir des connexions persistantes n'implique pas que tous les threads utilisent la même connexion. Il "dit" simplement que vous gardez la connexion ouverte (en contradiction d'ouvrir une connexion chaque fois que vous en avez besoin). L'ouverture d'une connexion est une opération coûteuse, donc - en général - vous essayez d'éviter d'ouvrir des connexions plus souvent que nécessaire.

C'est la raison pour laquelle les applications multithread utilisent souvent des pools de connexions. Le pool s'occupe de l'ouverture et de la fermeture des connexions et chaque thread qui a besoin d'une connexion en demande une au pool. Il est important de veiller à ce que le thread renvoie la connexion dès que possible au pool, afin qu'un autre thread puisse l'utiliser.

Si votre application n'a que quelques threads longs qui nécessitent des connexions, vous pouvez également ouvrir une connexion pour chaque thread et la garder ouverte.

L'utilisation d'une seule connexion (comme vous l'avez décrite) équivaut à un pool de connexions de taille maximale. Ce sera tôt ou tard votre goulot d'étranglement car tous les threads devront attendre la connexion. Cela pourrait être une option pour sérialiser les opérations de base de données (les exécuter dans un certain ordre), bien qu'il existe de meilleures options pour garantir la sérialisation.

26
mrab

Concernant votre question sur le cas où le serveur d'applications attendrait une connexion, la réponse est oui.

Les connexions MySQL bloquent. Lorsque vous émettez une demande du serveur MySQL via une connexion, la connexion attendra, inactive, jusqu'à ce qu'une réponse soit reçue du serveur.

Il n'y a aucun moyen d'envoyer deux requêtes sur la même connexion et de voir laquelle retourne en premier. Vous ne pouvez envoyer qu'une seule demande à la fois.

Ainsi, généralement, un seul thread dans un pool de connexions se compose d'une connexion côté client (dans votre cas, le serveur d'applications est le client) et d'une connexion côté serveur (base de données).

Votre application doit attendre un thread de connexion disponible à partir du pool, ce qui permet au pool de s'agrandir lorsque cela est nécessaire et de revenir à votre nombre de threads par défaut, lorsqu'il est moins occupé.

17
Marcus Adams