Настройване на параметрите на ядрото на Linux за оптимизация на PostgreSQL

Настройване на параметрите на ядрото на Linux за оптимизация на PostgreSQL Оптималната производителност на PostgreSQL зависи от правилно зададените параметри на операционната система. Лошо настроените параметри на ядрото на ОС могат да доведат до намаляване на производителността на сървъра на базата данни. Затова е задължително тези параметри да бъдат конфигурирани в съответствие с базата данни и неговото натоварване. В този пост ще обсъдим някои важни параметри на Linux ядрото, които могат да повлияят на производителността на сървъра и начините за тяхната настройка.

SHMMAX / SHMALL

SHMMAX — това е параметър на ядрото, използван за определяне на максималния размер на един сегмент споделена памет (shared memory), който процесът Linux може да задели. До версия 9.2 PostgreSQL използваше System V (SysV), за който е необходима настройка на SHMMAX. След 9.2 PostgreSQL премина на споделена памет POSIX. Така че сега е необходима по-малко байтове споделена памет System V.

До версия 9.3 SHMMAX беше най-важният параметър на ядрото. Стойността на SHMMAX се задава в байтове.

Подобно на това, SHMALL — това е още един параметър на ядрото, използван за определяне на
общия обем на страниците споделена памет (shared memory). За да видите текущите стойности на SHMMAX, SHMALL или SHMMIN, използвайте командата ipcs.

SHM* Подробности — Linux

$ ipcs -lm

------ Ограничения на споделената памет --------
максимален брой сегменти = 4096
макс. размер на сегмента (кбайта) = 1073741824
макс. обща споделена памет (кбайта) = 17179869184
мин. размер на сегмента (байта) = 1

SHM* Подробности — MacOS X

$ ipcs -M
Статус на IPC от  към Чет Авг 16 22:20:35 PKT 2018
shminfo:
	shmmax: 16777216	(макс. размер на сегмента споделена памет)
	shmmin:       1	(мин. размер на сегмента споделена памет)
	shmmni:      32	(макс. брой идентификатори на споделена памет)
	shmseg:       8	(макс. споделени сегменти на процес)
	shmall:    1024	(макс. количество споделена памет в страници)

PostgreSQL използва System V IPC за заделяне на споделена памет. Този параметър е един от най-важните параметри на ядрото. Всяки път, когато получавате следните съобщения за грешки, това означава, че имате по-стара версия на PostgreSQL и имате много ниска стойност на SHMMAX. Очаква се потребителите да коригират и увеличат стойността в съответствие със споделената памет, която планират да използват.

Възможни грешки при неправилна конфигурация

Ако SHMMAX е настроен неправилно, можете да получите грешка при опит да инициализирате кластера PostgreSQL с помощта на командата initdb.

initdb Неуспех
ДЕТАЙЛИ: Неуспешен системен повик беше shmget(key=1, size=2072576, 03600).

ПОДСКАЗКА: Тази грешка обикновено означава, че искането на PostgreSQL за сегмент споделена памет надвишава параметъра SHMMAX на вашето ядро. 
Можете да намалите размера на заявката или да пренастроите ядрото с по-голям SHMMAX. За да намалите размера на заявката (в момента 2072576 байта),
намалете споделената памет на PostgreSQL, например, като намалите shared_buffers или max_connections.

Ако размерът на заявката вече е малък, е възможно да е по-малък от параметъра SHMMIN на ядрото ви,
в такъв случай е необходимо да увеличите размера на заявката или да пренастроите SHMMIN.

Документацията на PostgreSQL съдържа повече информация за конфигурацията на споделената памет. Процесът дете излезе с код за изход 1.

По подобен начин можете да получите грешка при стартиране на PostgreSQL сървъра с командата pg_ctl.

pg_ctl Провал
ДЕТАЙЛ: Неуспешен системен повик е shmget(key=5432001, size=14385152, 03600).

ПОДСКАЗКА: Тази грешка обикновено означава, че искането на PostgreSQL за сегмент споделена памет надвишава параметъра SHMMAX на вашето ядро.

Можете да намалите размера на заявката или да пренастроите ядрото с по-голям SHMMAX.; За да намалите размера на заявката (в момента 14385152 байта), намалете споделената памет на PostgreSQL, например, като намалите shared_buffers или max_connections.

Ако размерът на заявката вече е малък, е възможно да е по-малък от параметъра SHMMIN на ядрото ви,
в такъв случай е необходимо да увеличите размера на заявката или да пренастроите SHMMIN.

Документацията на PostgreSQL съдържа повече информация за конфигурацията на споделената памет.

Разбиране на разликите в определенията

Определенията на параметрите SHMMAX/SHMALL малко се различават в Linux и MacOS X:

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

Екип sysctl може да се използва за временно изменение на стойността. За да зададете постоянни стойности, добавете запис в /etc/sysctl.conf. Подробности са посочени по-долу.

Промяна на параметрите на ядрото в 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

Промяна на параметрите на ядрото в 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

Не забравяйте: за да направите измененията постоянни, добавете тези стойности в /etc/sysctl.conf

Големи страници (Huge Pages)

По подразбиране в Linux се използват 4 КБ паметни страници, в BSD — Super Pages, а в Windows — Large Pages. Страницата е част от оперативната памет, разпределена на процеса. Процесът може да разполага с няколко страници в зависимост от потребностите си от памет. Колкото повече памет изисква процесът, толкова повече страници му се разпределят. ОС поддържа таблица за разпределение на страниците за процесите. Колкото по-малък е размерът на страницата, толкова по-голяма е таблицата, толкова повече време е необходимо за намиране на страница в тази таблица с страници. Затова, големите страници позволяват използването на голямо количество памет с намалени разходи; по-малко преглеждания на страници, по-малко странични грешки, по-бързи операции по четене/писане чрез големи буфери. В резултат на това — подобряване на производителността.

PostgreSQL поддържа големи страници само в Linux. По подразбиране Linux използва 4 KB страници памет, така че в случаи, когато операциите с памет са прекалено много, е необходимо да се зададат страници с по-голям размер. Наблюдава се увеличение на производителността при използване на големи страници с размер 2 MB и до 1 GB. Размерът на голямата страница може да бъде зададен по време на зареждане. Можете лесно да проверите параметрите на голямата страница и тяхната употреба на вашия Linux компютър, като използвате командата cat /proc/meminfo | grep -i huge.

Получаване на информация за големите страници (само на 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

В този пример, въпреки че размерът на голямата страница е зададен на 2048 (2 MB), общият брой на големите страници е 0. Това означава, че големите страници са изключени.

Скрипт за определяне на броя на големите страници

Това е прост скрипт, който връща необходимия брой големи страници. Изпълнете скрипта на вашия Linux сървър, докато работи PostgreSQL. Уверете се, че за променливата на средата $PGDATA е зададена директорията на данни PostgreSQL.

Получаване на цифрата на изискваните големи страници

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

Изходът на скрипта изглежда по следния начин:

Изход на скрипта

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

Препоръчителната стойност на големите страници е 88, така че трябва да зададете стойността 88.

Настройка на големите страници

sysctl -w vm.nr_hugepages=88

Проверете големите страници сега, ще видите, че големите страници не се използват (HugePages_Free = HugePages_Total).

Отново информация за големите страници (само на 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

Сега задайте параметъра huge_pages на "on" в $PGDATA/postgresql.conf и рестартирайте сървъра.

И отново информация за големите страници (само на 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

Сега можете да видите, че се използват много малко големи страници. Нека сега опитаме да добавим някои данни в базата данни.

Някои операции с базата данни за управлението на големи страници

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

Нека да видим дали в момента използваме повече големи страници, отколкото преди.

Още веднъж информация за големите страници (само за 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

Сега можете да видите, че повечето от големите страници се използват.

Забележка: примерната стойност за HugePages, използвана тук, е много ниска, което не е нормална стойност за машина в продуктовата среда. Моля, оценете необходимия брой страници за вашата система и ги настройте съответно в зависимост от натоварването и ресурсите.

vm.swappiness

vm.swappiness — това е още един параметър на ядрото, който може да влияе на производителността на базата данни. Този параметър се използва за управление на поведението на подмяната (swappiness) (подмяна на страниците в паметта и извън нея) в Linux. Стойността варира от 0 до 100. Тя определя колко памет ще бъде освобождавана или заменяна. Нулата означава деактивиране на подмяната, а 100 означава агресивна подмяна.

Можете да постигнете добра производителност, като зададете по-ниски стойности.

Задаването на стойност 0 в по-нови ядра може да доведе до това OOM Killer (процес за почистване на паметта в Linux) да убие процеса. Следователно, можете безопасно да зададете стойност 1, ако искате да минимизирате подмяната. Стандартната стойност в Linux е 60. По-високата стойност кара MMU (блок за управление на паметта) да използва повече пространство за подмяна отколкото RAM, докато по-ниската стойност запазва повече данни/код в паметта.

По-ниска стойност е добра ставка за подобряване на производителността в PostgreSQL.

vm.overcommit_memory / vm.overcommit_ratio

Приложенията получават памет и я освобождават, когато вече не е нужна. Но в някои случаи приложението получава твърде много памет и не я освобождава. Това може да предизвика OOM killer. Ето възможните стойности на параметъра vm.overcommit_memory с описание за всяка:

  1. Евристично overcommit (по подразбиране); базирана на ядрото евристика
  2. Разрешаване на overcommit при всякакви обстоятелства
  3. Не прекалявайте, не надвишавайте коефициента на overcommit.

Ссылка: https://www.kernel.org/doc/Documentation/vm/overcommit-accounting

vm.overcommit_ratio — процент на оперативната памет, достъпна за прекомерно използване. Стойността 50% в система с 2 ГБ RAM може да предостави до 3 ГБ RAM.

Стойност 2 за vm.overcommit_memory осигурява по-добра производителност за PostgreSQL. Тази стойност максимизира използването на оперативната памет от сървърния процес без съществуващ риск от убиване на процеса от OOM killer. Приложението ще може да се рестартира, но само в рамките на прекомерното използване, което намалява риска да бъде убит от OOM killer. Следователно, стойност 2 предоставя по-добра производителност от стойността по подразбиране 0. Въпреки това, надеждността може да бъде подобрена, тъй като паметта извън допустимия обхват няма да бъде често използвана. Това изключва риска от убиване на процеса от OOM-killer.

В системи без разменна памет може да възникне проблем с vm.overcommit_memory, зададено на 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 — това е процентът на паметта, запълнена с мръсни страници, които трябва да бъдат записани на диск. Записът на диск се извършва във фонов режим. Стойността на този параметър варира от 0 до 100; обаче стойност под 5 може да бъде неефективна и някои ядра не поддържат това. 10 е стойността по подразбиране в повечето Linux системи. Можете да увеличите производителността на операции с интензивно записване с по-нисък коефициент, което ще означава, че Linux ще записва мръсни страници във фонов режим.

Трябва да зададете стойността vm.dirty_background_bytes в зависимост от скоростта на вашия диск.

За тези две параметри няма "добри" стойности, тъй като и двете зависят от хардуера. Въпреки това, задаването на vm.dirty_background_ratio на стойност 5 и vm.dirty_background_bytes на 25% от скоростта на диска увеличава производителността до ~ 25% в повечето случаи.

vm.dirty_ratio / dirty_bytes

Това е същото като vm.dirty_background_ratio / dirty_background_bytes, с изключение на това, че записът се извършва в работна сесия, блокирайки приложението. Затова vm.dirty_ratio трябва да е по-високо от vm.dirty_background_ratio. Това гарантира, че фонова обработка ще стартира по-рано, за да се избегне максимално възможното блокиране на приложението. Можете да настроите разликата между тези две съотношения в зависимост от натоварването на дисковия вход-изход.

Резюме

Можете да настроите и други параметри за повишаване на производителността, но подобренията ще бъдат минимални и няма да получите особени ползи. Трябва да помним, че не всички параметри важат за всички типове приложения. Някои приложения работят по-добре, когато настройваме определени параметри, а други - не. Трябва да намерите правилния баланс между конфигурациите на тези параметри за очакваното натоварване и типа приложение, а също така е необходимо да се вземе предвид поведението на ОС. Настройването на ядрени параметри не е толкова просто, колкото настройването на базови параметри: трудно е да се дават препоръки тук.

Източник: habr.com

Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри 🔥 Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри | ProHoster