sql >> Database teknologi >  >> RDS >> PostgreSQL

Skalering af forbindelser i PostgreSQL ved hjælp af Connection Pooling

At åbne en databaseforbindelse er en dyr operation, og forbindelsespooling bruges til at holde databaseforbindelser åbne, så de kan genbruges. Dette undgår gentagne gange at skulle åbne netværkssessioner, autentificere og kontrollere autorisation. Pooling holder forbindelserne aktive, så når der senere anmodes om en forbindelse, bruges en af ​​de aktive i stedet for at skulle oprette en fra bunden.

Forbindelsespooling

Forbindelsespooling er blevet en af ​​de mest almindelige metoder til håndtering af databaseforbindelser forud for en forespørgselsanmodning. Vi tror normalt, at en forbindelse til databasen er hurtig, men det er ikke tilfældet, især når et stort antal klienter opretter forbindelse. Uden forbindelsespooling vil en anmodning tage op til 35-50 ms at oprette forbindelse, men 1-2 ms, hvis forbindelsespooling anvendes. Forbindelsespooling er derfor at forudallokere databaseforbindelser og derefter genbruge dem, når nye klienter opretter forbindelse

Årsager til forbindelsespooling

  1. For at undgå at crashe din server. PostgreSQL-servere er begrænset til et antal klienter, de håndterer ad gangen, afhængigt af hukommelsesparameteren. Hvis dette tal overskrides, vil du ende med at crashe serveren. Med forbindelsespooling bruger klienter et bestemt antal forbindelser.
  2. Lettelse af forespørgselsbehandling. Normalt udføres databaseanmodninger på en seriel måde med et kriterium om først-ind først-ud. Med et stort antal kunder ville det tage evigheder at opnå denne proces. Derfor bør tilgangen være at oprette en enkelt forbindelse med pipelinede anmodninger, som kan udføres samtidigt i stedet for hver enkelt ad gangen.
  3. Forbedre sikkerheden. Ofte involverer en forbindelse et håndtryk, der kan tage 25-35 ms i gennemsnit, over hvilket en SSL etableres, adgangskoder kontrolleres og deling af konfigurationsoplysningerne. Alt dette arbejde for hver tilsluttet bruger vil resultere i omfattende brug af hukommelse. Men med forbindelsespooling reduceres antallet af forbindelser, hvorved der spares på hukommelsen.

Typer af forbindelsespooling

Der er grundlæggende to typer forbindelsespooling, men der er en tredje type work-around, der fungerer som en forbindelsespoolingstrategi kendt som vedvarende forbindelser.

Persistent Connection Pooling

Denne tilgang har til hensigt at holde en indledende forbindelse aktiv fra det tidspunkt, den initieres. Det har ikke fuldt ud forbindelsespooling-funktionerne, men godt nok til at give en kontinuerlig forbindelse. Det er ganske nyttigt for et lille sæt klientforbindelser, hvis overhead kan variere mellem 25-50 ms. En begrænsning ved denne tilgang er, at den er begrænset til et antal forbindelser til db'en med normalt en enkelt forbindelse pr. indgang til serveren.

Framework Connection Pooling

Rammeforbindelsespooling forekommer på et applikationsniveau, hvorved, hver gang dit serverscript startes, etableres en pulje af forbindelser til at håndtere forespørgselsanmodninger, der kommer senere.

Fristående forbindelsespooling

For hver forbindelse til databasen bruges en overheadhukommelse mellem 5 og 10 MB op til at imødekomme en forespørgselsanmodning. Dette er ikke helt godt for et stort antal forbindelser. Brug af rammeforbindelsespooling kan begrænses af dette antal forbindelser, da det kan støde på et stort hukommelsesforbrug. Vi vælger derfor at bruge den selvstændige forbindelsespooling, som er konfigureret i overensstemmelse med Postgres-sessioner, erklæringer og transaktioner. Kernefordelen forbundet med denne tilgang er:minimale overheadomkostninger på omkring 2 kb for hver forbindelse.

Når du opretter en forbindelsespooling-klasse, bør den opfylde følgende faktorer for en øget databaseydeevne:

  1. Tildel forbindelserne på forhånd
  2. Få tilsyn med forbindelser, der er tilgængelige
  3. Tildel nye forbindelser
  4. Vent på, at en forbindelse er tilgængelig
  5. Luk forbindelsen
Download Whitepaper Today PostgreSQL Management &Automation med ClusterControlFå flere oplysninger om, hvad du skal vide for at implementere, overvåge, administrere og skalere PostgreSQLDownload Whitepaper

Forudallokering af forbindelserne

At sikre flere forbindelser på forhånd vil lette håndteringen af ​​anmodninger på det tidspunkt, hvor applikationen er startet. Hvis din server f.eks. er udviklet med Java, kan du bruge vektorer til at gemme tilgængelige ledige forbindelser ved hjælp af koden nedenfor.

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

Overvågning af tilgængelige forbindelser

Klassen bør være i stand til at kontrollere, om der er ledig forbindelse på en liste over optaget forbindelser og returnere den. Dette gøres grundlæggende for at genbruge en forbindelse eller lukke forbindelser, der ikke er i brug. Nogle gange timeout forbindelsen, og det er derfor meget vigtigt at kontrollere, om den stadig er åben, når du returnerer en forbindelse. Hvis ikke, bliver du nødt til at kassere denne forbindelse og gentage processen. Når en forbindelse kasseres, åbnes en slot, som kan bruges til at behandle en ny forbindelse, når grænsen er nået. Dette kan opnås med

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); }
} }

Tildeling af en ny forbindelse

Du bør være i stand til at starte en baggrundstråd for at tildele en ny forbindelse, hvis der ikke er nogen ledig på tilgængelig, og hvis forbindelsesgrænsen næsten er nået.

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

Venter på en ny forbindelse

Når der ikke er nogen inaktiv forbindelse, og forbindelsesgrænsen er nået, bør konfigurationen kunne vente på, at en ny forbindelse er tilgængelig uden kontinuerlig pooling. Vi kan gøre det ved at bruge ventemetoden, som giver en trådsynkroniseringslås og suspenderer tråden, indtil der er givet en notifikation.

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

For god applikationsetik bør klienter ikke vente i realtid på en forbindelse, men du vil kaste en undtagelse, når forbindelser er fraværende med koden nedenfor:

throw new SQLException("Connection limit reached");

Afslutning af forbindelsen

Når forbindelser er opsamlet affald, bør du lukke dem i stedet for at gøre det eksplicit. Men hvis du ønsker en eksplicit tilgang til at lukke en forbindelse, kan du bruge:

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();
}

Konklusion

Forbindelsespooling til PostgreSQL hjælper os med at reducere antallet af ressourcer, der kræves for at oprette forbindelse til databasen, og forbedrer forbindelseshastigheden til databasen. Dette opnås ved at samle forbindelser til databasen, vedligeholde disse forbindelser og følgelig reducere antallet af forbindelser, der skal åbnes.


  1. Brug af DATEADD, DATEDIFF og DATEPART T-SQL-funktioner i simple termer

  2. Problemer med indholdstyper ved indlæsning af en armatur i Django

  3. Dump alle tabeller i CSV-format ved hjælp af 'mysqldump'

  4. Opsætning af en geo-distribueret databaseklynge ved hjælp af MySQL-replikering