sql >> Databasteknik >  >> RDS >> PostgreSQL

Driving Performance för PostgreSQL med HAProxy

Databasprestanda är ett mycket viktigt problem när du underhåller ditt databaskluster, särskilt när det växer med tiden. Detta gäller särskilt om din applikation började med låg trafik och sedan ökade till måttlig eller tung läs-skrivarbetsbelastning.

Det man bör komma ihåg är att det inte finns någon perfekt konfiguration som du kan lita på under lång tid, eftersom vissa arbetsbelastningar kan förändras över tiden.

Med ClusterControl, skapar eller distribuerar ett nytt PostgreSQL-databaskluster en grundläggande analys som att kontrollera dina hårdvaruresurser, tillämpar sedan automatisk justering och ställer in värdena för de valda inställbara parametrarna. I takt med att PostgreSQL utvecklas har många verktyg också utvecklats för att stödja olika konfigurationer, speciellt för lastbalansering.

I den här bloggen tar vi en titt på vikten av HAProxy och hur det kan hjälpa till att öka prestanda. Det är ett gammalt verktyg, men ändå en kraftfull proxy och/eller lastbalanserare som stöder inte bara databasservrar utan även nätverksprogramspecifika protokoll. HAProxy kan arbeta via lager fyra respektive lager sju, beroende på typen av konfiguration baserat på konfigurationen.

PostgreSQL-prestandajustering

En av de primära faktorerna för att driva prestanda för PostgreSQL börjar med den grundläggande parameterinställningen från initdb till runtime parametervärden. Detta måste kunna hantera önskad arbetsbelastning i enlighet med dina specifika krav. Innan vi kan ta en väg för HAProxy-funktionen för PostgreSQL måste din databasserver vara stabil och inställd på önskade variabler. Låt oss ta en lista över områden för PostgreSQL om vad som kan påverka prestandadrivningen för din databasserver.

Inställning för genomförbar minneshantering

PostgreSQL är effektivt och det är möjligt att köra effektivt på så lite som 256 Mb minne. Minnet är inte dyrt, men de flesta datamängder är mindre än 4Gib. Om du har minst 4Gib kan din aktiva datamängd finnas kvar i fil- och/eller shared_buffer-cache.

Att ställa in din PostgreSQL för minneshantering är en av de mest primära och grundläggande sakerna som du behöver ställa in. Om du ställer in den på rätt sätt kan det påverka prestandan för din databasserver. Även om det beror på vilken typ av bord du spelar med. Dåliga frågor och dåliga tabelldefinitioner kan också leda till dålig prestanda. Med korrekta index definierade för dina tabeller och med frågor som hänvisar till index, kan chansen nå från 80 % - 100 % av frågorna kan hämtas från ditt minne. Detta speciellt om indexbufferten har rätt värde för att ladda ditt definierade index på dina tabeller. Låt oss titta på de parametrar som vanligtvis ställs in för att förbättra prestanda.

  • shared_buffers - PostgreSQL dimensionerar sitt huvudsakliga minnesutrymme med shared_buffers. Arbetscachen för alla hot tuples (och indexposter) inom PostgreSQL. Den här parametern ställer in mängden minne som databasservern använder för delade minnesbuffertar. Det är en förtilldelad cache (buffertar). För Linux-baserade system är det idealiskt att ställa in kärnparametern kernel.shmmax som kan ställas in konstant via /etc/sysctl.conf kärnkonfigurationsfil.
  • temp_buffers - Ställer in det maximala antalet tillfälliga buffertar som används för varje session. Dessa är lokala sessionsbuffertar som endast används för att komma åt tillfälliga tabeller. En session kommer att tilldela de temporära buffertarna efter behov upp till gränsen som ges av temp_buffers.
  • work_mem - Arbetsminnet som är tillgängligt för arbetsoperationer (sorteras) innan PostgreSQL kommer att byta. Ställ inte in globalt (postgresql.conf). Använd per transaktion eftersom detta kan vara dåligt per fråga, per anslutning eller per sort. Att använda EXPLAIN ANALYZE rekommenderas för att se om du svämmar över eller inte.
  • maintenance_work_mem - Anger mängden minne som ska användas för underhållsoperationer (VACUUM, CREATE INDEX och ALTER TABLE … LÄGG TILL UTLÄNDSK NYCKEL…)

Inställning för genomförbar diskhantering

Ett antal körtidsparametrar att ställa in här. Låt oss lista vad dessa är:

  • temp_file_limit - Anger den maximala mängden diskutrymme som en session kan använda för temporära filer, till exempel sortera och hasha temporära filer, eller lagringsfilen för en hållen markör. En transaktion som försöker överskrida denna gräns kommer att avbrytas.
  • fsync - Om fsync är aktiverat kommer PostgreSQL att försöka se till att uppdateringarna skrivs fysiskt till disken. Detta säkerställer att databasklustret kan återställas till ett konsekvent tillstånd efter ett operativsystem eller en maskinvarukrasch. Även om inaktivering av fsync i allmänhet förbättrar prestandan, kan det orsaka dataförlust i händelse av ett strömavbrott eller en systemkrasch. Därför är det bara att rekommendera att inaktivera fsync om du enkelt kan återskapa hela din databas från extern data
  • synchronous_commit - Används för att framtvinga att commit väntar på att WAL skrivs på disken innan en framgångsstatus returneras till klienten. Denna variabel har avvägningar mellan prestanda och tillförlitlighet. Om du behöver mer prestanda, ställ in detta på av vilket innebär att när servern kraschar, tendens att stöta på dataförlust. Annars, om tillförlitlighet är viktigt, aktivera detta. Detta innebär att det kommer att finnas en tidsskillnad mellan framgångsstatusen och en garanterad skrivning till disk, vilket kan påverka prestandan.
  • checkpoint_timeout, checkpoint_completion_target – PostgreSQL skriver ändringar till WAL, vilket är en dyr operation. Om det ofta skriver ändringar till WAL kan det påverka prestandan dåligt. Så hur det fungerar, checkpointprocessen spolar in data i datafilerna. Denna aktivitet görs när CHECKPOINT inträffar och kan orsaka en enorm mängd IO. Hela denna process involverar dyra läs-/skrivoperationer för disk. Även om du (adminanvändare) alltid kan utfärda CHECKPOINT när det verkar nödvändigt eller automatisera det genom att ställa in önskade värden för dessa parametrar. Parametern checkpoint_timeout används för att ställa in tid mellan WAL-kontrollpunkter. Att ställa in detta för lågt minskar kraschåterställningstiden, eftersom mer data skrivs till disken, men det skadar också prestandan eftersom varje kontrollpunkt slutar att förbruka värdefulla systemresurser. Checkpoint_completion_target är bråkdelen av tiden mellan checkpoints för att checkpoint fullbordas. En hög frekvens av kontrollpunkter kan påverka prestandan. För smidig kontroll måste checkpoint_timeout vara ett lågt värde. Annars kommer operativsystemet att samla alla smutsiga sidor tills förhållandet är uppfyllt och sedan gå till en stor spolning.

Justera andra parametrar för prestanda

Det finns vissa parametrar som ger boost och drivkraft för prestanda i PostgreSQL. Låt oss lista vad dessa är nedan:

  • wal_buffers - PostgreSQL skriver sin WAL-post (write ahead log) i buffertarna och sedan spolas dessa buffertar till disken. Standardstorleken på bufferten, definierad av wal_buffers, är 16 MB, men om du har många samtidiga anslutningar kan ett högre värde ge bättre prestanda.
  • effective_cache_size - Effective_cache_size ger en uppskattning av det tillgängliga minnet för diskcache. Det är bara en riktlinje, inte det exakta tilldelade minnet eller cachestorleken. Den allokerar inte verkligt minne utan talar om för optimeraren hur mycket cache som är tillgängligt i kärnan. Om värdet på detta är inställt för lågt kan frågeplaneraren besluta att inte använda vissa index, även om de skulle vara till hjälp. Därför är det alltid fördelaktigt att ställa in ett stort värde.
  • default_statistics_target - PostgreSQL samlar in statistik från var och en av tabellerna i sin databas för att bestämma hur frågor ska köras på dem. Som standard samlar den inte in för mycket information, och om du inte får bra exekveringsplaner bör du öka detta värde och sedan köra ANALYSE i databasen igen (eller vänta på AUTOVACUUM).

PostgreSQL-frågeeffektivitet 

PostgreSQL har en mycket kraftfull funktion för att optimera frågor. Med den inbyggda Genetic Query Optimizer (känd som GEQO). Den använder en genetisk algoritm som är en heuristisk optimeringsmetod genom randomiserad sökning. Detta tillämpas när man utför optimering med JOINs vilket ger en mycket bra prestandaoptimering. Varje kandidat i sammanfogningsplanen representeras av en sekvens i vilken basrelationerna ska sammanfogas. Den utför slumpmässigt ett genetiskt förhållande genom att helt enkelt generera någon möjlig sammanfogningssekvens men slumpmässigt.

För varje anslutningssekvens som beaktas anropas standardplanerarkoden för att uppskatta kostnaden för att utföra frågan med den kopplingssekvensen. Så för var och en av JOIN-sekvenserna har alla sina initialt bestämda relationsavsökningsplaner. Sedan kommer frågeplanen att beräkna den mest genomförbara och effektiva planen, d.v.s. med lägre uppskattad kostnad och anses vara "mer lämplig" än de med högre kostnad.

Med tanke på att den har en kraftfull funktion integrerad i PostgreSQL och de korrekt konfigurerade parametrarna i enlighet med dina önskade krav, motverkar den inte genomförbarheten när det kommer till prestanda om belastningen bara kastas till en primär nod. Lastbalansering med HAProxy hjälper till med ännu bättre drivprestanda för PostgreSQL.

Öka prestanda för PostgreSQL med läs-skrivdelning 

Du kanske har bra prestanda när du hanterar din PostgreSQL-servernod men du kanske inte kan förutse vilken typ av arbetsbelastning du kan ha, särskilt när hög trafik träffar och efterfrågan går utanför gränsen. Att balansera belastningen mellan en primär och sekundär ger en prestandaökning inom din applikation och/eller klienter som ansluter till ditt PostgreSQL-databaskluster. Hur detta kan göras är inte längre en fråga eftersom det är en mycket vanlig inställning för hög tillgänglighet och redundans när det gäller att fördela belastningen och undvika att den primära noden fastnar på grund av hög belastningsbearbetning.

Det är enkelt att installera med HAProxy. Ändå är det mer effektivt snabbare och genomförbart med ClusterControl. Så vi använder ClusterControl för att ställa in detta åt oss.

Konfigurera PostgreSQL med HAProxy

För att göra detta behöver vi bara installera och ställa in HAProxy ovanpå PostgreSQL-klustren. HAProxy har en funktion för att stödja PostgreSQL genom alternativet pgsql-check men dess stöd är en mycket enkel implementering för att avgöra om en nod är uppe eller inte. Den har inga kontroller för att identifiera en primär och en återställningsnod. Ett alternativ är att använda xinetd som vi förlitar oss på att kommunicera HAProxy för att lyssna via vår xinetd-tjänst som kontrollerar tillståndet för en viss nod i vårt PostgreSQL-kluster.

Under ClusterControl, navigera till Hantera → Load Balancer precis som nedan,

Följ sedan baserat på gränssnittet enligt skärmbilden nedan. Du kan klicka på Visa avancerade inställningar för att se fler avancerade alternativ. Att följa användargränssnittet är dock väldigt enkelt. Se nedan,

Jag importerar endast en enda nod HAProxy utan redundans men i syfte att den här bloggen, låt oss göra det enklare.

Mitt exempel på HAProxy-vy visas nedan,

Som visas ovan är 192.168.30.20 och 192.168.30.30 de primära respektive sekundära/återställningsnoder. Medan HAProxy är installerad i den sekundära/återställningsnoden. Helst kan du installera din HAProxy på flera noder för att få mer redundans och mycket tillgänglig, det är bäst att isolera den mot databasnoderna. Om du har knappt med budget eller sparar på din användning, kan du välja att installera dina HAProxy-noder, där dina databasnoder också är installerade.

ClusterControl ställer in detta automatiskt och inkluderar även xinetd-tjänsten för PostgreSQL-kontroll. Detta kan verifieras med netstat precis som nedan,

[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

Medan port 5433 är läs-skriv och 5444 är skrivskyddad.

För PostgreSQL, kontrollera efter xinetd-tjänst, nämligen postgreshk som visas nedan,

[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-tjänsterna är också beroende av /etc/services så att du kanske kan hitta porten som är avsedd att kartlägga.

[email protected]:~# grep postgreschk /etc/services

postgreschk        9201/tcp

Om du behöver ändra porten för din postgreschk till vilken port som ska mappas, måste du ändra denna fil förutom tjänstens konfigurationsfil och glöm inte att starta om xinetd daemon.

Tjänsten postgreschk innehåller en referens till en extern fil som i princip gör en kontroll av noder om den är skrivbar, vilket betyder att den är en primär eller en master. Om en nod är under återställning är det en replika eller en återställningsnod.

[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";

Kombinationen av användare/lösenord måste vara en giltig ROLL i din PostgreSQL-server. Eftersom vi installerar via ClusterControl, hanteras detta automatiskt.

Nu när vi har en komplett HAProxy-installation tillåter denna inställning oss att ha en läs-skriv-delning där läs-skriver går till den primära eller skrivbara noden, medan skrivskyddad för både primär och sekundär/ återställningsnoder. Den här inställningen betyder inte att den redan fungerar, den har fortfarande finjusterats som diskuterats tidigare med en kombination av HAProxy för lastbalansering, vilket ger mer prestandaökning för din applikation och respektive databasklienter.


  1. DEGREES() Exempel i SQL Server

  2. PostgreSQL - GROUP BY-klausul

  3. Hur man lägger till administratörsservern i R12.2

  4. syntaxfel med uppdateringsfråga när du går med i någon tabell