sql >> Databasteknik >  >> RDS >> PostgreSQL

Jämföra lastbalanserare för PostgreSQL

Lastbalansering ökar systemets prestanda, särskilt ur applikationssynpunkt, vilket gör att flera datorer kan leverera samma data. Det fungerar så att belastningen fördelas mellan klientförfrågningar till replikanoder bortsett från dess primära nod eller huvudnod, medan databasändringar enbart dirigeras till huvudnoden. Eventuella modifieringar av masternoden sprids sedan till varje replik med PostgreSQL Streaming Replication.

Hur kan lastbalanserare påverka PostgreSQL?

Användning av lastbalansering ska styra klientapplikationer att ansluta till lastbalanseringsservern och distribuera de initierade anslutningarna till tillgängliga PostgreSQL-noder beroende på typen av frågeförfrågningar. Detta hjälper till att stressa ut enastående belastning på en viss PostgreSQL-server och främjar parallell belastningsbalans mellan de tillgängliga noderna inom klustret.

Med PostgreSQL finns det redan en handfull befintliga lösningar för att få detta att fungera. Dessa lösningar kan fungera sömlöst eller så kan lastbalansering fungera med den aktuella topologin - med primära och standbynoder - men lastbalansering implementeras i själva applikationslagret. Lastbalansering står inför utmaningar med synkroniseringsproblem, vilket är den grundläggande svårigheten för servrar att arbeta tillsammans. Eftersom det inte finns någon enskild lösning som eliminerar effekten av synkroniseringsproblemet för alla användningsfall, finns det flera lösningar. Varje lösning löser detta problem på olika sätt och minimerar dess påverkan för en specifik arbetsbelastning.

I den här bloggen tar vi en titt på dessa lastbalanserare genom att jämföra dem och hur fördelaktigt det är för din PostgreSQL-arbetsbelastning.

HAProxy-belastningsbalansering för PostgreSQL

HAProxy är en händelsedriven, icke-blockerande motor som kombinerar en proxy med ett mycket snabbt I/O-lager och en prioritetsbaserad, flertrådig schemaläggare. Eftersom den är designad med ett mål för vidarebefordran av data i åtanke, är dess arkitektur utformad för att fungera i en lätt process som är optimerad för att flytta data så snabbt som möjligt med minsta möjliga operationer. Den fokuserar på att optimera CPU-cache-effektiviteten genom att hålla anslutningar till samma CPU så länge som möjligt. Som sådan implementerar den en skiktad modell som erbjuder bypass-mekanismer på varje nivå som säkerställer att data inte når högre nivåer om det inte behövs. Det mesta av bearbetningen utförs i kärnan. HAProxy gör sitt bästa för att hjälpa kärnan att göra jobbet så snabbt som möjligt genom att ge några tips eller genom att undvika vissa operationer när den gissar att de kan grupperas senare. Som ett resultat visar typiska siffror 15 % av bearbetningstiden som spenderas i HAProxy mot 85 % i kärnan i TCP- eller HTTP-stängningsläge, och cirka 30 % för HAProxy jämfört med 70 % för kärnan i HTTP Keep-alive-läge.

HAProxy har också ytterligare funktioner för lastbalansering. TCP-proxyfunktionen tillåter oss till exempel att använda den för databasanslutningar, speciellt för PostgreSQL med hjälp av dess inbyggda kontrolltjänststöd. Även om det finns stöd för databastjänster, räcker det inte med den önskade hälsokontrollen, särskilt för en replikeringstyp av kluster. Standardmetoden när du distribuerar den för produktion är att använda TCP-kontroll och sedan vara beroende av xinetd med HAProxy.

Fördelar med att använda HAProxy för PostgreSQL

Det bästa med HAProxy är dess lätta, lätta att konfigurera och använda, och den gör jobbet som förväntat. Att använda HAProxy ovanpå ett PostgreSQL-kluster har implementerats och distribuerats flera gånger från stora organisationer till olika små och medelstora företag/SMB för deras produktionsanvändning. Det har länge bevisats för produktion och hög arbetsbelastningskapacitet, inte bara för databaser utan även med andra nätverkstjänster som webbapplikationer eller för geobelastningsbalansering (fördela trafik över flera datacenter). Genom att ha HAProxy ovanpå PostgreSQL, tillåter det användare att strypa eller begränsa svaren för att parallellisera och fördela belastningen korrekt till alla tillgängliga noder i klustret. Den inbyggda mekanismen med HAProxy tillåter också användaren att ställa in hög tillgänglighet sömlöst och lättare att skala om belastning behövs och undvika single point of failure (SPOF).

Nackdelar med att använda HAProxy för PostgreSQL

HAProxy tillhandahåller inte frågefiltrering och inte heller frågeanalys för att identifiera typen av påståenden som efterfrågas. Den saknar förmågan att utföra en läs/skrivdelning på en enda port. Att ställa in en lastbalanserare ovanpå HAProxy kräver att du åtminstone måste ställa in olika portar för dina skrivningar och olika portar för dina läsningar. Detta kräver applikationsändringar för att passa dina behov.

HAProxy har också ett mycket enkelt funktionsstöd med PostgreSQL för hälsokontroll, men detta avgör bara om noden är uppe eller inte, som om den bara plingar noden och väntar på ett studssvar. Den identifierar inte vilken roll en nod den försöker vidarebefordra de begärda anslutningarna från klienten till den önskade noden. Därför förstår den inte eller ingen funktion i HAProxy för att förstå replikeringstopologin. Även om en användare kan skapa separata lyssnare baserat på olika portar, men ändå lägger den till ändringar i applikationen för att tillfredsställa lastbalanseringsbehoven. Detta innebär att antingen ett externt skript med xinetd kan vara lösningen för att uppfylla kraven. Ändå är det inte integrerat med HAProxy och kan vara utsatt för mänskliga fel.

Om en nod eller grupp av noder måste placeras i underhållsläge, måste du också göra ändringar i din HAProxy, annars kan det bli katastrofalt.

Pgpool-II för lastbalansering av din PostgreSQL

Pgpool-II är en programvara med öppen källkod och omfamnas av den massiva PostgreSQL-communityt för att implementera lastbalansering och använda detta för att fungera som deras mellanprogram från applikationen ner till proxylagret, och sedan distribuera belastningen efter att den fullständigt har analyserat typen av begäran per fråga eller databasanslutning. Pgpool-II har funnits där så länge sedan 2003 som ursprungligen hette Pgpool tills det blev Pgpool-II 2006, vilket fungerar som ett bevis på ett mycket stabilt proxyverktyg inte bara för lastbalansering utan massor av coola funktioner också .

Pgpool-II är känd som den schweiziska armékniven för PostgreSQL och är en proxymjukvara som sitter mellan PostgreSQL-servrar och en PostgreSQL-databasklient. Grundidén med PgPool-II är att den sitter på klienten, sedan måste läsfrågor levereras till standbynoderna, medan skrivningen eller ändringarna går direkt till den primära. Det är en mycket intelligent lastbalanseringslösning som inte bara gör lastbalansering, utan också stöder hög tillgänglighet och ger anslutningspooling. Den intelligenta mekanismen gör det möjligt att balansera belastningen mellan masters och slavar. Så skrivningar laddas till mastern, medan bearbetningsläsningar dirigeras till de tillgängliga skrivskyddade servrarna, som är dina förmodade heta standby-noder. Pgpool-II tillhandahåller också logisk replikering. Även om dess användning och betydelse har minskat när de inbyggda replikeringsalternativen förbättrades på PostgreSQL-serversidan, är detta fortfarande ett värdefullt alternativ för äldre versioner av PostgreSQL. Utöver allt detta ger den också anslutningspooling.

Pgpool-II har en mer involverad arkitektur än PgBouncer för att stödja alla funktioner den gör. Eftersom båda stöder anslutningspoolning har den senare inga lastbalanseringsfunktioner.

Pgpool-II kan hantera flera PostgreSQL-servrar. Genom att använda replikeringsfunktionen kan du skapa en säkerhetskopia i realtid på 2 eller flera fysiska diskar, så att tjänsten kan fortsätta utan att stoppa servrar i händelse av ett diskfel. Eftersom Pgpool-II också är kapabel för anslutningspoolning, kan den ge begränsningar för de överskridande anslutningarna. Det finns en gräns för det maximala antalet samtidiga anslutningar med PostgreSQL, och anslutningar avvisas efter så många anslutningar. Att ställa in det maximala antalet anslutningar ökar dock resursförbrukningen och påverkar systemets prestanda. pgpool-II har också en gräns för det maximala antalet anslutningar, men extra anslutningar kommer att köas istället för att returnera ett fel omedelbart.

I lastbalansering,  Om en databas replikeras, kommer en SELECT-fråga att köras på valfri server att returnera samma resultat. pgpool-II drar fördel av replikeringsfunktionen för att minska belastningen på varje PostgreSQL-server genom att distribuera SELECT-frågor mellan flera servrar, vilket förbättrar systemets totala genomströmning. I bästa fall förbättras prestandan proportionellt mot antalet PostgreSQL-servrar. Lastbalans fungerar bäst i en situation där det finns många användare som kör många frågor samtidigt.

Med hjälp av den parallella frågefunktionen kan data delas upp mellan flera servrar, så att en fråga kan köras på alla servrar samtidigt för att minska den totala exekveringstiden. Parallellfråga fungerar bäst när du söker i storskalig data.

Fördelar med att använda Pgpool för PostgreSQL

Det är en funktionsrik typ av programvara, inte bara för lastbalansering. Kärnfunktionerna och stödet för det här verktyget är mycket on-demand som ger anslutningspooling, en alternativ go PgBouncer, native replikering, online-återställning, in-memory query caching, automatisk failover och hög tillgänglighet med dess underprocess som använder watchdog. Det här verktyget har varit så gammalt och stöds kontinuerligt massivt av PostgreSQL-communityt, så att hantera problem kan inte vara svårt att söka hjälp. Dokumentationen är din vän här när du söker frågor, men det är inte svårt att söka efter hjälp i samhället, och det faktum att detta verktyg är en öppen källkod så att du fritt kan använda detta så länge du följer BSD-licensen.

Pgpool-II har också SQL-tolkare. Det betyder att den kan analysera SQL-filerna korrekt och skriva om frågan. Detta tillåter Pgpool-II att öka parallelliteten beroende på frågeförfrågan.

Nackdelar med att använda Pgpool för PostgreSQL

Pgpool-II erbjuder inte STONITH (skjut den andra noden i huvudet) som tillhandahåller nodfäktningsmekanism. Om PostgreSQL-servern misslyckas bibehåller den tjänstens tillgänglighet. Pgpool-II kan också vara single point of failure (SPOF). När noden går ner, stoppar din databasanslutning och tillgänglighet från den punkten. Även om detta kan åtgärdas genom att ha redundans med Pgpool-II och behöva använda watchdog för att koordinera flera Pgpool-II-noder, lägger det till extra arbete.

För anslutningspooling, tyvärr, för de som bara fokuserar på anslutningspooling, är det som Pgpool-II inte gör särskilt bra anslutningspooling, särskilt för ett litet antal klienter. Eftersom varje underordnad process har sin egen pool och det inte finns något sätt att styra vilken klient som ansluter till vilken underordnad process, lämnas för mycket åt turen när det gäller att återanvända anslutningar.

Använda JDBC-drivrutin för lastbalansering av din PostgreSQL

Java Database Connectivity (JDBC) är ett applikationsprogrammeringsgränssnitt (API) för programmeringsspråket Java, som definierar hur en klient kan komma åt en databas. Den är en del av Java Standard Edition-plattformen och tillhandahåller metoder för att fråga och uppdatera data i en databas, och är inriktad på relationsdatabaser.

PostgreSQL JDBC-drivrutin (förkortat PgJDBC) tillåter Java-program att ansluta till en PostgreSQL-databas med standard, databasoberoende Java-kod. Är en JDBC-drivrutin med öppen källkod skriven i Pure Java (Typ 4), och kommunicerar i PostgreSQL-nätverksprotokollet. På grund av detta är föraren plattformsoberoende; när den väl har kompilerats kan drivrutinen användas på alla system.

Det är inte jämförbart med lastbalanseringslösningar som vi har påpekat tidigare. Därför är det här verktyget ditt API för applikationsprogrammeringsgränssnitt som låter dig ansluta från din applikation för vilken typ av programmeringsspråk detta än är skrivet som stöder JDBC eller åtminstone har adapter för att ansluta till JDBC. Å andra sidan är det mer fördelaktigt med Java-applikationer.

Lastbalanseringen med JDBC är ganska naiv men kan göra jobbet. Försedd med anslutningsparametrarna som kan utlösa lastbalanseringsmekanismen som detta verktyg har att erbjuda,

  • targetServerType - tillåter öppning av anslutningar till endast servrar med erforderlig status/roll i enlighet med den definierande faktorn för PostgreSQL-servrarna. De tillåtna värdena är valfri, primär, master (utfasad), slav (utfasad), sekundär, preferSlave och preferSecondary. Tillstånd eller roll bestäms genom att observera om servern tillåter skrivningar eller inte.
  • hostRecheckSeconds - styr hur länge i sekunder kunskapen om en värdtillstånd cachelagras i JVM wide global cache. Standardvärdet är 10 sekunder.
  • loadBalanceHosts – låter dig konfigurera om den första värden alltid testas (när den är inställd på false) eller om anslutningar väljs slumpmässigt (när den är satt till true)

Så använder loadBalanceHosts som accepterar ett booleskt värde. loadBalanceHosts är inaktiverat i standardläget och värdarna ansluts i den angivna ordningen. Om aktiverat väljs värdar slumpmässigt från uppsättningen lämpliga kandidater. Den grundläggande syntaxen när du ansluter till databasen med jdbc är följande,

  • jdbc:postgresql:database
  • jdbc:postgresql:/
  • jdbc:postgresql://host/database
  • jdbc:postgresql://host/
  • jdbc:postgresql://host:port/database
  • jdbc:postgresql://host:port/

Med tanke på att loadBalanceHosts och anslutning tar emot flera värdar konfigurerade precis som nedan,

jdbc:postgresql://host1:port1,host2:port2,host3:port3/database

Detta tillåter JDBC att slumpmässigt välja bland lämpliga kandidater.

Fördelar med att använda PgJDBC för PostgreSQL

Ingen behov av att kräva mellanprogram eller proxy som belastningsutjämnare. Denna process lägger till mer prestandaökning från applikationens gränssnitt eftersom det inte finns något extra lager för varje begäran att passera. Om du har applikationer redo och är skrivna för att stödja gränssnitt till JDBC, kan detta vara fördelaktigt och om du inte behöver mer mellanprogram, särskilt om din budget är knapp och bara vill begränsa de processer som är dedikerade till dess enda syfte och funktion. Till skillnad från applikationer med hög trafik och stor efterfrågan, kan det kräva proxyservrar som fungerar som dina belastningsutjämnare och kan kräva extra resurser för att korrekt hantera höga förfrågningar av anslutningar, vilket också kräver krav på CPU och minnesbehandling.

Nackdelar med att använda PgJDBC för PostgreSQL

Du måste ställa in din kod för varje anslutning som ska begäras. Det är ett applikationsprogrammeringsgränssnitt vilket innebär att det finns arbete bakom att hantera, särskilt om din applikation är mycket krävande på varje begäran som ska skickas till rätt servrar. Det finns ingen hög tillgänglighet, automatisk skalbarhet och har en enda felpunkt.

Vad sägs om wrappers eller verktyg som implementeras med libpq för lastbalansering av din PostgreSQL?

libpq är C-applikationsprogrammerarens gränssnitt till PostgreSQL. libpq är en uppsättning biblioteksfunktioner som tillåter klientprogram att skicka frågor till PostgreSQL-servern och ta emot resultaten av dessa frågor.

libpq är också den underliggande motorn för flera andra PostgreSQL-applikationsgränssnitt, inklusive de skrivna för C++, PHP, Perl, Python, Tcl, Swift och ECPG. Så vissa aspekter av libpqs beteende kommer att vara viktiga för dig om du använder ett av dessa paket.

libpq automatiserar inte lastbalanseringen och är inte att betrakta som ett verktyg för lastbalanseringslösningar. Ändå kan den ansluta till nästa tillgängliga servrar om de tidigare servrarna som är listade för anslutning misslyckas. Till exempel, om du har två tillgängliga hot standby-noder, om den första noden är för upptagen och inte svarar på motsvarande timeout-värde, ansluter den till nästa tillgängliga nod i den givna anslutningen. Det beror på vilken typ av sessionsattribut du angav. Detta förlitar sig på parametern target_session_attrs.

Parametern target_session_attrs accepterar värden läs-skriv, och alla som är standardvärden om de inte anges. Vad betyder parameter target_session_attrs är att, om den är inställd på läs-skriv, endast en anslutning där läs-skrivtransaktioner accepteras under anslutning. Frågan SHOW transaction_read_only kommer att skickas vid en lyckad anslutning. Om resultatet är på kommer anslutningen att stängas, vilket innebär att noden identifieras som en replik eller inte bearbetar skrivningar. Om flera värdar angavs i anslutningssträngen kommer alla återstående servrar att prövas precis som om anslutningsförsöket hade misslyckats. Standardvärdet för denna parameter, någon, vilket betyder att alla anslutningar är acceptabla. Även om det inte räcker att förlita sig med target_session_attrs för lastbalansering, kanske du kan simulera ett round-robin-sätt. Se mitt exempel C-kod nedan med libpq,

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <time.h>

#include <unistd.h>

#include <libpq-fe.h>




const char* _getRoundRobinConn() {

   char* h[2];

   h[0] = "dbname=node40 host=192.168.30.40,192.168.30.50";

   h[1] = "dbname=node50 host=192.168.30.50,192.168.30.40";



   time_t t;

   //srand((unsigned)time(&t));

   sleep(1.85);

   srand((unsigned)time(NULL));



   return h[rand() % 2];

}



void

_connect()

{

  PGconn *conn;

  PGresult *res;

  char strConn[120];




  snprintf(strConn, 1000, "user=dbapgadmin password=dbapgadmin %s target_session_attrs=any", _getRoundRobinConn());

  //printf("\nstrConn value is: %s\n", strConn);



  conn = PQconnectdb(strConn);



  res = PQexec(conn, "SELECT current_database(), inet_client_addr();");



  if ( PQresultStatus(res)==PGRES_TUPLES_OK )

  {

    printf("current_database = %s on %s\n", PQgetvalue(res, 0, 0),

PQhost(conn));

  } else {



    printf("\nFailed... Message Code is: %d\n", PQresultStatus(res));

  }



  PQclear(res);

  PQfinish(conn);



}



int main(void)

{

  int i;

  for (i=0 ; i<5 ; i++)

    _connect();



  return 0;

}

Resultatet avslöjar,

[email protected]:/home/vagrant# gcc -I/usr/include/postgresql -L/usr/lib/postgresql/12/lib libpq_conn.c -lpq -o libpq_conn; ./libpq_conn

current_database = node40 on 192.168.30.40

current_database = node40 on 192.168.30.40

current_database = node50 on 192.168.30.50

current_database = node40 on 192.168.30.40

current_database = node50 on 192.168.30.50

Observera att om nod .40 (den primära noden) går ner kommer den alltid att dirigera anslutningen till .50 så länge som ditt target_session_attrs-värde är något.

I så fall kan du helt enkelt skapa din egen fritt med hjälp av libpq. Även om processen att förlita sig på libpq och/eller dess omslag är alldeles för rå för att säga att detta kan ge den önskade lastbalanseringsmekanismen med jämn fördelning till de noder du har. Definitivt kan detta tillvägagångssätt och kodning förbättras men tanken är att detta är gratis och öppen källkod, och du kan koda utan att förlita dig på mellanprogram och fritt konstruera hur din lastbalansering ska fungera.

Fördelar med att använda libpq för PostgresQL

libpq-biblioteket är programmerarens applikationsgränssnitt byggt i programmeringsspråket C. Ändå har biblioteket implementerats på olika språk som omslag så att programmerare kan kommunicera med PostgreSQL-databasen med sina favoritspråk. Du kan direkt skapa din egen applikation med hjälp av dina favoritspråk och sedan lista ner de servrar du avser att frågor ska skickas men bara efter den andra, om fel eller timeout skicka din laddning till de tillgängliga noderna som du tänker fördela belastningen. Det är tillgängligt på språk som Python, Perl, PHP, Ruby, Tcl eller Rust.

Nackdelar med att använda libpq för PostgresQL

Implementering för lastparallellism är inte perfekt och du måste skriva din egen lastbalanseringsmekanism med kod. Det finns ingen konfiguration som du kan använda eller anpassa eftersom det bara är ett programmeringsgränssnitt till PostgreSQL-databasen med hjälp av target_session_attrs param. Det betyder att när du skapar en databasanslutning måste du ha en serie läsanslutningar som går till dina replika/standby-noder, och sedan skriv frågor som går till skrivaren eller primärnoden i din kod, oavsett om det finns i din applikation eller om du måste skapa ditt eget API för att hantera lastbalanseringslösning.

Att använda detta tillvägagångssätt behöver definitivt inte eller förlita sig på en mellanprogramvara från front-end-applikationsperspektivet till databasen som backend. Naturligtvis är det lätt men när du skickar listan över servrar vid anslutning betyder det inte att belastningen förstås och skickas jämnt om du inte måste lägga till din kod för detta tillvägagångssätt. Detta skapar bara krångel, men det finns redan befintliga lösningar så varför behöver man uppfinna hjulet på nytt?

Slutsats

Att implementera dina lastbalanserare med PostgreSQL kan vara krävande men beror på vilken typ av applikation och kostnad du har att göra med. Ibland, för en hög belastningsefterfrågan, kräver det ett behov av middleware som fungerar som en proxy för att korrekt fördela belastningen och även övervaka dess nodtillstånd eller hälsa. Å andra sidan kan den kräva serverresurser, antingen måste den köras på en dedikerad server eller kräver extra CPU och minne för att tillfredsställa behoven och detta ökar kostnaden. Därför finns det också ett enkelt sätt men ändå tidskrävande men erbjuder fördelningen av belastningen till de tillgängliga servrar du redan har. Ändå kräver det programmeringskunskaper och förståelse för API:s funktionalitet.


  1. Hur får man fråga om kolumnattribut från tabellnamn med PostgreSQL?

  2. Exempel på hur man använder bind_result vs get_result

  3. Komplett process för att kopiera tabell från en databas till en annan (export-import) i SQL Server

  4. En expertguide till Slony-replikering för PostgreSQL