Podešavanje opcija Linux kernela za optimizaciju PostgreSQL-a

Podešavanje opcija Linux kernela za optimizaciju PostgreSQL-a Optimalne performanse PostgreSQL-a zavise od ispravno definisanih parametara operativnog sistema. Loše konfigurirane postavke kernela OS-a mogu rezultirati lošim performansama poslužitelja baze podataka. Stoga je imperativ da se ove postavke konfiguriraju prema poslužitelju baze podataka i njegovom radnom opterećenju. U ovom postu ćemo raspravljati o nekim važnim parametrima jezgre Linuxa koji mogu utjecati na performanse poslužitelja baze podataka i kako ih konfigurirati.

SHMMAX / SHMALL

SHMMAX je parametar kernela koji se koristi za određivanje maksimalne veličine jednog segmenta dijeljene memorije koji Linux proces može dodijeliti. Prije verzije 9.2, PostgreSQL je koristio System V (SysV), koji zahtijeva postavku SHMMAX. Nakon 9.2, PostgreSQL je prešao na POSIX zajedničku memoriju. Dakle, sada je potrebno manje bajtova dijeljene memorije System V.

Prije verzije 9.3, SHMMAX je bio najvažniji parametar kernela. SHMMAX vrijednost je navedena u bajtovima.

Slično tome SHMALL je još jedan parametar kernela koji se koristi za određivanje
volumen stranica dijeljene memorije u cijelom sistemu. Za prikaz trenutnih vrijednosti SHMMAX, SHMALL ili SHMMIN koristite naredbu ipcs.

SHM* Detalji - Linux

$ ipcs -lm

------ Shared Memory Limits --------
max number of segments = 4096
max seg size (kbytes) = 1073741824
max total shared memory (kbytes) = 17179869184
min seg size (bytes) = 1

SHM* Detalji - MacOS X

$ ipcs -M
IPC status from  as of Thu Aug 16 22:20:35 PKT 2018
shminfo:
	shmmax: 16777216	(max shared memory segment size)
	shmmin:       1	(min shared memory segment size)
	shmmni:      32	(max number of shared memory identifiers)
	shmseg:       8	(max shared memory segments per process)
	shmall:    1024	(max amount of shared memory in pages)

PostgreSQL koristi Sistem V IPC da dodijelite zajedničku memoriju. Ovaj parametar je jedan od najvažnijih parametara kernela. Kad god primite sljedeće poruke o grešci, to znači da imate stariju verziju PostgreSQL-a i da je vaša SHMMAX vrijednost vrlo niska. Od korisnika se očekuje da prilagode i povećaju vrijednost prema zajedničkoj memoriji koju namjeravaju koristiti.

Moguće greške u pogrešnoj konfiguraciji

Ako SHMMAX nije ispravno konfiguriran, možete dobiti grešku kada pokušate inicijalizirati PostgreSQL klaster pomoću naredbe initdb.

initdb Failure
DETAIL: Failed system call was shmget(key=1, size=2072576, 03600).

HINT: This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter. 
You can either reduce the request size or reconfigure the kernel with larger SHMMAX. To reduce the request size (currently 2072576 bytes),
reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.

If the request size is already small, it's possible that it is less than your kernel's SHMMIN parameter,
in which case raising the request size or reconfiguring SHMMIN is called for.

The PostgreSQL documentation contains more information about shared memory configuration. child process exited with exit code 1

Isto tako, možete dobiti grešku prilikom pokretanja PostgreSQL servera pomoću naredbe pg_ctl.

pg_ctl Greška
DETAIL: Failed system call was shmget(key=5432001, size=14385152, 03600).

HINT: This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter.

You can either reduce the request size or reconfigure the kernel with larger SHMMAX.; To reduce the request size (currently 14385152 bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.

If the request size is already small, it's possible that it is less than your kernel's SHMMIN parameter,
in which case raising the request size or reconfiguring SHMMIN is called for.

The PostgreSQL documentation contains more information about shared memory configuration.

Razumijevanje razlika u definicijama

Definiranje SHMMAX/SHMALL parametara je malo drugačije na Linux i MacOS X:

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

tim sysctl može se koristiti za privremenu promjenu vrijednosti. Da biste postavili konstantne vrijednosti, dodajte unos u /etc/sysctl.conf. Detalji su u nastavku.

Promjena postavki kernela na 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

Promjena parametara kernela na Linuxu

# 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

Nemoj zaboraviti: Da bi promjene bile trajne, dodajte ove vrijednosti u /etc/sysctl.conf

Ogromne stranice

Linux koristi 4 KB memorijske stranice po defaultu, BSD koristi XNUMX KB memorijske stranice. Super stranice, a na Windows-u - Velike stranice. Stranica je dio RAM-a koji je dodijeljen procesu. Proces može imati više stranica ovisno o zahtjevima za memorijom. Što više memorije proces zahtijeva, više stranica mu se dodjeljuje. OS održava tablicu dodjele stranica za procese. Što je manja veličina stranice, veća je tabela, duže je potrebno da se stranica pronađe u toj tabeli stranica. Velike stranice stoga omogućavaju korištenje velikih količina memorije sa smanjenim troškovima; manje pregleda stranica, manje grešaka stranica, brže operacije čitanja/pisanja preko većih bafera. Rezultat su poboljšane performanse.

PostgreSQL podržava samo velike stranice na Linuxu. Linux podrazumevano koristi memorijske stranice od 4 KB, tako da je u slučajevima kada ima previše memorijskih operacija potrebno postaviti veće stranice. Porast performansi se primećuje kada se koriste velike stranice od 2 MB i do 1 GB. Velika veličina stranice može se podesiti prilikom pokretanja. Možete jednostavno provjeriti velike parametre stranice i njihovu upotrebu na vašem Linux stroju pomoću naredbe mačka /proc/meminfo | grep -i ogroman.

Dobivanje informacija o velikim stranicama (samo za Linux)

Note: This is only for Linux, for other OS this operation is ignored$ 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

U ovom primjeru, iako je velika veličina stranice postavljena na 2048 (2 MB), ukupan broj velikih stranica je postavljen na 0. To znači da su velike stranice onemogućene.

Skripta za određivanje broja velikih stranica

Ova jednostavna skripta vraća potreban broj velikih stranica. Pokrenite skriptu na svom Linux serveru dok je PostgreSQL pokrenut. Uvjerite se da je to za varijablu okruženja $PGDATA PostgreSQL direktorij podataka je specificiran.

Dobivanje broja potrebnih velikih stranica

#!/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

Izlaz skripte izgleda ovako:

Izlaz skripte

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

Preporučena vrijednost za velike stranice je 88, tako da biste je trebali postaviti na 88.

Instaliranje velikih stranica

sysctl -w vm.nr_hugepages=88

Provjerite sada velike stranice, vidjet ćete da se velike stranice ne koriste (HugePages_Free = HugePages_Total).

Ponovno posjećene velike stranice (samo za 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

Sada postavite parametar huge_pages na "on" u $PGDATA/postgresql.conf i ponovo pokrenite server.

Još jednom, informacije o velikim stranicama (samo za 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

Sada možete vidjeti da se koristi vrlo malo velikih stranica. Pokušajmo sada dodati neke podatke u bazu podataka.

Neke operacije baze podataka za recikliranje velikih stranica

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

Hajde da vidimo da li sada koristimo više velikih stranica nego ranije.

Više informacija na velikim stranicama (samo za Linux)

$ 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

Sada možete vidjeti da se većina velikih stranica koristi.

Napomena: Procenjena vrednost za HugePages koja se ovde koristi je veoma niska, što nije normalna vrednost za mašinu koja radi u okruženju proizvoda. Procijenite potreban broj stranica za vaš sistem i postavite ih u skladu s tim na osnovu opterećenja i resursa.

vm.swappiness

vm.swappiness je još jedan parametar kernela koji može utjecati na performanse baze podataka. Ova opcija se koristi za kontrolu ponašanja zamjene (zamjena stranica u memoriji i izvan nje) na Linuxu. Vrijednost je u rasponu od 0 do 100. Određuje koliko će memorije biti dostavljeno ili prevučeno. Nula znači da nema razmjene, a 100 znači agresivnu razmjenu.

Možete postići dobre performanse postavljanjem nižih vrijednosti.

Postavljanje na 0 na novijim kernelima može uzrokovati da OOM Killer (Linuxov proces čišćenja memorije) ubije proces. Stoga je sigurno postaviti na 1 ako želite minimizirati zamjenu. Zadana vrijednost u Linuxu je 60. Veća vrijednost uzrokuje da MMU (jedinica za upravljanje memorijom) koristi više swap prostora od RAM-a, dok niža vrijednost zadržava više podataka/koda u memoriji.

Niža vrijednost je dobra opklada za poboljšane performanse u PostgreSQL-u.

vm.overcommit_memory / vm.overcommit_ratio

Aplikacije preuzimaju memoriju i oslobađaju je kada više nije potrebna. Ali u nekim slučajevima, aplikacija dobije previše memorije i ne oslobađa je. Ovo može uzrokovati OOM ubicu. Ovdje su moguće vrijednosti parametara vm.overcommit_memory sa opisom za svaki:

  1. Heurističko overcommit (podrazumevano); heuristika zasnovana na kernelu
  2. U svakom slučaju dozvolite prekomjerno preuzimanje
  3. Nemojte pretjerivati, nemojte prekoračiti omjer prekomjerne obveze.

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

vm.overcommit_ratio — postotak RAM-a koji je dostupan za preopterećenje. Vrijednost od 50% na sistemu sa 2 GB RAM-a može dodijeliti do 3 GB RAM-a.

Vrijednost 2 za vm.overcommit_memory pruža bolje performanse za PostgreSQL. Ova vrijednost maksimizira korištenje RAM-a serverskog procesa bez ikakvog značajnog rizika da bude ubijen od strane procesa ubijanja OOM-a. Aplikacija će se moći ponovo učitati, ali samo u granicama prekoračenja, što smanjuje rizik da OOM ubojica ubije proces. Stoga, vrijednost 2 daje bolje performanse od zadane vrijednosti 0. Međutim, pouzdanost se može poboljšati osiguravanjem da memorija izvan opsega nije preopterećena. Ovo eliminiše rizik da proces bude ubijen od strane OOM ubice.

Na sistemima bez zamjene može doći do problema sa vm.overcommit_memory jednakim 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 je postotak memorije ispunjene prljavim stranicama koje je potrebno upisati na disk. Ispiranje na disk se događa u pozadini. Vrijednost ovog parametra se kreće od 0 do 100; međutim, vrijednost ispod 5 može biti neefikasna i neka jezgra to ne podržavaju. 10 je zadana vrijednost na većini Linux sistema. Možete poboljšati performanse za operacije intenzivne pisanja za manji faktor, što će značiti da će Linux ispirati prljave stranice u pozadini.

Morate postaviti vrijednost vm.dirty_background_bytes ovisno o brzini vaše vožnje.

Ne postoje "dobre" vrijednosti za ova dva parametra jer oba ovise o hardveru. Međutim, postavljanje vm.dirty_background_ratio na 5 i vm.dirty_background_bytes na 25% brzine diska poboljšava performanse na ~25% u većini slučajeva.

vm.dirty_ratio/dirty_bytes

Ovo je isto kao vm.dirty_background_ratio/dirty_background_bytes, osim što se resetovanje vrši u radnoj sesiji, blokirajući aplikaciju. Stoga bi vm.dirty_ratio trebao biti veći od vm.dirty_background_ratio. Ovo osigurava da pozadinski procesi počnu ranije kako bi se izbjeglo blokiranje aplikacije koliko god je to moguće. Možete podesiti razliku između ova dva omjera ovisno o I/O opterećenju diska.

Rezultat

Možete podesiti druge postavke da biste poboljšali performanse, ali poboljšanja će biti minimalna i nećete vidjeti mnogo koristi. Moramo imati na umu da se sve opcije ne primjenjuju na sve vrste aplikacija. Neke aplikacije rade bolje kada prilagodimo neke postavke, a neke ne. Morate pronaći pravi balans između konfigurisanja ovih postavki za vaše očekivano radno opterećenje i tip aplikacije, a takođe morate uzeti u obzir ponašanje OS-a prilikom podešavanja. Konfiguriranje parametara kernela nije tako jednostavno kao konfiguriranje parametara baze podataka; teže je dati preporuke.

izvor: www.habr.com

Dodajte komentar