Pag-tune ng Linux Kernel Options para I-optimize ang PostgreSQL

Pag-tune ng Linux Kernel Options para I-optimize ang PostgreSQL Ang pinakamainam na pagganap ng PostgreSQL ay nakasalalay sa wastong tinukoy na mga setting ng operating system. Maaaring humantong sa mabagal na pagganap ng server ng database ang hindi magandang na-configure na mga parameter ng kernel ng OS. Samakatuwid, kinakailangang i-configure ang mga setting na ito ayon sa database server at workload nito. Sa post na ito, tatalakayin natin ang ilan sa mahahalagang parameter ng Linux kernel na maaaring makaapekto sa pagganap ng database server at kung paano ibagay ang mga ito.

SHMMAX / SHMALL

SHMMAX ay isang kernel parameter na ginagamit upang matukoy ang maximum na laki ng isang nakabahaging memory segment na maaaring ilaan ng isang proseso ng Linux. Bago ang bersyon 9.2, ginamit ng PostgreSQL ang System V (SysV), na nangangailangan ng setting ng SHMMAX. Pagkatapos ng 9.2 PostgreSQL lumipat sa POSIX shared memory. Kaya ngayon mas kaunting mga byte ng System V shared memory ang kinakailangan.

Bago ang bersyon 9.3, ang SHMMAX ang pinakamahalagang parameter ng kernel. Ang halaga ng SHMMAX ay ibinibigay sa mga byte.

Katulad din SHMALL ay isa pang parameter ng kernel na ginagamit upang matukoy
kabuuang laki ng system ng mga nakabahaging pahina ng memorya. Upang tingnan ang kasalukuyang mga halaga ng SHMMAX, SHMALL, o SHMMIN, gamitin ang command ipcs.

Mga Detalye ng SHM* - 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

Mga Detalye ng SHM* - 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)

Gumagamit ang PostgreSQL System V IPC upang maglaan ng nakabahaging memorya. Ang setting na ito ay isa sa pinakamahalagang opsyon sa kernel. Sa tuwing makukuha mo ang mga sumusunod na mensahe ng error, nangangahulugan ito na mayroon kang mas lumang bersyon ng PostgreSQL at may napakababang halaga ng SHMMAX. Inaasahan ang mga gumagamit na ayusin at taasan ang halaga ayon sa nakabahaging memorya na nilalayon nilang gamitin.

Mga Posibleng Maling Pag-configure

Kung ang SHMMAX ay hindi na-configure nang tama, maaari kang makakuha ng isang error kapag sinusubukan mong simulan ang isang PostgreSQL cluster gamit ang command initdb.

initdb Pagkabigo
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

Katulad nito, maaari kang magkaroon ng error kapag sinimulan ang PostgreSQL server gamit ang command pg_ctl.

pg_ctl Nabigo
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.

Pag-unawa sa Mga Pagkakaiba sa Mga Kahulugan

Ang kahulugan ng mga opsyon sa SHMMAX/SHMALL ay bahagyang naiiba sa Linux at MacOS X:

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

Koponan sysctl maaaring gamitin upang pansamantalang baguhin ang halaga. Upang magtakda ng mga pare-parehong halaga, magdagdag ng entry sa /etc/sysctl.conf. Nasa ibaba ang mga detalye.

Pagbabago ng Mga Opsyon sa Kernel sa 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

Pagbabago ng Mga Opsyon sa Kernel sa Linux

# 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

Huwag kalimutan: upang gawing permanente ang mga pagbabago idagdag ang mga halagang ito sa /etc/sysctl.conf

Napakalaking Pahina

Ang Linux ay nagde-default sa 4 KB na mga pahina, ang BSD ay nagde-default sa Mga Super Pahina, at sa Windows Malaking Pahina. Ang pahina ay isang bahagi ng RAM na inilalaan sa isang proseso. Ang isang proseso ay maaaring magkaroon ng maraming pahina depende sa mga kinakailangan sa memorya. Kung mas maraming memorya ang kailangan ng isang proseso, mas maraming mga pahina ang inilalaan dito. Ang OS ay nagpapanatili ng talahanayan ng paglalaan ng pahina para sa mga proseso. Kung mas maliit ang laki ng pahina, mas malaki ang talahanayan, mas tumatagal upang maghanap ng pahina sa talahanayan ng pahinang iyon. Samakatuwid, ang malalaking pahina ay nagbibigay-daan sa isang malaking halaga ng memorya na magamit sa pinababang overhead; mas kaunting page view, mas kaunting page fault, mas mabilis na read/write operations sa pamamagitan ng mas malalaking buffer. Ang resulta ay pinabuting pagganap.

Sinusuportahan lamang ng PostgreSQL ang malalaking pahina sa Linux. Bilang default, ang Linux ay gumagamit ng 4 KB ng mga pahina ng memorya, kaya sa mga kaso kung saan mayroong masyadong maraming mga pagpapatakbo ng memorya, kinakailangang mag-install ng mas malalaking pahina. Mayroong pagtaas sa performance kapag gumagamit ng malalaking page na 2 MB at hanggang 1 GB. Maaaring itakda ang malaking laki ng page sa oras ng pag-load. Madali mong masusuri ang mga pagpipilian sa malalaking pahina at ang kanilang paggamit sa iyong Linux machine gamit ang command pusa /proc/meminfo | grep -i malaki.

Pagkuha ng impormasyon tungkol sa malalaking page (Linux lang)

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

Sa halimbawang ito, bagama't ang malaking laki ng pahina ay nakatakda sa 2048 (2 MB), ang kabuuang bilang ng malalaking pahina ay 0. Nangangahulugan ito na ang malalaking pahina ay hindi pinagana.

Script para sa pagtukoy ng bilang ng malalaking pahina

Ibinabalik ng simpleng script na ito ang kinakailangang bilang ng malalaking pahina. Patakbuhin ang script sa iyong Linux server habang tumatakbo ang PostgreSQL. Tiyaking nakatakda ang environment variable $PGDATA ang direktoryo ng data ng PostgreSQL ay tinukoy.

Pagkuha ng Bilang ng Malaking Pahina na Kinakailangan

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

Ang output ng script ay ganito:

Output ng Script

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

Ang inirerekomendang halaga para sa malalaking pahina ay 88, kaya dapat mong itakda ito sa 88.

Pag-install ng malalaking pahina

sysctl -w vm.nr_hugepages=88

Suriin ang malalaking pahina ngayon, makikita mo na walang malalaking pahina ang ginagamit (HugePages_Free = HugePages_Total).

Muling impormasyon ng malaking page (Linux lang)

$ 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

Ngayon itakda ang huge_pages na opsyon sa "on" sa $PGDATA/postgresql.conf at i-restart ang server.

Muling Impormasyon sa Malaking Pahina (sa Linux lang)

$ 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

Ngayon ay makikita mo na napakakaunting malalaking pahina ang ginagamit. Subukan nating magdagdag ng ilang data sa database.

Ang ilang mga pagpapatakbo ng database upang i-recycle ang malalaking pahina

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

Tingnan natin kung gumagamit tayo ng mas malalaking page ngayon kaysa dati.

Higit pang impormasyon tungkol sa malalaking pahina (Linux lang)

$ 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

Ngayon ay makikita mo na ang karamihan sa malalaking pahina ay ginagamit.

Tandaan: Ang halimbawang halaga para sa HugePages na ginamit dito ay napakababa, na hindi normal para sa isang production machine. Mangyaring tantyahin ang kinakailangang bilang ng mga pahina para sa iyong system at itakda ang mga ito nang naaayon depende sa pag-load at mga mapagkukunan.

vm.swappiness

vm.swappiness ay isa pang kernel setting na maaaring makaapekto sa pagganap ng database. Ang setting na ito ay ginagamit upang kontrolin ang swappiness na gawi (paging page sa loob at labas ng memorya) sa Linux. Ang halaga ay mula 0 hanggang 100. Tinutukoy nito kung gaano karaming memory ang ida-page o ia-unload. Ang ibig sabihin ng zero ay walang pagbabahagi, at ang ibig sabihin ng 100 ay agresibong pagbabahagi.

Maaari kang makakuha ng mahusay na pagganap sa pamamagitan ng pagtatakda ng mas mababang mga halaga.

Ang pagtatakda nito sa 0 sa mga mas bagong kernel ay maaaring maging sanhi ng OOM Killer (proseso ng paglilinis ng memorya ng Linux) upang patayin ang proseso. Kaya ligtas na itakda ang halaga sa 1 kung gusto mong bawasan ang paging. Ang default na halaga sa Linux ay 60. Ang mas mataas na halaga ay nagiging sanhi ng MMU (Memory Management Unit) na gumamit ng mas maraming swap space kaysa sa RAM, habang ang mas mababang halaga ay nagpapanatili ng mas maraming data/code sa memorya.

Ang isang mas mababang halaga ay isang magandang taya para sa mga pagpapabuti ng pagganap sa PostgreSQL.

vm.overcommit_memory / vm.overcommit_ratio

Ang mga application ay nakakakuha ng memorya at inilalabas ito kapag hindi na ito kailangan. Ngunit sa ilang mga kaso, ang application ay nakakakuha ng masyadong maraming memorya at hindi ito pinakawalan. Ito ay maaaring mag-trigger ng isang OOM killer. Narito ang mga posibleng halaga ng parameter vm.overcommit_memory na may paglalarawan para sa bawat:

  1. Heuristic overcommit (default); heuristic na nakabatay sa kernel
  2. Payagan pa rin ang overcommit
  3. Huwag lumampas, huwag lumampas sa overcommit ratio.

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

vm.overcommit_ratio - porsyento ng RAM na magagamit para sa overloading. Ang halagang 50% sa isang system na may 2 GB ng RAM ay maaaring maglaan ng hanggang 3 GB ng RAM.

Ang pagtatakda ng vm.overcommit_memory sa 2 ay nagbibigay ng pinakamahusay na pagganap para sa PostgreSQL. Pina-maximize ng value na ito ang paggamit ng RAM ng proseso ng server nang walang anumang malaking panganib na mapatay ng proseso ng OOM killer. Magagawang mag-reboot ang application, ngunit sa loob lamang ng limitasyon sa pag-overrun, na binabawasan ang panganib na papatayin ng OOM killer ang proseso. Samakatuwid, ang isang halaga ng 2 ay nagbibigay ng mas mahusay na pagganap kaysa sa default na halaga ng 0. Gayunpaman, ang pagiging maaasahan ay maaaring mapabuti sa pamamagitan ng pagtiyak na ang memorya sa labas ng pinapayagang hanay ay hindi ma-overload. Inaalis nito ang panganib ng proseso na mapatay ng OOM-killer.

Sa mga non-paging system, maaaring may problema sa vm.overcommit_memory na nakatakda sa 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 ay ang porsyento ng memorya na puno ng mga maruruming pahina na kailangang isulat sa disk. Ang pag-flush sa disk ay ginagawa sa background. Ang halaga ng parameter na ito ay mula 0 hanggang 100; gayunpaman, ang isang halaga sa ibaba 5 ay maaaring hindi epektibo at ang ilang mga kernel ay hindi sumusuporta dito. 10 ay ang default na halaga sa karamihan ng mga sistema ng Linux. Maaari mong pagbutihin ang pagganap para sa masinsinang pagsulat na mga operasyon sa pamamagitan ng isang mas maliit na kadahilanan, na nangangahulugan na ang Linux ay mag-flush ng maruruming mga pahina sa background.

Kailangan mong itakda ang halaga vm.dirty_background_bytes depende sa bilis ng iyong disk.

Walang mga "magandang" halaga para sa dalawang parameter na ito, dahil pareho silang nakadepende sa hardware. Gayunpaman, ang pagtatakda ng vm.dirty_background_ratio sa 5 at vm.dirty_background_bytes sa 25% ng bilis ng disk ay nagpapabuti sa pagganap ng hanggang ~25% sa karamihan ng mga kaso.

vm.dirty_ratio/dirty_bytes

Ito ay katulad ng vm.dirty_background_ratio/dirty_background_bytes, maliban na ang pag-reset ay ginagawa sa isang sesyon ng trabaho, na bina-block ang application. Samakatuwid ang vm.dirty_ratio ay dapat na mas mataas kaysa vm.dirty_background_ratio. Tinitiyak nito na ang mga proseso sa background ay magsisimula nang mas maaga upang maiwasan ang pagharang sa application hangga't maaari. Maaari mong ayusin ang pagkakaiba sa pagitan ng dalawang ratios na ito batay sa disk I/O load.

Kabuuan

Maaari kang mag-tweak ng iba pang mga setting upang mapabuti ang pagganap, ngunit ang mga pagpapabuti ay magiging minimal at hindi ka makakakuha ng maraming benepisyo. Dapat nating tandaan na hindi lahat ng opsyon ay nalalapat sa lahat ng uri ng application. Mas gumagana ang ilang app kapag nag-tweak kami ng ilang setting at ang ilan ay hindi. Dapat mong mahanap ang tamang balanse sa pagitan ng mga pagsasaayos ng mga setting na ito para sa inaasahang workload at uri ng application, at ang pag-uugali ng OS ay dapat isaalang-alang kapag nagko-configure. Ang pag-tune ng mga parameter ng kernel ay hindi kasingdali ng pag-configure ng mga parameter ng database: mas mahirap gumawa ng mga rekomendasyon dito.

Pinagmulan: www.habr.com

Magdagdag ng komento