PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Zwiększanie wydajności PostgreSQL dzięki HAProxy

Wydajność bazy danych jest bardzo ważnym problemem podczas utrzymywania klastra bazy danych, zwłaszcza, gdy rośnie on z biegiem czasu. Jest to szczególnie ważne, jeśli aplikacja zaczynała od małego ruchu, a następnie rosła do umiarkowanych lub dużych obciążeń odczytu i zapisu.

Należy pamiętać, że nie ma idealnej konfiguracji, na której można by polegać przez długi czas, ponieważ niektóre obciążenia mogą się zmieniać z czasem.

Dzięki ClusterControl tworzenie lub wdrażanie nowego klastra bazy danych PostgreSQL przeprowadza podstawową analizę, taką jak sprawdzenie zasobów sprzętowych, a następnie stosuje automatyczne dostrajanie i ustawia wartości dla wybranych parametrów, które można dostroić. Wraz z rozwojem PostgreSQL powstało wiele narzędzi do obsługi różnych konfiguracji, zwłaszcza do równoważenia obciążenia.

W tym blogu przyjrzymy się, jak ważna jest HAProxy i jak może pomóc w zwiększeniu wydajności. Jest to stare narzędzie, ale potężne proxy i/lub load balancer, które obsługuje nie tylko serwery baz danych, ale także protokoły aplikacji sieciowych. HAProxy może działać odpowiednio w warstwie czwartej i warstwie siódmej, w zależności od rodzaju konfiguracji w oparciu o konfigurację.

Dostrajanie wydajności PostgreSQL

Jeden z głównych czynników wpływających na wydajność PostgreSQL zaczyna się od podstawowego dostrojenia parametrów od initdb do wartości parametrów środowiska wykonawczego. To musi być w stanie obsłużyć pożądane obciążenie pracą zgodnie z określonymi wymaganiami. Zanim będziemy mogli skorzystać z funkcji HAProxy dla PostgreSQL, serwer bazy danych musi być stabilny i dostrojony do żądanych zmiennych. Zróbmy listę obszarów dla PostgreSQL na temat tego, co może wpłynąć na wydajność serwera bazy danych.

Dostrajanie pod kątem możliwego zarządzania pamięcią

PostgreSQL jest wydajny i można go efektywnie uruchomić na zaledwie 256 MB pamięci. Pamięć nie jest droga, ale większość zestawów danych ma mniej niż 4 GB. Jeśli masz co najmniej 4 GB, Twój aktywny zestaw danych może pozostać w pamięci podręcznej plików i/lub shared_buffer.

Dostrajanie PostgreSQL do zarządzania pamięcią jest jedną z najbardziej podstawowych i podstawowych rzeczy, które musisz ustawić. Odpowiednie ustawienie może wpłynąć na zwiększenie wydajności serwera bazy danych. Chociaż zależy to od tego, przy jakich stołach grasz. Złe zapytania i słabe definicje tabel mogą również prowadzić do niskiej wydajności. Przy odpowiednich indeksach zdefiniowanych w Twoich tabelach i zapytaniach odwołujących się do indeksów, szanse mogą sięgać od 80% do 100% zapytań, które można pobrać z Twojej pamięci. Zwłaszcza jeśli bufor indeksów ma odpowiednią wartość do załadowania indeksu zdefiniowanego w twoich tabelach. Przyjrzyjmy się parametrom, które są zwykle ustawiane w celu poprawy wydajności.

  • shared_buffers - PostgreSQL powiększa swoją główną przestrzeń pamięci za pomocą shared_buffers. Działająca pamięć podręczna wszystkich gorących krotek (i wpisów indeksu) w PostgreSQL. Ten parametr określa ilość pamięci używanej przez serwer bazy danych na bufory pamięci współużytkowanej. Jest to wstępnie przydzielona pamięć podręczna (bufory). W przypadku systemów opartych na Linuksie idealnym rozwiązaniem jest ustawienie parametru jądra kernel.shmmax, który można ustawić na stałe za pomocą pliku konfiguracyjnego jądra /etc/sysctl.conf.
  • temp_buffers — Ustawia maksymalną liczbę buforów tymczasowych używanych w każdej sesji. Są to lokalne bufory sesji używane tylko do dostępu do tabel tymczasowych. Sesja przypisze tymczasowe bufory zgodnie z potrzebami do limitu podanego przez temp_buffers.
  • work_mem - Pamięć robocza dostępna dla operacji roboczych (sortowanie) przed zamianą PostgreSQL. Nie ustawiaj globalnie (postgresql.conf). Użyj na transakcję, ponieważ może to być złe dla zapytania, połączenia lub sortowania. Zalecane jest użycie EXPLAIN ANALYZE, aby sprawdzić, czy jesteś przepełniony, czy nie.
  • maintenance_work_mem - Określa ilość pamięci używanej do operacji konserwacyjnych (VACUUM, CREATE INDEX i ALTER TABLE… ADD FOREIGN KEY…)

Dostrajanie pod kątem możliwego zarządzania dyskami

Liczba parametrów wykonawczych do ustawienia w tym miejscu. Wymieńmy, co to jest:

  • temp_file_limit — Określa maksymalną ilość miejsca na dysku, jaką sesja może wykorzystać na pliki tymczasowe, takie jak sortowanie i mieszanie plików tymczasowych lub plik pamięci dla zatrzymanego kursora. Transakcja próbująca przekroczyć ten limit zostanie anulowana.
  • fsync - Jeśli fsync jest włączone, PostgreSQL spróbuje upewnić się, że aktualizacje są fizycznie zapisywane na dysku. Dzięki temu klaster bazy danych można odzyskać do spójnego stanu po awarii systemu operacyjnego lub sprzętu. Chociaż wyłączenie fsync ogólnie poprawia wydajność, może spowodować utratę danych w przypadku awarii zasilania lub awarii systemu. Dlatego zaleca się wyłączenie fsync tylko wtedy, gdy możesz łatwo odtworzyć całą bazę danych z danych zewnętrznych
  • synchronous_commit — Służy do wymuszenia, że ​​zatwierdzenie będzie czekać na zapisanie WAL na dysku przed zwróceniem statusu sukcesu do klienta. Ta zmienna ma kompromis między wydajnością a niezawodnością. Jeśli potrzebujesz większej wydajności, wyłącz to, co oznacza, że ​​w przypadku awarii serwera występuje tendencja do utraty danych. W przeciwnym razie, jeśli niezawodność jest ważna, włącz tę opcję. Oznacza to, że będzie istniała przerwa czasowa między statusem sukcesu a gwarantowanym zapisem na dysku, co może mieć wpływ na wydajność.
  • checkpoint_timeout, checkpoint_completion_target - PostgreSQL zapisuje zmiany w WAL, co jest kosztowną operacją. Jeśli często zapisuje zmiany w WAL, może to mieć słaby wpływ na wydajność. Jak to działa, proces punktu kontrolnego opróżnia dane do plików danych. Ta czynność jest wykonywana, gdy wystąpi CHECKPOINT i może spowodować ogromną ilość IO. Cały ten proces obejmuje kosztowne operacje odczytu/zapisu na dysku. Chociaż Ty (administrator) zawsze możesz wystawić CHECKPOINT, gdy wydaje się to konieczne, lub zautomatyzować to, ustawiając żądane wartości dla tych parametrów. Parametr checkpoint_timeout służy do ustawiania czasu między punktami kontrolnymi WAL. Ustawienie zbyt niskiego poziomu skraca czas odzyskiwania po awarii, ponieważ na dysku jest zapisywanych więcej danych, ale wpływa to również na wydajność, ponieważ każdy punkt kontrolny zużywa cenne zasoby systemowe. checkpoint_completion_target to ułamek czasu między punktami kontrolnymi do zakończenia punktu kontrolnego. Wysoka częstotliwość punktów kontrolnych może wpłynąć na wydajność. Aby zapewnić płynne wskazywanie punktów kontrolnych, checkpoint_timeout musi mieć niską wartość. W przeciwnym razie system operacyjny akumuluje wszystkie brudne strony, aż stosunek zostanie spełniony, a następnie przejdzie do dużego rzutu.

Dostrajanie innych parametrów pod kątem wydajności

Istnieją pewne parametry, które zapewniają przyspieszenie i napęd dla wydajności w PostgreSQL. Wymieńmy poniżej:

  • wal_buffers - PostgreSQL zapisuje swój rekord WAL (zapis z wyprzedzeniem) do buforów, a następnie bufory te są opróżniane na dysk. Domyślny rozmiar bufora, zdefiniowany przez wal_buffers, to 16 MB, ale jeśli masz dużo jednoczesnych połączeń, wyższa wartość może zapewnić lepszą wydajność.
  • efektywny_rozmiar_cache - Efektywny_rozmiar_cache zapewnia oszacowanie ilości pamięci dostępnej do buforowania dysku. To tylko wskazówka, a nie dokładna przydzielona pamięć lub rozmiar pamięci podręcznej. Nie przydziela rzeczywistej pamięci, ale informuje optymalizator o ilości pamięci podręcznej dostępnej w jądrze. Jeśli wartość tego jest zbyt niska, planer zapytań może zdecydować, że nie będzie używać niektórych indeksów, nawet jeśli byłyby pomocne. Dlatego ustawienie dużej wartości jest zawsze korzystne.
  • default_statistics_target - PostgreSQL zbiera statystyki z każdej tabeli w swojej bazie danych, aby decydować o tym, jak będą wykonywane na nich zapytania. Domyślnie nie zbiera zbyt wielu informacji, a jeśli nie otrzymujesz dobrych planów wykonania, powinieneś zwiększyć tę wartość, a następnie ponownie uruchomić ANALIZA w bazie danych (lub poczekać na AUTOVACUUM).

Wydajność zapytań PostgreSQL 

PostgreSQL ma bardzo potężną funkcję optymalizacji zapytań. Z wbudowanym Genetycznym Optymalizatorem Zapytań (znanym jako GEQO). Wykorzystuje algorytm genetyczny, który jest heurystyczną metodą optymalizacji poprzez wyszukiwanie losowe. Jest to stosowane podczas wykonywania optymalizacji przy użyciu JOIN, co zapewnia bardzo dobrą optymalizację wydajności. Każdy kandydat w planie złączenia jest reprezentowany przez sekwencję, w której należy dołączyć do relacji podstawowych. Losowo wykonuje relację genetyczną, po prostu generując pewną możliwą sekwencję złączenia, ale losowo.

Dla każdej rozważanej sekwencji łączenia wywoływany jest standardowy kod planera w celu oszacowania kosztu wykonania zapytania przy użyciu tej sekwencji łączenia. Tak więc dla każdej z sekwencji JOIN, wszystkie mają swoje wstępnie określone plany skanowania relacji. Następnie plan zapytań obliczy najbardziej wykonalny i wydajny plan, tj. z niższym szacowanym kosztem i będzie uważany za „bardziej dopasowany” niż te o wyższych kosztach.

Biorąc pod uwagę, że ma potężną funkcję zintegrowaną z PostgreSQL i odpowiednio skonfigurowane parametry zgodnie z pożądanymi wymaganiami, nie umniejsza to wykonalności, jeśli chodzi o wydajność, jeśli obciążenie jest rzucane tylko na węzeł główny. Równoważenie obciążenia za pomocą HAProxy zapewnia jeszcze większą wydajność dysku dla PostgreSQL.

Zwiększanie wydajności PostgreSQL dzięki dzieleniu odczytu i zapisu

Możesz mieć świetną wydajność radzenia sobie z węzłem serwera PostgreSQL, ale możesz nie być w stanie przewidzieć, jaki rodzaj obciążenia możesz mieć, zwłaszcza gdy pojawia się duży ruch, a popyt wykracza poza granice. Równoważenie obciążenia między podstawowym i dodatkowym zapewnia wzrost wydajności aplikacji i/lub klientów łączących się z klastrem bazy danych PostgreSQL. Jak to zrobić, nie jest już pytaniem, ponieważ jest to bardzo powszechna konfiguracja zapewniająca wysoką dostępność i nadmiarowość, jeśli chodzi o dystrybucję obciążenia i unikanie ugrzęźnięcia głównego węzła z powodu przetwarzania dużego obciążenia.

Konfiguracja z HAProxy jest łatwa. Jednak jest to wydajniejsze, szybsze i bardziej wykonalne dzięki ClusterControl. Dlatego użyjemy ClusterControl, aby to dla nas skonfigurować.

Konfiguracja PostgreSQL z HAProxy

W tym celu wystarczy zainstalować i skonfigurować HAProxy na szczycie klastrów PostgreSQL. HAProxy ma funkcję obsługi PostgreSQL poprzez opcję pgsql-check, ale jej obsługa jest bardzo prostą implementacją do określenia, czy węzeł jest uruchomiony, czy nie. Nie ma kontroli identyfikujących węzeł główny i węzeł odzyskiwania. Opcją jest użycie xinetd, dla którego będziemy polegać na przekazywaniu HAProxy do nasłuchiwania za pośrednictwem naszej usługi xinetd, która sprawdza stan konkretnego węzła w naszym klastrze PostgreSQL.

W ClusterControl przejdź do Zarządzaj → Load Balancer, jak poniżej,

Następnie postępuj zgodnie z interfejsem użytkownika na poniższym zrzucie ekranu. Możesz kliknąć Pokaż ustawienia zaawansowane, aby wyświetlić bardziej zaawansowane opcje. Śledzenie interfejsu użytkownika jest jednak bardzo proste. Zobacz poniżej,

Importuję tylko jeden węzeł HAProxy bez nadmiarowości, ale w celu tego bloga, uprośćmy to.

Mój przykładowy widok HAProxy jest pokazany poniżej,

Jak pokazano powyżej, 192.168.30.20 i 192.168.30.30 są podstawowymi oraz odpowiednio węzły wtórne/odzyskiwania. Natomiast HAProxy jest zainstalowany w węźle pomocniczym/odzyskiwania. W idealnym przypadku możesz zainstalować HAProxy na wielu węzłach, aby mieć większą nadmiarowość i wysoką dostępność, najlepiej jest odizolować go od węzłów bazy danych. Jeśli masz napięty budżet lub oszczędne użytkowanie, możesz zdecydować się na zainstalowanie węzłów HAProxy, w których zainstalowane są również węzły bazy danych.

ClusterControl konfiguruje to automatycznie i obejmuje również usługę xinetd do sprawdzania PostgreSQL. Można to zweryfikować za pomocą netstat, tak jak poniżej,

[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

Podczas gdy port 5433 jest przeznaczony do odczytu i zapisu, a 5444 jest tylko do odczytu.

Dla PostgreSQL sprawdź usługę xinetd, a mianowicie postgreshk, jak widać poniżej,

[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

}

Usługi xinetd również opierają się na /etc/services, więc możesz być w stanie znaleźć port, który jest przeznaczony do mapowania.

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

postgreschk        9201/tcp

Jeśli chcesz zmienić port swojego postgreschk na port do mapowania, musisz zmienić ten plik, a także plik konfiguracyjny usługi, a następnie nie zapomnij zrestartować demona xinetd.

Usługa postgreschk zawiera odniesienie do zewnętrznego pliku, który zasadniczo sprawdza węzły, czy jest zapisywalny, co oznacza, że ​​jest plikiem podstawowym lub głównym. Jeśli węzeł znajduje się w trybie odzyskiwania, jest to replika lub węzeł odzyskiwania.

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

Kombinacja użytkownika/hasła musi być prawidłową ROLE na twoim serwerze PostgreSQL. Ponieważ instalujemy poprzez ClusterControl, jest to obsługiwane automatycznie.

Teraz, gdy mamy kompletną instalację HAProxy, ta konfiguracja pozwala nam na dzielenie odczytu i zapisu, w którym odczyt-zapis idą do węzła podstawowego lub z możliwością zapisu, podczas gdy tylko do odczytu dla głównego i dodatkowego/ węzły odzyskiwania. Ta konfiguracja nie oznacza, że ​​jest już wydajna, nadal została dostrojona, jak omówiono wcześniej, z kombinacją HAProxy do równoważenia obciążenia, która zwiększa wydajność aplikacji i odpowiednich klientów baz danych.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Różnica wydajności:warunek umieszczony w klauzuli INNER JOIN vs WHERE

  2. pghoard Alternatywy - Zarządzanie kopiami zapasowymi PostgreSQL z ClusterControl

  3. Jak skonfigurować postgresql po raz pierwszy?

  4. dołącz do dwóch różnych tabel i usuń zduplikowane wpisy

  5. Zrzut Postgres zawierający tylko części tabel dla migawki dewelopera