PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Mise à l'échelle des connexions dans PostgreSQL à l'aide du regroupement de connexions

L'ouverture d'une connexion à une base de données est une opération coûteuse, et le regroupement de connexions est utilisé pour garder les connexions à la base de données ouvertes afin qu'elles puissent être réutilisées. Cela évite d'avoir à ouvrir à plusieurs reprises des sessions réseau, à s'authentifier et à vérifier l'autorisation. Le regroupement maintient les connexions actives afin que, lorsqu'une connexion est demandée ultérieurement, l'une des connexions actives soit utilisée plutôt que d'avoir à en créer une à partir de zéro.

Regroupement des connexions

Le regroupement de connexions est devenu l'une des méthodes les plus courantes de gestion des connexions de base de données avant une demande de requête. Nous pensons normalement qu'une connexion à la base de données est rapide, mais ce n'est pas le cas, surtout lorsqu'un grand nombre de clients se connectent. Sans regroupement de connexions, une demande prendrait jusqu'à 35 à 50 ms pour se connecter, mais 1 à 2 ms si le regroupement de connexions est utilisé. Le regroupement de connexions consiste donc à préallouer des connexions à la base de données, puis à les recycler lorsque de nouveaux clients se connectent

Raisons du regroupement de connexions

  1. Pour éviter de planter votre serveur. Les serveurs PostgreSQL sont limités à un nombre de clients qu'ils gèrent à la fois en fonction du paramètre de mémoire. Si ce nombre est dépassé, vous finirez par planter le serveur. Avec le regroupement de connexions, les clients utilisent un nombre défini de connexions.
  2. Faciliter le traitement des requêtes. Normalement, les requêtes de base de données sont exécutées de manière sérielle avec un critère de premier entré, premier sorti. Avec un grand nombre de clients, cela prendrait des années pour réaliser ce processus. Par conséquent, l'approche devrait consister à établir une connexion unique avec des requêtes en pipeline qui peuvent être exécutées simultanément plutôt que chacune à la fois.
  3. Améliorez la sécurité. Souvent, une connexion implique une poignée de main qui peut prendre 25 à 35 ms en moyenne au cours de laquelle un SSL est établi, les mots de passe sont vérifiés et le partage des informations de configuration. Tout ce travail pour chaque utilisateur connecté se traduira par une utilisation intensive de la mémoire. Cependant, avec le regroupement de connexions, le nombre de connexions est réduit, ce qui permet d'économiser de la mémoire.

Types de regroupement de connexions

Il existe essentiellement deux types de regroupement de connexions, cependant, il existe un troisième type de solution de contournement qui agit comme une stratégie de regroupement de connexions appelée connexions persistantes.

Regroupement de connexions persistantes

Cette approche vise à maintenir une connexion initiale active à partir du moment où elle est initiée. Il ne contient pas entièrement les fonctionnalités de regroupement de connexions, mais suffisamment pour fournir une connexion continue. C'est très utile pour un petit ensemble de connexions client dont la surcharge peut varier entre 25 et 50 ms. Une limitation de cette approche est qu'elle est limitée à un certain nombre de connexions à la base de données avec normalement une seule connexion par entrée au serveur.

Regroupement des connexions de la structure

La mise en pool des connexions du framework se produit au niveau de l'application par laquelle, chaque fois que votre script de serveur est démarré, un pool de connexions est établi pour gérer les demandes de requête qui arriveront plus tard.

Groupement de connexions autonome

Pour chaque connexion à la base de données, une surcharge mémoire comprise entre 5 et 10 Mo est utilisée pour répondre à une demande de requête. Ce n'est pas tout à fait bon pour un grand nombre de connexions. L'utilisation de la mise en pool des connexions du framework peut être limitée par ce nombre de connexions car elle peut rencontrer une utilisation importante de la taille de la mémoire. Nous choisissons donc d'utiliser le regroupement de connexions autonome qui est configuré conformément aux sessions, déclarations et transactions Postgres. Le principal avantage associé à cette approche est le suivant :un coût minimal d'environ 2 Ko pour chaque connexion.

Lorsque vous créez une classe de regroupement de connexions, celle-ci doit respecter les facteurs suivants pour améliorer les performances de la base de données :

  1. Préallouer les connexions
  2. Superviser les connexions disponibles
  3. Attribuer de nouvelles connexions
  4. Attendre qu'une connexion soit disponible
  5. Fermer la connexion
Téléchargez le livre blanc aujourd'hui PostgreSQL Management &Automation with ClusterControlDécouvrez ce que vous devez savoir pour déployer, surveiller, gérer et faire évoluer PostgreSQLTélécharger le livre blanc

Préallouer les connexions

Assurer plus de connexions à l'avance facilitera le traitement des demandes au moment où l'application a été lancée. Par exemple, si votre serveur est développé avec Java, vous pouvez utiliser des vecteurs pour stocker les connexions inactives disponibles en utilisant le code ci-dessous.

availableConnections = new Vector(connections); 
busyConnections = new Vector();
for(int i=0; i<connections; i++) {
availableConnections.addElement(makeNewConnection()); 
}

Surveillance des connexions disponibles

La classe doit pouvoir rechercher toute connexion inactive dans une liste de connexions occupées et la renvoyer. Ceci est essentiellement fait afin de réutiliser une connexion ou de fermer des connexions qui ne sont pas utilisées. Parfois, les connexions expirent. Par conséquent, lors du retour d'une connexion, il est très important de vérifier si elle est toujours ouverte. Si ce n'est pas le cas, vous devrez supprimer cette connexion et répéter le processus. Lorsqu'une connexion est rejetée, un slot est ouvert qui peut être utilisé pour traiter une nouvelle connexion lorsque la limite a été atteinte. Ceci peut être réalisé avec

public synchronized Connection getConnection() throws SQLException {
if (!availableConnections.isEmpty()) { Connection existingConnection =
(Connection)availableConnections.lastElement(); int lastIndex = availableConnections.size() - 1; availableConnections.removeElementAt(lastIndex); if (existingConnection.isClosed()) {
notifyAll(); // Freed up a spot for anybody waiting.
return(getConnection()); // Repeat process. } else {
busyConnections.addElement(existingConnection);
return(existingConnection); }
} }

Attribuer une nouvelle connexion

Vous devriez pouvoir démarrer un fil d'arrière-plan pour attribuer une nouvelle connexion s'il n'y a pas d'inactivité disponible et si la limite de connexion est presque atteinte.

if ((totalConnections() < maxConnections) && !connectionPending) { // Pending = connecting in bg
makeBackgroundConnection(); }
try {
wait(); // Give up lock and suspend self.
} catch(InterruptedException ie) {} return(getConnection()); // Try again.

En attente d'une nouvelle connexion

Lorsqu'il n'y a pas de connexion inactive et que la limite de connexion a été atteinte, la configuration doit pouvoir attendre qu'une nouvelle connexion soit disponible sans mise en commun continue. Nous pouvons le faire en utilisant la méthode d'attente qui fournit un verrou de synchronisation de thread et suspend le thread jusqu'à ce qu'une notification ait été fournie.

try {
     wait();
} catch(InterruptedException ie) {} 
return(getConnection());

Pour une bonne éthique d'application, les clients ne doivent pas attendre en temps réel une connexion, vous lancerez plutôt une exception lorsque les connexions sont absentes avec le code ci-dessous :

throw new SQLException("Connection limit reached");

Fermer la connexion

Lorsque les connexions sont ramassées, vous devez les fermer plutôt que de le faire explicitement. Cependant, si vous souhaitez une approche explicite pour fermer une connexion, vous pouvez utiliser :

public synchronized void closeAllConnections() {
// The closeConnections method loops down Vector, calling // close and ignoring any exceptions thrown. closeConnections(availableConnections); availableConnections = new Vector(); closeConnections(busyConnections);
busyConnections = new Vector();
}

Conclusion

Le regroupement de connexions pour PostgreSQL nous aide à réduire le nombre de ressources nécessaires pour se connecter à la base de données et améliore la vitesse de connexion à la base de données. Ceci est réalisé en regroupant les connexions à la base de données, en maintenant ces connexions et en réduisant par conséquent le nombre de connexions qui doivent être ouvertes.