Konfiguracja parametrów jądra Linux w celu optymalizacji PostgreSQL

Konfiguracja parametrów jądra Linux w celu optymalizacji PostgreSQL Optymalna wydajność PostgreSQL zależy od odpowiednio określonych parametrów systemu operacyjnego. Źle skonfigurowane parametry jądra OS mogą prowadzić do spadku wydajności serwera bazy danych. Dlatego konieczne jest, aby te parametry były dostosowane do serwera bazy danych i jego obciążenia roboczego. W tym wpisie omówimy niektóre ważne parametry jądra Linux, które mogą wpłynąć na wydajność serwera bazy danych oraz sposoby ich konfiguracji.

SHMMAX / SHMALL

SHMMAX — to parametr jądra, używany do określenia maksymalnego rozmiaru jednego segmentu pamięci dzielonej (shared memory), który może przydzielić proces Linux. Do wersji 9.2 PostgreSQL używał System V (SysV), dla którego wymagana była konfiguracja SHMMAX. Po 9.2 PostgreSQL przeszedł na pamięć dzieloną POSIX. Tak więc teraz wymaga się mniej bajtów pamięci dzielonej System V.

Do wersji 9.3 SHMMAX był najważniejszym parametrem jądra. Wartość SHMMAX jest określana w bajtach.

Podobnie, SHMALL — to kolejny parametr jądra, używany do określenia
całkowitej objętości stron pamięci dzielonej (shared memory). Aby zobaczyć aktualne wartości SHMMAX, SHMALL lub SHMMIN, użyj polecenia ipcs.

SHM* Szczegóły — Linux

$ ipcs -lm

------ Limity Pamięci Dzielonej --------
max liczba segmentów = 4096
max rozmiar segmentu (kB) = 1073741824
max całkowita pamięć dzielona (kB) = 17179869184
min rozmiar segmentu (bajty) = 1

SHM* Szczegóły — MacOS X

$ ipcs -M
Status IPC na dzień Thu Aug 16 22:20:35 PKT 2018
shminfo:
	shmmax: 16777216	(maxymalny rozmiar segmentu pamięci dzielonej)
	shmmin:       1	(minimalny rozmiar segmentu pamięci dzielonej)
	shmmni:      32	(maxymalna liczba identyfikatorów pamięci dzielonej)
	shmseg:       8	(maxymalna liczba segmentów pamięci dzielonej na proces)
	shmall:    1024	(maxymalna ilość pamięci dzielonej w stronach)

PostgreSQL używa System V IPC do przydzielania pamięci dzielonej. Ten parametr jest jednym z najważniejszych parametrów jądra. Za każdym razem, gdy otrzymujesz następujące komunikaty o błędach, oznacza to, że masz starszą wersję PostgreSQL i bardzo niską wartość SHMMAX. Oczekuje się, że użytkownicy dostosują i zwiększą tę wartość zgodnie z pamięcią dzieloną, którą zamierzają wykorzystać.

Możliwe błędy niewłaściwej konfiguracji

Jeśli SHMMAX jest źle skonfigurowane, możesz otrzymać błąd przy próbie zainicjowania klastra PostgreSQL za pomocą polecenia initdb.

initdb Failure
SZCZEGÓŁY: Nieudane wywołanie systemowe shmget(key=1, size=2072576, 03600).

WSKAZÓWKA: Ten błąd zazwyczaj oznacza, że żądanie PostgreSQL dotyczące segmentu pamięci dzielonej przekroczyło parametr SHMMAX Twojego jądra. 
Możesz albo zmniejszyć rozmiar żądania, albo skonfigurować jądro z większym SHMMAX. Aby zmniejszyć rozmiar żądania (aktualnie 2072576 bajtów),
zmniejsz użycie pamięci współdzielonej PostgreSQL, być może przez zmniejszenie shared_buffers lub max_connections.

Jeżeli rozmiar żądania jest już mały, możliwe, że jest mniejszy niż parametr SHMMIN w twoim jądrze,
w takim przypadku konieczne jest zwiększenie rozmiaru żądania lub skonfigurowanie SHMMIN.

Dokumentacja PostgreSQL zawiera więcej informacji na temat konfiguracji pamięci współdzielonej. Proces potomny zakończył się kodem wyjścia 1

Podobnie, możesz napotkać błąd podczas uruchamiania serwera PostgreSQL, używając komendy pg_ctl.

pg_ctl Błąd
SZCZEGÓŁY: Nieudane wywołanie systemowe to shmget(klucz=5432001, rozmiar=14385152, 03600).

WSKAZÓWKA: Ten błąd zazwyczaj oznacza, że żądanie PostgreSQL dotyczące segmentu pamięci dzielonej przekroczyło parametr SHMMAX Twojego jądra.

Możesz albo zmniejszyć rozmiar żądania, albo skonfigurować jądro z większym SHMMAX. Aby zmniejszyć rozmiar żądania (aktualnie 14385152 bajtów), zmniejsz użycie pamięci współdzielonej PostgreSQL, być może przez zmniejszenie shared_buffers lub max_connections.

Jeżeli rozmiar żądania jest już mały, możliwe, że jest mniejszy niż parametr SHMMIN w twoim jądrze,
w takim przypadku konieczne jest zwiększenie rozmiaru żądania lub skonfigurowanie SHMMIN.

Dokumentacja PostgreSQL zawiera więcej informacji na temat konfiguracji pamięci współdzielonej.

Zrozumienie różnic w definicjach

Definicje parametrów SHMMAX/SHMALL nieco różnią się w Linuxie i MacOS X:

  • Linux: kernel.shmmax, kernel.shmall
  • MacOS X: kern.sysv.shmmax, kern.sysv.shmall

Zespół sysctl może być użyta do tymczasowej zmiany wartości. Aby ustawić trwałe wartości, dodaj wpis do /etc/sysctl.conf. Szczegóły podano poniżej.

Zmiana parametrów jądra w MacOS X

# Get the value of SHMMAX
sudo sysctl kern.sysv.shmmax
kern.sysv.shmmax: 4096

# Get the value of SHMALL
sudo sysctl kern.sysv.shmall 
kern.sysv.shmall: 4096

# Set the value of SHMMAX
sudo sysctl -w kern.sysv.shmmax=16777216
kern.sysv.shmmax: 4096 -> 16777216

# Set the value of SHMALL 
sudo sysctl -w kern.sysv.shmall=16777216
kern.sysv.shmall: 4096 -> 16777216

Zmiana parametrów jądra w Linuxie

# Get the value of SHMMAX
sudo sysctl kernel.shmmax
kernel.shmmax: 4096

# Get the value of SHMALL
sudo sysctl kernel.shmall
kernel.shmall: 4096

# Set the value of SHMMAX
sudo sysctl -w kernel.shmmax=16777216
kernel.shmmax: 4096 -> 16777216

# Set the value of SHMALL 
sudo sysctl -w kernel.shmall=16777216
kernel.shmall: 4096 -> 16777216

Nie zapomnij: aby zmiany były trwałe, dodaj te wartości do /etc/sysctl.conf

Duże strony (Huge Pages)

W Linuxie domyślnie używane są strony pamięci 4 KB, w BSD — Super Pages, a w Windows — Large Pages. Strona jest częścią pamięci RAM przydzieloną procesowi. Proces może mieć kilka stron w zależności od wymagań dotyczących pamięci. Im więcej pamięci wymaga proces, tym więcej stron jest mu przydzielanych. System operacyjny utrzymuje tabelę przydzielania stron dla procesów. Im mniejszy rozmiar strony, tym większa tabela, tym więcej czasu potrzeba na wyszukiwanie strony w tej tabeli stron. Dlatego duże strony pozwalają na korzystanie z dużej ilości pamięci przy zmniejszonym narzuceniu; mniej przeglądania stron, mniej błędów stron, szybsze operacje odczytu/zapisu dzięki dużym buforom. W rezultacie — lepsza wydajność.

PostgreSQL obsługuje duże strony tylko w systemie Linux. Domyślnie system Linux wykorzystuje strony pamięci o rozmiarze 4 KB, dlatego gdy operacji z pamięcią jest za dużo, należy ustawić strony o większym rozmiarze. Zauważono wzrost wydajności przy użyciu dużych stron o rozmiarze 2 MB i do 1 GB. Rozmiar dużej strony można ustawić podczas uruchamiania. Możesz łatwo sprawdzić parametry dużych stron i ich wykorzystanie na swoim komputerze z systemem Linux, używając polecenia cat /proc/meminfo | grep -i huge.

Uzyskiwanie informacji o dużych stronach (tylko w systemie Linux)

Uwaga: Dotyczy to tylko systemu Linux, dla innych systemów ta operacja jest ignorowana
$ cat /proc/meminfo | grep -i huge
AnonHugePages: 0 kB
ShmemHugePages: 0 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB

W tym przykładzie, chociaż rozmiar dużej strony ustawiono na 2048 (2 MB), całkowita liczba dużych stron wynosi 0. Oznacza to, że duże strony są wyłączone.

Skrypt do ustalania liczby dużych stron

To prosty skrypt, który zwraca wymaganą liczbę dużych stron. Uruchom skrypt na swoim serwerze Linux, gdy działa PostgreSQL. Upewnij się, że zmienna środowiskowa $PGDATA wskazuje na katalog danych PostgreSQL.

Uzyskiwanie liczby wymaganych dużych stron

#!/bin/bash
pid=`head -1 $PGDATA/postmaster.pid`
echo "Pid:            $pid"
peak=`grep ^VmPeak /proc/$pid/status | awk '{ print $2 }'`
echo "VmPeak:            $peak kB"
hps=`grep ^Hugepagesize /proc/meminfo | awk '{ print $2 }'`
echo "Hugepagesize:   $hps kB"
hp=$((peak/hps))
echo Set Huge Pages:     $hp

Wynik skryptu wygląda następująco:

Wynik skryptu

Pid: 12737
VmPeak: 180932 kB
Hugepagesize: 2048 kB
Set Huge Pages: 88

Zalecana wartość dużych stron to 88, więc powinieneś ustawić wartość 88.

Ustawienie dużych stron

sysctl -w vm.nr_hugepages=88

Sprawdź teraz duże strony, zobaczysz, że duże strony nie są używane (HugePages_Free = HugePages_Total).

Ponownie informacje o dużych stronach (tylko w systemie Linux)

$ cat /proc/meminfo | grep -i huge
AnonHugePages: 0 kB
ShmemHugePages: 0 kB
HugePages_Total: 88
HugePages_Free: 88
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB

Teraz ustaw parametr huge_pages na „on” w $PGDATA/postgresql.conf i uruchom ponownie serwer.

I ponownie informacje o dużych stronach (tylko w systemie Linux)

$ cat /proc/meminfo | grep -i huge
AnonHugePages: 0 kB
ShmemHugePages: 0 kB
HugePages_Total: 88
HugePages_Free: 81
HugePages_Rsvd: 64
HugePages_Surp: 0
Hugepagesize: 2048 kB

Teraz możesz zobaczyć, że wykorzystano bardzo mało dużych stron. Spróbujmy teraz dodać dane do bazy danych.

Niektóre operacje na bazach danych dotyczące używania dużych stron

postgres=# CREATE TABLE foo(a INTEGER);
CREATE TABLE
postgres=# INSERT INTO foo VALUES(generate_Series(1,10000000));
INSERT 0 10000000

Sprawdźmy, czy obecnie używamy więcej dużych stron niż wcześniej.

Ponownie informacje o dużych stronach (tylko na Linuxie)

$ cat /proc/meminfo | grep -i huge
AnonHugePages:         0 kB
ShmemHugePages:        0 kB
HugePages_Total:      88
HugePages_Free:       18
HugePages_Rsvd:        1
HugePages_Surp:        0
Hugepagesize:       2048 kB

Teraz możesz zobaczyć, że większość dużych stron jest używana.

Uwaga: przybliżona wartość dla HugePages używana tutaj jest bardzo niska, co nie jest normalnym wartością dla maszyny w środowisku produkcyjnym. Proszę ocenić potrzebną liczbę stron dla swojego systemu i ustawić je odpowiednio w zależności od obciążenia i zasobów.

vm.swappiness

vm.swappiness — to kolejny parametr jądra, który może wpływać na wydajność bazy danych. Parametr ten jest używany do zarządzania zachowaniem wymiany (swappiness) (wymiana stron do pamięci i z niej) w Linuxie. Wartość waha się od 0 do 100. Określa, ile pamięci będzie wymienione lub zredukowane. Zero oznacza dezaktywację wymiany, a 100 oznacza agresywną wymianę.

Możesz uzyskać dobrą wydajność, ustawiając niższe wartości.

Ustawienie wartości 0 w nowszych jądrach może spowodować, że OOM Killer (proces oczyszczania pamięci w Linuxie) zabiłby proces. Dlatego można bezpiecznie ustawić wartość 1, jeśli chcesz minimalizować wymianę. Domyślna wartość w Linuxie wynosi 60. Wyższa wartość powoduje, że MMU (jednostka zarządzania pamięcią) używa więcej miejsca na wymianę niż RAM, podczas gdy niższa wartość pozostawia więcej danych/kodu w pamięci.

Niższa wartość to dobre założenie dla poprawy wydajności w PostgreSQL.

vm.overcommit_memory / vm.overcommit_ratio

Aplikacje przydzielają pamięć i zwalniają ją, gdy nie jest już potrzebna. W niektórych przypadkach jednak aplikacja przydziela zbyt dużo pamięci i jej nie zwalnia. Może to spowodować OOM killer. Oto możliwe wartości parametru vm.overcommit_memory z opisem dla każdego:

  1. Heurystyka overcommit (domyślnie); heurystyka oparta na jądrze
  2. Zezwól na overcommit w każdym przypadku
  3. Nie przesadzaj, nie przekraczaj współczynnika overcommit.

Link: https://www.kernel.org/doc/Documentation/vm/overcommit-accounting

vm.overcommit_ratio — procent pamięci RAM dostępnej do nadmiernego wykorzystania. Wartość 50% w systemie z 2 GB RAM może przydzielać do 3 GB RAM.

Wartość 2 dla vm.overcommit_memory zapewnia lepszą wydajność dla PostgreSQL. Ta wartość maksymalizuje wykorzystanie pamięci RAM przez proces serwera bez znaczącego ryzyka bycia zabitym przez proces OOM killer. Aplikacja będzie mogła się ponownie uruchomić, ale tylko w granicach nadmiaru, co zmniejsza ryzyko, że OOM killer zabije proces. W związku z tym wartość 2 daje lepszą wydajność niż domyślna wartość 0. Niemniej jednak niezawodność może być poprawiona poprzez to, że pamięć poza dozwolonym zakresem nie będzie przeciążona. Eliminuję to ryzyko, że proces zostanie zabity przez OOM-killera.

W systemach bez wymiany może wystąpić problem z vm.overcommit_memory równym 2.

https://www.postgresql.org/docs/current/static/kernel-resources.html#LINUX-MEMORY-OVERCOMMIT

vm.dirty_background_ratio / vm.dirty_background_bytes

vm.dirty_background_ratio — jest to procent pamięci zajętej przez brudne strony, które muszą być zapisane na dysk. Zrzut na dysk odbywa się w tle. Wartość tego parametru wynosi od 0 do 100; jednak wartość poniżej 5 może być nieskuteczna, a niektóre jądra jej nie obsługują. 10 jest wartością domyślną w większości systemów Linux. Możesz poprawić wydajność operacji z intensywnym zapisem przy mniejszym współczynniku, co oznacza, że Linux będzie zrzucał brudne strony w tle.

Musisz ustawić wartość vm.dirty_background_bytes w zależności od prędkości twojego dysku.

Dla tych dwóch parametrów nie ma «dobrych» wartości, ponieważ oba zależą od sprzętu. Jednak ustawienie vm.dirty_background_ratio na wartość 5 i vm.dirty_background_bytes na 25% prędkości dysku, poprawia wydajność o ~ 25% w większości przypadków.

vm.dirty_ratio / dirty_bytes

To to samo co vm.dirty_background_ratio / dirty_background_bytes, z tym wyjątkiem, że zrzut jest wykonywany w sesji roboczej, blokując aplikację. Dlatego vm.dirty_ratio powinno być wyższe niż vm.dirty_background_ratio. To gwarantuje, że procesy w tle będą uruchamiane wcześniej, aby uniknąć maksymalnej blokady aplikacji. Możesz dostosować różnicę między tymi dwoma stosunkami w zależności od obciążenia wejścia/wyjścia dysku.

Podsumowanie

Możesz dostosować inne parametry w celu zwiększenia wydajności, ale poprawa będzie minimalna, a korzyści nie będą znaczące. Musimy pamiętać, że nie wszystkie parametry odnoszą się do wszystkich typów aplikacji. Niektóre aplikacje działają lepiej, gdy dostosowujemy niektóre parametry, a inne – nie. Musisz znaleźć odpowiednią równowagę pomiędzy konfiguracjami tych parametrów a oczekiwaną obciążeniem roboczym i typem aplikacji, a także przy dostosowywaniu należy uwzględnić zachowanie systemu operacyjnego. Dostosowanie parametrów jądra nie jest tak proste, jak dostosowanie parametrów bazy danych: tu jest trudniej udzielić jednoznacznych rekomendacji.

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster