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

Sammenligning af Load Balancers til PostgreSQL

Belastningsbalancering øger systemets ydeevne, især fra et applikationssynspunkt, hvilket tillader flere computere at betjene de samme data. Det fungerer sådan, at belastningen fordeles mellem klientforespørgsler til replika-noder bortset fra dens primære eller master-knude, mens databaseændringer udelukkende dirigeres til masterknuden. Eventuelle ændringer af masterknudepunktet udbredes efterfølgende til hver replika ved hjælp af PostgreSQL Streaming Replication.

Hvordan kan Load Balancers påvirke PostgreSQL?

Anvendelse af belastningsbalancering skal dirigere klientapplikationer til at oprette forbindelse til belastningsbalanceringsserveren og distribuere de igangsatte forbindelser til de tilgængelige PostgreSQL-noder afhængigt af typen af ​​forespørgselsanmodninger. Dette hjælper med at understrege enestående belastning på en bestemt PostgreSQL-server og fremmer parallel belastningsbalance mellem de tilgængelige noder i klyngen.

Ved brug af PostgreSQL er der allerede en håndfuld eksisterende løsninger til at få dette til at fungere. Disse løsninger kan fungere problemfrit, eller belastningsbalancering kan fungere med den aktuelle topologi - med primære og standby-knudepunkter - alligevel er belastningsbalancering implementeret i selve applikationslaget. Belastningsbalancering står over for udfordringer med synkroniseringsproblemer, som er den grundlæggende vanskelighed for servere, der arbejder sammen. Fordi der ikke er en enkelt løsning, der eliminerer virkningen af ​​synkroniseringsproblemet for alle use cases, er der flere løsninger. Hver løsning løser dette problem på en anden måde og minimerer dets indvirkning på en specifik arbejdsbyrde.

I denne blog tager vi et kig på disse belastningsbalancere ved at sammenligne dem, og hvor gavnligt det er for din PostgreSQL-arbejdsbyrde.

HAProxy Load Balancing For PostgreSQL

HAProxy er en hændelsesdrevet, ikke-blokerende motor, der kombinerer en proxy med et meget hurtigt I/O-lag og en prioritetsbaseret, multi-threaded planlægger. Da den er designet med et mål for videresendelse af data i tankerne, er dens arkitektur designet til at fungere i en letvægtsproces, som er optimeret til at flytte data så hurtigt som muligt med færrest mulige operationer. Den fokuserer på at optimere CPU-cache-effektiviteten ved at holde forbindelser til den samme CPU så længe som muligt. Som sådan implementerer den en lagdelt model, der tilbyder bypass-mekanismer på hvert niveau, der sikrer, at data ikke når højere niveauer, medmindre det er nødvendigt. Det meste af behandlingen udføres i kernen. HAProxy gør sit bedste for at hjælpe kernen med at udføre arbejdet så hurtigt som muligt ved at give nogle hints eller ved at undgå visse operationer, når den gætter på, at de kan grupperes senere. Som følge heraf viser typiske tal 15 % af behandlingstiden brugt i HAProxy mod 85 % i kernen i TCP- eller HTTP-lukketilstand, og omkring 30 % for HAProxy mod 70 % for kernen i HTTP Keep-alive-tilstand.

HAProxy har også yderligere funktioner til belastningsbalancering. For eksempel giver TCP-proxy-funktionen os mulighed for at bruge den til databaseforbindelser, især til PostgreSQL ved hjælp af dens indbyggede checkservice-support. Selvom der er databaseservicesupport, er det ikke tilstrækkeligt med det ønskede sundhedstjek, især for en replikeringstype af klynge. Standardmetoden, når den implementeres til produktion, er at bruge TCP-tjek og derefter afhænge af xinetd med HAProxy.

Fordele ved at bruge HAProxy til PostgreSQL

Det bedste ved HAProxy er dets lette, nemme at konfigurere og bruge, og det gør jobbet som forventet. Brug af HAProxy oven på en PostgreSQL-klynge er blevet implementeret og implementeret flere gange fra store organisationer til forskellige SMV'er/SMB'er til deres produktionsbrug. Det har længe været bevist for produktion og høj arbejdsbelastningskapacitet, ikke kun for databaser, men endda med andre netværkstjenester såsom webapplikationer eller for geo-belastningsbalancering (fordel trafik på tværs af flere datacentre). Med HAProxy oven på PostgreSQL giver det brugerne mulighed for at drosle eller begrænse svarene for at parallelisere og fordele belastningen korrekt til alle tilgængelige noder i klyngen. Den indbyggede mekanisme med HAProxy giver også brugeren mulighed for at opsætte høj tilgængelighed problemfrit og nemmere at skalere, hvis der er behov for belastning og undgå single point of failure (SPOF).

Udemper ved at bruge HAProxy til PostgreSQL

HAProxy leverer ikke forespørgselsfiltrering og heller ikke forespørgselsanalyse for at identificere typen af ​​udsagn, der anmodes om. Den mangler evnen til at udføre en læse/skrive-split på en enkelt port. At indstille en load balancer oven på HAProxy kræver, at du som minimum skal konfigurere forskellige porte til dine skrivninger og forskellige til dine læsninger. Dette kræver applikationsændringer, så de passer til dine behov.

HAProxy understøtter også en meget enkel funktion med PostgreSQL til helbredstjek, men dette bestemmer kun, om noden er oppe eller ej, som om den bare pinger noden og venter på et retursvar. Den identificerer ikke, hvilken rolle en node den forsøger at videresende de ønskede forbindelser fra klienten til den ønskede node. Derfor forstår den ikke eller ingen funktion i HAProxy at forstå replikationstopologien. Selvom en bruger kan oprette separate lyttere baseret på forskellige porte, men det tilføjer stadig ændringer i applikationen for at tilfredsstille belastningsbalanceringsbehovene. Det betyder, at enten brug af et eksternt script med xinetd kan være løsningen for at opfylde kravene. Alligevel er det ikke integreret med HAProxy og kan være tilbøjeligt til menneskelige fejl.

Hvis én node eller gruppe af noder skal placeres i vedligeholdelsestilstand, skal du også anvende ændringer på din HAProxy, ellers kan det være katastrofalt.

Pgpool-II til belastningsbalancering af din PostgreSQL

Pgpool-II er en open source-software og er omfavnet af det massive PostgreSQL-fællesskab til at implementere belastningsbalancering og bruge dette til at fungere som deres middleware fra applikationen ned til proxy-laget og derefter fordele belastningen efter at den har analyseret typen af ​​anmodning pr. forespørgsel eller databaseforbindelse. Pgpool-II har været der i så lang tid siden 2003, som oprindeligt hed Pgpool, indtil det blev Pgpool-II i 2006, hvilket fungerer som et bevis på et meget stabilt proxyværktøj, ikke kun til belastningsbalancering, men også tonsvis af fede funktioner .

Pgpool-II er kendt som den schweiziske hærkniv til PostgreSQL og er en proxysoftware, der sidder mellem PostgreSQL-servere og en PostgreSQL-databaseklient. Den grundlæggende idé med PgPool-II er, at den sidder på klienten, så skal læseforespørgsler leveres til standby-knuderne, mens skrivningen eller ændringerne går direkte til den primære. Det er en meget intelligent belastningsbalanceringsløsning, der ikke kun laver belastningsbalance, men også understøtter høj tilgængelighed og giver forbindelsespooling. Den intelligente mekanisme gør det muligt at balancere belastningen mellem mastere og slaver. Så skrivninger indlæses til masteren, mens behandlingslæsninger dirigeres til de tilgængelige skrivebeskyttede servere, som er dine angiveligt varme standby-noder. Pgpool-II giver også logisk replikering. Selvom dets brug og betydning er faldet, efterhånden som de indbyggede replikeringsmuligheder blev forbedret på PostgreSQL-serversiden, er dette stadig en værdifuld mulighed for ældre versioner af PostgreSQL. Oven i alt dette giver det også forbindelsespooling.

Pgpool-II har en mere involveret arkitektur end PgBouncer for at understøtte alle de funktioner, den gør. Da begge understøtter forbindelsespooling, har sidstnævnte ingen belastningsbalanceringsfunktioner.

Pgpool-II kan administrere flere PostgreSQL-servere. Brug af replikeringsfunktionen gør det muligt at oprette en sikkerhedskopiering i realtid på 2 eller flere fysiske diske, så tjenesten kan fortsætte uden at stoppe servere i tilfælde af en diskfejl. Da Pgpool-II også er en forbindelsespooling-kapabel, kan den give begrænsninger på de overskridende forbindelser. Der er en grænse for det maksimale antal samtidige forbindelser med PostgreSQL, og forbindelser afvises efter så mange forbindelser. Indstilling af det maksimale antal forbindelser øger imidlertid ressourceforbruget og påvirker systemets ydeevne. pgpool-II har også en grænse for det maksimale antal forbindelser, men ekstra forbindelser vil blive sat i kø i stedet for at returnere en fejl med det samme.

I belastningsbalancering,  Hvis en database replikeres, vil udførelse af en SELECT-forespørgsel på en hvilken som helst server returnere det samme resultat. pgpool-II udnytter replikeringsfunktionen til at reducere belastningen på hver PostgreSQL-server ved at distribuere SELECT-forespørgsler mellem flere servere, hvilket forbedrer systemets samlede gennemløb. I bedste fald forbedres ydeevnen proportionalt med antallet af PostgreSQL-servere. Belastningsbalance fungerer bedst i en situation, hvor der er mange brugere, der udfører mange forespørgsler på samme tid.

Ved at bruge den parallelle forespørgselsfunktion kan data opdeles mellem de flere servere, så en forespørgsel kan udføres på alle serverne samtidigt for at reducere den samlede eksekveringstid. Parallel forespørgsel fungerer bedst, når der søges i data i stor skala.

Fordele ved at bruge Pgpool til PostgreSQL

Det er en funktionsrig type software, ikke kun til belastningsbalancering. Kernefunktionerne og understøttelsen af ​​dette værktøj er meget on-demand, som giver forbindelsespooling, en alternativ go PgBouncer, native replikering, online recovery, in-memory query caching, automatisk failover og høj tilgængelighed med dens underproces ved hjælp af watchdog. Dette værktøj har været så gammelt og understøttes konstant massivt af PostgreSQL-fællesskabet, så det kan ikke være svært at søge hjælp at håndtere problemer. Dokumentationen er din ven her, når du søger spørgsmål, men det er ikke svært at søge efter hjælp i fællesskabet, og det faktum, at dette værktøj er en open source, så du frit kan bruge dette, så længe du overholder BSD-licensen.

Pgpool-II har også SQL-parser. Dette betyder, at den er i stand til nøjagtigt at parse SQL'erne og omskrive forespørgslen. Dette gør det muligt for Pgpool-II at øge paralleliteten afhængigt af forespørgselsanmodningen.

Udemper ved at bruge Pgpool til PostgreSQL

Pgpool-II tilbyder ikke STONITH (skyd den anden knude i hovedet), som giver knudehegn. Hvis PostgreSQL-serveren fejler, opretholder den tjenestens tilgængelighed. Pgpool-II kan også være single point of failure (SPOF). Når noden går ned, stopper din databaseforbindelse og tilgængelighed fra det tidspunkt. Selvom dette kan løses ved at have redundans med Pgpool-II og at skulle bruge vagthund til at koordinere flere Pgpool-II-noder, tilføjer det ekstra arbejde.

For forbindelsespooling, desværre, for dem, der kun fokuserer på forbindelsespooling, er det, Pgpool-II ikke gør særlig godt, forbindelsespooling, især for et lille antal klienter. Fordi hver underordnet proces har sin egen pulje, og der ikke er nogen måde at kontrollere, hvilken klient der forbinder til hvilken underordnet proces, er for meget overladt til heldet, når det kommer til at genbruge forbindelser.

Brug af JDBC-driver til belastningsbalancering af din PostgreSQL

Java Database Connectivity (JDBC) er en applikationsprogrammeringsgrænseflade (API) til programmeringssproget Java, som definerer, hvordan en klient kan få adgang til en database. Det er en del af Java Standard Edition-platformen og giver metoder til at forespørge og opdatere data i en database og er orienteret mod relationelle databaser.

PostgreSQL JDBC-driver (forkortet PgJDBC) tillader Java-programmer at oprette forbindelse til en PostgreSQL-database ved hjælp af standard, databaseuafhængig Java-kode. Er en open source JDBC-driver skrevet i Pure Java (Type 4), og kommunikerer i PostgreSQL native netværksprotokol. På grund af dette er føreren platformsuafhængig; når den er kompileret, kan driveren bruges på ethvert system.

Det er ikke sammenligneligt med belastningsbalanceringsløsninger, som vi tidligere har påpeget. Derfor er dette værktøj din applikationsprogrammeringsgrænseflade API, som giver dig mulighed for at oprette forbindelse fra din applikation til hvilken type programmeringssprog dette er skrevet, der understøtter JDBC eller i det mindste har adapter til at forbinde med JDBC. På den anden side er det mere gunstigt med Java-applikationer.

Belastningsbalanceringen med JDBC er temmelig naiv, men kan dog klare opgaven. Forsynet med forbindelsesparametrene, der kan udløse belastningsbalanceringsmekanismen, som dette værktøj har at tilbyde,

  • targetServerType - tillader kun at åbne forbindelser til servere med påkrævet tilstand/rolle i overensstemmelse med den definerende faktor for PostgreSQL-serverne. De tilladte værdier er enhver, primær, master (forældet), slave (forældet), sekundær, preferSlave og preferSecondary. Tilstand eller rolle bestemmes ved at observere, om serveren tillader skrivninger eller ej.
  • hostRecheckSeconds - styrer, hvor længe i sekunder viden om en værtstilstand er cachelagret i JVM wide global cache. Standardværdien er 10 sekunder.
  • loadBalanceHosts – giver dig mulighed for at konfigurere, om den første vært altid prøves (når den er indstillet til falsk), eller hvis forbindelser er tilfældigt valgt (når den er sat til sand)

Så bruger loadBalanceHosts, som accepterer en boolesk værdi. loadBalanceHosts er deaktiveret i standardtilstanden, og værter er forbundet i den givne rækkefølge. Hvis aktiveret, vælges værter tilfældigt fra sættet af egnede kandidater. Den grundlæggende syntaks ved tilslutning til databasen ved hjælp af jdbc er som følger,

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

I betragtning af at loadBalanceHosts og forbindelse modtager flere værter konfigureret ligesom nedenfor,

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

Dette gør det muligt for JDBC at vælge tilfældigt fra sættet af egnede kandidater.

Fordele ved at bruge PgJDBC til PostgreSQL

Ingen behov for at kræve middleware eller proxy som belastningsbalancer. Denne proces tilføjer mere ydeevneboost fra applikationens frontend, da der ikke er noget ekstra lag for hver anmodning at passere forbi. Hvis du har applikationer klar og er skrevet til at understøtte grænseflader til JDBC, kan dette være fordelagtigt, og hvis du ikke har brug for mere middleware, især hvis dit budget er stramt og kun ønsker at begrænse de processer, der er dedikeret til dets eneste formål og funktion. I modsætning til applikationer med høj trafik og stor efterspørgsel kan det kræve proxy-servere, der fungerer som dine belastningsbalancer og kan kræve ekstra ressourcer for korrekt at håndtere høje anmodninger om forbindelser, hvilket også kræver efterspørgsel på CPU og hukommelsesbehandling.

Udemper ved at bruge PgJDBC til PostgreSQL

Du skal konfigurere din kode for hver eneste forbindelse, der skal anmodes om. Det er en applikationsprogrammeringsgrænseflade, hvilket betyder, at der er arbejde bag at håndtere, især hvis din applikation er meget krævende på hver anmodning om at blive sendt til de rigtige servere. Der er ingen høj tilgængelighed, automatisk skalerbarhed og har et enkelt fejlpunkt.

Hvad med wrappers eller værktøjer implementeret med libpq til belastningsbalancering af din PostgreSQL?

libpq er C-applikationsprogrammørens grænseflade til PostgreSQL. libpq er et sæt biblioteksfunktioner, der tillader klientprogrammer at sende forespørgsler til PostgreSQL-backend-serveren og modtage resultaterne af disse forespørgsler.

libpq er også den underliggende motor for adskillige andre PostgreSQL-applikationsgrænseflader, inklusive dem skrevet til C++, PHP, Perl, Python, Tcl, Swift og ECPG. Så nogle aspekter af libpqs adfærd vil være vigtige for dig, hvis du bruger en af ​​disse pakker.

libpq automatiserer ikke belastningsbalanceringen og er ikke at betragte som et værktøj til belastningsbalanceringsløsninger. Alligevel er den i stand til at oprette forbindelse til de næste tilgængelige servere, hvis de tidligere servere, der er angivet til forbindelse, mislykkes. For eksempel, hvis du har to tilgængelige hot-standby-noder, hvis den første node er for optaget og ikke reagerer på den tilsvarende timeout-værdi, forbinder den til den næste tilgængelige node i den givne forbindelse. Det afhænger af, hvilken type sessionsattributter du har angivet. Dette afhænger af parameteren target_session_attrs.

Parameteren target_session_attrs accepterer værdier read-write, og enhver som er standardværdien, hvis den ikke er angivet. Hvad betyder parameter target_session_attrs er, at hvis den er sat til read-write, kun en forbindelse, hvor read-write transaktioner accepteres under forbindelse. Forespørgslen SHOW transaction_read_only vil blive sendt ved enhver vellykket forbindelse. Hvis resultatet er slået til, vil forbindelsen blive lukket, hvilket betyder, at noden er identificeret som en replika eller ikke behandler skrivninger. Hvis der er angivet flere værter i forbindelsesstrengen, vil eventuelle resterende servere blive prøvet, ligesom hvis forbindelsesforsøget var mislykket. Standardværdien for denne parameter, enhver, hvilket betyder, at alle forbindelser er acceptable. Selvom det ikke er nok at stole på target_session_attrs til belastningsbalancering, kan du muligvis simulere en round-robin måde. Se mit eksempel C-kode nedenfor ved hjælp af 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 afslører,

[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

Bemærk, at hvis node .40 (den primære node) går ned, vil den altid dirigere forbindelsen til .50, så længe din target_session_attrs-værdi er nogen.

I så fald kan du simpelthen oprette din egen frit ved hjælp af libpq. Selvom processen med at stole på libpq og/eller dens indpakning bare er for rå til at sige, at dette kan give den ønskede belastningsbalanceringsmekanisme med jævn fordeling til de noder, du har. Denne tilgang og kodning kan bestemt forbedres, men tanken er, at dette er gratis og åben kildekode, og du kan kode uden at være afhængig af middleware og frit konstruere den måde, din belastningsbalancering skal fungere på.

Fordele ved at bruge libpq til PostgresQL

libpq-biblioteket er programmørens applikationsgrænseflade bygget i programmeringssproget C. Alligevel er biblioteket blevet implementeret på forskellige sprog som indpakninger, så programmører kan kommunikere med PostgreSQL-databasen ved hjælp af deres yndlingssprog. Du kan direkte oprette din egen applikation ved hjælp af dine yndlingssprog og derefter liste ned de servere, du har til hensigt at forespørgsler skal sendes, men kun efter den anden, hvis fejl eller timeout sende din belastning til de tilgængelige noder, som du har til hensigt at distribuere belastningen. Det er tilgængeligt på sprog som Python, Perl, PHP, Ruby, Tcl eller Rust.

Udemper ved at bruge libpq til PostgresQL

Implementeringsmæssigt for belastningsparallelisme er ikke perfekt, og du skal skrive din egen belastningsbalanceringsmekanisme efter kode. Der er ingen konfiguration, som du kan bruge eller tilpasse, da det helt alene er en programmeringsgrænseflade til PostgreSQL-databasen ved hjælp af target_session_attrs param. Det betyder, at når du opretter en databaseforbindelse, skal du have en række læseforbindelser, der går til dine replika/standby noder, og derefter skrive forespørgsler, der går til forfatteren eller den primære node i din kode, uanset om det er i din applikation, eller du skal oprette din egen API til at administrere belastningsbalanceringsløsning.

Brug af denne tilgang behøver bestemt ikke eller stole på en middleware fra front-end-applikationsperspektivet til databasen som backend. Det er selvfølgelig let, men når du sender listen over servere ved forbindelse, betyder det ikke, at belastningen forstås og sendes jævnt, medmindre du skal tilføje din kode for denne tilgang. Dette tilføjer bare besværet, men der er allerede eksisterende løsninger, så hvorfor skal du genopfinde hjulet?

Konklusion

Implementering af dine load balancers med PostgreSQL kan være krævende, men afhænger af hvilken type applikation og omkostninger du har med at gøre. Nogle gange, for en høj belastningsefterspørgsel, kræver det, at middleware fungerer som en proxy for korrekt at fordele belastningen og også overvåger dens nodetilstand eller sundhed. På den anden side kan det kræve serverressourcer, enten det skal køres på en dedikeret server eller kræver ekstra CPU og hukommelse for at tilfredsstille behovene, og det øger omkostningerne. Derfor er der også en enkel måde, men alligevel tidskrævende, men tilbyder fordelingen af ​​belastningen til de tilgængelige servere, du allerede har. Alligevel kræver det programmeringsfærdigheder og forståelse af API'ens funktionalitet.


  1. Fjern SCHEMABINDING fra en visning i SQL Server

  2. MySQL -- Forenes mellem databaser på forskellige servere ved hjælp af Python?

  3. Implementering af en Django-app til AWS Elastic Beanstalk

  4. Sådan opretter du et beregnet felt i Access