Databaseydelse er en meget vigtig bekymring, når du vedligeholder din databaseklynge, især da den vokser over tid. Dette gælder især, hvis din applikation startede med lav trafik og derefter voksede til moderate eller tunge læse-skrive-arbejdsbelastninger.
Det, du skal huske, er, at der ikke er nogen perfekt konfiguration, som du kan stole på i lang tid, da visse arbejdsbelastninger kan ændre sig over tid.
Med ClusterControl udfører oprettelse eller implementering af en ny PostgreSQL-databaseklynge en grundlæggende analyse, såsom kontrol af dine hardwareressourcer, anvender derefter automatisk tuning og indstiller værdierne for de valgte tunbare parametre. Efterhånden som PostgreSQL udvikler sig, er der også udviklet en masse værktøjer til at understøtte forskellige konfigurationer, især til belastningsbalancering.
I denne blog tager vi et kig på vigtigheden af HAProxy, og hvordan det kan hjælpe med at øge ydeevnen. Det er et gammelt værktøj, men alligevel en kraftfuld proxy og/eller load balancer, som understøtter ikke kun databaseservere, men også netværksapplikationsspecifikke protokoller. HAProxy kan fungere via henholdsvis lag fire og lag syv, afhængigt af typen af opsætning baseret på konfigurationen.
PostgreSQL Performance Tuning
En af de primære faktorer for at øge ydeevnen for PostgreSQL starter med den grundlæggende parameterindstilling fra initdb til runtime-parameterværdier. Dette skal være i stand til at håndtere den ønskede arbejdsbyrde i overensstemmelse med dine specifikke krav. Før vi kan tage en vej til HAProxy-funktionen til PostgreSQL, skal din databaseserver være stabil og indstillet til dens ønskede variabler. Lad os tage en liste over områder for PostgreSQL om, hvad der er ting, der kan påvirke ydeevnen for din databaseserver.
Indstilling til mulig hukommelsesstyring
PostgreSQL er effektivt, og det er muligt at køre effektivt på så lidt som 256 Mb hukommelse. Hukommelse er ikke dyrt, men de fleste datasæt er mindre end 4Gib. Hvis du har mindst 4Gib, kan dit aktive datasæt forblive i fil- og/eller shared_buffer-cache.
Justering af din PostgreSQL til hukommelseshåndtering er en af de mest primære og grundlæggende ting, du skal indstille. Hvis du indstiller det korrekt, kan det påvirke din databaseservers ydeevne. Selvom det afhænger af, hvilken slags borde du spiller med. Dårlige forespørgsler og dårlige tabeldefinitioner kan også føre til dårlig ydeevne. Med korrekte indekser defineret til dine tabeller og med forespørgsler, der refererer til indekser, kan chancerne nå fra 80 % - 100 % af forespørgslerne kan hentes fra din hukommelse. Dette især hvis indeksbufferen har den rigtige værdi til at indlæse dit indeks defineret på dine tabeller. Lad os se på de parametre, der almindeligvis er indstillet til forbedring af ydeevnen.
- shared_buffers - PostgreSQL størrelser dets primære hukommelsesplads med shared_buffers. Arbejdscachen for alle hot tuples (og indeksposter) i PostgreSQL. Denne parameter indstiller mængden af hukommelse, som databaseserveren bruger til delte hukommelsesbuffere. Det er en forudtildelt cache (buffere). For Linux-baserede systemer er det ideelt at indstille kerneparameteren kernel.shmmax, som konstant kan indstilles via /etc/sysctl.conf-kernekonfigurationsfilen.
- temp_buffere - Indstiller det maksimale antal midlertidige buffere, der bruges til hver session. Disse er lokale sessionsbuffere, der kun bruges til at få adgang til midlertidige tabeller. En session vil tildele de midlertidige buffere efter behov op til grænsen givet af temp_buffers.
- work_mem - Den arbejdshukommelse, der er tilgængelig for arbejdsoperationer (sorterer), før PostgreSQL vil bytte. Indstil ikke globalt (postgresql.conf). Brug pr. transaktion, da dette kan være dårligt pr. forespørgsel, pr. forbindelse eller pr. sortering. Det anbefales at bruge EXPLAIN ANALYZE for at se, om du løber over eller ej.
- maintenance_work_mem - Angiver mængden af hukommelse, der skal bruges til vedligeholdelsesoperationer (VACUUM, CREATE INDEX, og ALTER TABLE … TILFØJ UDENLANDSKE NØGLE…)
Indstilling til mulig diskhåndtering
En række køretidsparametre, der skal indstilles her. Lad os liste, hvad disse er:
- temp_file_limit - Angiver den maksimale mængde diskplads, som en session kan bruge til midlertidige filer, såsom sortering og hash af midlertidige filer, eller lagerfilen for en tilbageholdt markør. En transaktion, der forsøger at overskride denne grænse, vil blive annulleret.
- fsync - Hvis fsync er aktiveret, vil PostgreSQL forsøge at sikre, at opdateringerne er fysisk skrevet til disken. Dette sikrer, at databaseklyngen kan gendannes til en konsistent tilstand efter et operativsystem- eller hardwarenedbrud. Selvom deaktivering af fsync generelt forbedrer ydeevnen, kan det forårsage datatab i tilfælde af strømsvigt eller systemnedbrud. Derfor er det kun tilrådeligt at deaktivere fsync, hvis du nemt kan genskabe hele din database fra eksterne data
- synchronous_commit - Bruges til at håndhæve, at commit vil vente på, at WAL bliver skrevet på disken, før en successtatus returneres til klienten. Denne variabel har afvejninger mellem ydeevne og pålidelighed. Hvis du har brug for mere ydeevne, skal du slå dette fra, hvilket betyder, at når serveren går ned, har du tendens til at støde på datatab. Ellers, hvis pålidelighed er vigtig, skal du aktivere denne. Dette betyder, at der vil være et tidsrum mellem successtatus og en garanteret skrivning til disk, hvilket kan påvirke ydeevnen.
- checkpoint_timeout, checkpoint_completion_target - PostgreSQL skriver ændringer ind i WAL, hvilket er en dyr operation. Hvis det ofte skriver ændringer til WAL, kan det påvirke ydeevnen dårligt. Så hvordan det fungerer, checkpoint-processen skyller dataene ind i datafilerne. Denne aktivitet udføres, når CHECKPOINT opstår og kan forårsage en enorm mængde IO. Hele denne proces involverer dyre disklæse-/skriveoperationer. Selvom du (admin-bruger) altid kan udstede CHECKPOINT, når det synes nødvendigt, eller automatisere det ved at indstille ønskede værdier for disse parametre. Checkpoint_timeout-parameteren bruges til at indstille tiden mellem WAL-kontrolpunkter. Hvis du indstiller dette for lavt, reduceres nedbrudsgendannelsestiden, da flere data skrives til disken, men det skader også ydeevnen, da hvert kontrolpunkt ender med at forbruge værdifulde systemressourcer. Checkpoint_completion_target er brøkdelen af tiden mellem checkpoints for checkpoint afslutning. En høj frekvens af kontrolpunkter kan påvirke ydeevnen. For jævn checkpointing skal checkpoint_timeout være en lav værdi. Ellers vil operativsystemet akkumulere alle de beskidte sider, indtil forholdet er opfyldt, og derefter gå til en stor flush.
Justering af andre parametre til ydeevne
Der er visse parametre, der giver boost og drive for ydeevne i PostgreSQL. Lad os liste, hvad disse er nedenfor:
- wal_buffere - PostgreSQL skriver sin WAL-post (write ahead log) ind i bufferne og derefter skylles disse buffere til disken. Standardstørrelsen på bufferen, defineret af wal_buffers, er 16 MB, men hvis du har mange samtidige forbindelser, kan en højere værdi give bedre ydeevne.
- effective_cache_size - Effective_cache_size giver et estimat af den tilgængelige hukommelse til diskcache. Det er kun en rettesnor, ikke den nøjagtige tildelte hukommelse eller cachestørrelse. Den allokerer ikke faktisk hukommelse, men fortæller optimizeren mængden af cache, der er tilgængelig i kernen. Hvis værdien af dette er sat for lavt, kan forespørgselsplanlæggeren beslutte ikke at bruge nogle indekser, selvom de ville være nyttige. Derfor er det altid en fordel at angive en stor værdi.
- default_statistics_target - PostgreSQL indsamler statistik fra hver af tabellerne i sin database for at bestemme, hvordan forespørgsler vil blive udført på dem. Som standard indsamler den ikke for meget information, og hvis du ikke får gode eksekveringsplaner, bør du øge denne værdi og derefter køre ANALYSE i databasen igen (eller vente på AUTOVACUUM).
PostgreSQL-forespørgselseffektivitet
PostgreSQL har en meget kraftfuld funktion til optimering af forespørgsler. Med den indbyggede Genetic Query Optimizer (kendt som GEQO). Den bruger en genetisk algoritme, som er en heuristisk optimeringsmetode gennem randomiseret søgning. Dette anvendes, når der udføres optimering ved hjælp af JOINs, hvilket giver en meget god ydeevneoptimering. Hver kandidat i sammenføjningsplanen er repræsenteret af en sekvens, hvori basisrelationerne skal forbindes. Det udfører tilfældigt et genetisk forhold ved blot at generere en mulig sammenføjningssekvens, men tilfældigt.
For hver betragtede joinsekvens aktiveres standardplanlæggerkoden for at estimere omkostningerne ved at udføre forespørgslen ved hjælp af den joinsekvens. Så for hver af JOIN-sekvenserne har alle deres oprindeligt bestemte relationsscanningsplaner. Derefter vil forespørgselsplanen beregne den mest gennemførlige og effektive plan, dvs. med lavere estimerede omkostninger og betragtes som "mere passende" end dem med højere omkostninger.
I betragtning af, at den har en kraftfuld funktion integreret i PostgreSQL og de korrekt konfigurerede parametre i overensstemmelse med dine ønskede krav, besejrer den ikke gennemførligheden, når det kommer til ydeevne, hvis belastningen kun kastes til en primære knude. Belastningsbalancering med HAProxy hjælper med endnu mere drevydelse til PostgreSQL.
Øver ydeevne til PostgreSQL med læse-skriveopdeling
Du har muligvis en fantastisk ydeevne, når du håndterer din PostgreSQL-serverknude, men du er muligvis ikke i stand til at forudse, hvilken type arbejdsbyrde du kan have, især når høj trafik rammer, og efterspørgslen går ud over grænsen. Balancering af belastningen mellem en primær og sekundær giver et ydelsesboost i din applikation og/eller klienter, der forbinder til din PostgreSQL-databaseklynge. Hvordan dette kan gøres, er ikke længere et spørgsmål, da det er en meget almindelig opsætning for høj tilgængelighed og redundans, når det kommer til at fordele belastningen og undgå, at den primære node hænger fast på grund af høj belastningsbehandling.
Opsætning med HAProxy er let. Alligevel er det mere effektivt hurtigere og gennemførligt med ClusterControl. Så vi bruger ClusterControl til at konfigurere dette for os.
Opsætning af PostgreSQL med HAProxy
For at gøre dette skal vi blot installere og opsætte HAProxy oven på PostgreSQL-klyngerne. HAProxy har en funktion til at understøtte PostgreSQL gennem option pgsql-check, men dens support er en meget enkel implementering til at afgøre, om en node er oppe eller ej. Den har ikke kontrol til at identificere en primær og en gendannelsesknude. En mulighed er at bruge xinetd, som vi vil stole på at kommunikere HAProxy til at lytte via vores xinetd-tjeneste, som kontrollerer tilstanden af en bestemt node i vores PostgreSQL-klynge.
Under ClusterControl, naviger til Administrer → Load Balancer ligesom nedenfor,
Følg derefter baseret på brugergrænsefladen på skærmbilledet nedenfor. Du kan klikke på Vis avancerede indstillinger for at se flere avancerede muligheder. Det er dog meget ligetil at følge brugergrænsefladen. Se nedenfor,
Jeg importerer kun enkelt node HAProxy uden redundans, men med det formål at denne blog, lad os gøre det enklere.
Min prøve HAProxy-visning er vist nedenfor,
Som vist ovenfor er 192.168.30.20 og 192.168.30.30 de primære og sekundære/gendannelsesknuder henholdsvis. Mens HAProxy er installeret i den sekundære/gendannelsesknude. Ideelt set kan du installere din HAProxy på flere noder for at få mere redundans og høj tilgængelighed, det er bedst at isolere den mod databasenoderne. Hvis du er stram med budget eller sparer på dit forbrug, kan du vælge at installere dine HAProxy-noder, hvor dine databasenoder også er installeret.
ClusterControl opsætter dette automatisk og inkluderer også xinetd-tjenesten til PostgreSQL-tjek. Dette kan verificeres med netstat ligesom nedenfor,
[email protected]:~# netstat -tlv4np|grep haproxy
tcp 0 0 0.0.0.0:5433 0.0.0.0:* LISTEN 28441/haproxy
tcp 0 0 0.0.0.0:5434 0.0.0.0:* LISTEN 28441/haproxy
tcp 0 0 0.0.0.0:9600 0.0.0.0:* LISTEN 28441/haproxy
Mens port 5433 er læse-skrive og 5444 er skrivebeskyttet.
For PostgreSQL tjek for xinetd-tjenesten, nemlig postgreshk som vist nedenfor,
[email protected]:~# cat /etc/xinetd.d/postgreschk
# default: on
# description: postgreschk
service postgreschk
{
flags = REUSE
socket_type = stream
port = 9201
wait = no
user = root
server = /usr/local/sbin/postgreschk
log_on_failure += USERID
disable = no
#only_from = 0.0.0.0/0
only_from = 0.0.0.0/0
per_source = UNLIMITED
}
xinetd-tjenesterne er også afhængige af /etc/services, så du kan muligvis finde den port, der er udpeget til at kortlægge.
[email protected]:~# grep postgreschk /etc/services
postgreschk 9201/tcp
Hvis du har brug for at ændre porten på din postgreschk til hvilken port der skal tilknyttes, skal du ændre denne fil ud over servicekonfigurationsfilen og så glem ikke at genstarte xinetd daemon.
Postgreschk-tjenesten indeholder en reference til en ekstern fil, som grundlæggende kontrollerer for noder, hvis den er skrivbar, hvilket betyder, at den er en primær eller en master. Hvis en node er under gendannelse, er det en replika eller en gendannelsesknude.
[email protected]:~# cat /usr/local/sbin/postgreschk
#!/bin/bash
#
# This script checks if a PostgreSQL server is healthy running on localhost. It will
# return:
# "HTTP/1.x 200 OK\r" (if postgres is running smoothly)
# - OR -
# "HTTP/1.x 500 Internal Server Error\r" (else)
#
# The purpose of this script is make haproxy capable of monitoring PostgreSQL properly
#
export PGHOST='localhost'
export PGUSER='s9smysqlchk'
export PGPASSWORD='password'
export PGPORT='7653'
export PGDATABASE='postgres'
export PGCONNECT_TIMEOUT=10
FORCE_FAIL="/dev/shm/proxyoff"
SLAVE_CHECK="SELECT pg_is_in_recovery()"
WRITABLE_CHECK="SHOW transaction_read_only"
return_ok()
{
echo -e "HTTP/1.1 200 OK\r\n"
echo -e "Content-Type: text/html\r\n"
if [ "$1x" == "masterx" ]; then
echo -e "Content-Length: 56\r\n"
echo -e "\r\n"
echo -e "<html><body>PostgreSQL master is running.</body></html>\r\n"
elif [ "$1x" == "slavex" ]; then
echo -e "Content-Length: 55\r\n"
echo -e "\r\n"
echo -e "<html><body>PostgreSQL slave is running.</body></html>\r\n"
else
echo -e "Content-Length: 49\r\n"
echo -e "\r\n"
echo -e "<html><body>PostgreSQL is running.</body></html>\r\n"
fi
echo -e "\r\n"
unset PGUSER
unset PGPASSWORD
exit 0
}
return_fail()
{
echo -e "HTTP/1.1 503 Service Unavailable\r\n"
echo -e "Content-Type: text/html\r\n"
echo -e "Content-Length: 48\r\n"
echo -e "\r\n"
echo -e "<html><body>PostgreSQL is *down*.</body></html>\r\n"
echo -e "\r\n"
unset PGUSER
unset PGPASSWORD
exit 1
}
if [ -f "$FORCE_FAIL" ]; then
return_fail;
fi
# check if in recovery mode (that means it is a 'slave')
SLAVE=$(psql -qt -c "$SLAVE_CHECK" 2>/dev/null)
if [ $? -ne 0 ]; then
return_fail;
elif echo $SLAVE | egrep -i "(t|true|on|1)" 2>/dev/null >/dev/null; then
return_ok "slave"
fi
# check if writable (then we consider it as a 'master')
READONLY=$(psql -qt -c "$WRITABLE_CHECK" 2>/dev/null)
if [ $? -ne 0 ]; then
return_fail;
elif echo $READONLY | egrep -i "(f|false|off|0)" 2>/dev/null >/dev/null; then
return_ok "master"
fi
return_ok "none";
Bruger/adgangskodekombinationen skal være en gyldig ROLLE på din PostgreSQL-server. Da vi installerer via ClusterControl, håndteres dette automatisk.
Nu hvor vi har en komplet HAProxy-installation, giver denne opsætning os mulighed for at have en læse-skrive-opdeling, hvor læse-skrive går til den primære eller skrivbare node, hvorimod skrivebeskyttet for både primær og sekundær/ gendannelsesknuder. Denne opsætning betyder ikke, at den allerede er effektiv, den er stadig blevet justeret som diskuteret tidligere med en kombination af HAProxy til belastningsbalancering, der tilføjer mere ydeevne for din applikation og de respektive databaseklienter.