Configurazione dei parametri del kernel Linux per ottimizzare PostgreSQL

Configurazione dei parametri del kernel Linux per ottimizzare PostgreSQL Le prestazioni ottimali di PostgreSQL dipendono da parametri del sistema operativo correttamente definiti. Parametri mal configurati del kernel OS possono portare a una riduzione delle prestazioni del server del database. È quindi fondamentale che questi parametri siano impostati in base al server del database e al suo carico di lavoro. In questo post discuteremo alcuni importanti parametri del kernel Linux che possono influenzare le prestazioni del server del database e come configurarli.

SHMMAX / SHMALL

SHMMAX è un parametro del kernel utilizzato per definire la dimensione massima di un singolo segmento di memoria condivisa che un processo Linux può allocare. Fino alla versione 9.2, PostgreSQL utilizzava System V (SysV), per il quale è necessaria la configurazione di SHMMAX. Dopo la 9.2, PostgreSQL è passato alla memoria condivisa POSIX. Pertanto, ora è richiesta meno memoria condivisa System V in byte.

Fino alla versione 9.3, SHMMAX era il parametro del kernel più importante. Il valore di SHMMAX è espresso in byte.

Analogamente, SHMALL è un altro parametro del kernel utilizzato per definire
volume complessivo di pagine della memoria condivisa (shared memory). Per visualizzare i valori correnti di SHMMAX, SHMALL o SHMMIN, utilizza il comando ipcs.

Dettagli SHM* — Linux

$ ipcs -lm

------ Limiti della memoria condivisa --------
numero massimo di segmenti = 4096
dimensione massima segmento (kbytes) = 1073741824
totale massimo della memoria condivisa (kbytes) = 17179869184
dimensione minima segmento (bytes) = 1

Dettagli SHM* — MacOS X

$ ipcs -M
Stato IPC da  il Thu Aug 16 22:20:35 PKT 2018
shminfo:
	shmmax: 16777216	(dimensione massima del segmento di memoria condivisa)
	shmmin:       1	(dimensione minima del segmento di memoria condivisa)
	shmmni:      32	(numero massimo di identificatori di memoria condivisa)
	shmseg:       8	(numero massimo di segmenti di memoria condivisa per processo)
	shmall:    1024	(massima quantità di memoria condivisa in pagine)

PostgreSQL utilizza System V IPC per allocare memoria condivisa. Questo parametro è uno dei più importanti parametri del kernel. Ogni volta che ricevi i seguenti messaggi di errore, significa che hai una versione più vecchia di PostgreSQL e un valore SHMMAX molto basso. Si prevede che gli utenti correggano e aumentino il valore in base alla memoria condivisa che intendono utilizzare.

Possibili errori di configurazione errata

Se SHMMAX è configurato in modo errato, puoi ricevere un errore durante il tentativo di inizializzare il cluster PostgreSQL utilizzando il comando initdb.

Errore initdb
DETTAGLI: La chiamata di sistema non riuscita è stata shmget(key=1, size=2072576, 03600).

SUGGERIMENTO: Questo errore di solito significa che la richiesta di PostgreSQL per un segmento di memoria condivisa ha superato il parametro SHMMAX del kernel. 
Puoi ridurre la dimensione della richiesta o riconfigurare il kernel con un SHMMAX più grande. Per ridurre la dimensione della richiesta (attualmente 2072576 byte),
riduci l'uso della memoria condivisa di PostgreSQL, magari diminuendo shared_buffers o max_connections.

Se la dimensione della richiesta è già piccola, è possibile che sia inferiore al parametro SHMMIN del tuo kernel,
nel qual caso è necessario aumentare la dimensione della richiesta o riconfigurare lo SHMMIN.

La documentazione di PostgreSQL contiene ulteriori informazioni sulla configurazione della memoria condivisa. Il processo figlio è terminato con codice di uscita 1

Allo stesso modo, puoi ricevere un errore durante l'avvio del server PostgreSQL utilizzando il comando pg_ctl.

Errore pg_ctl
DETTAGLIO: La chiamata di sistema fallita era shmget(key=5432001, size=14385152, 03600).

SUGGERIMENTO: Questo errore di solito significa che la richiesta di PostgreSQL per un segmento di memoria condivisa ha superato il parametro SHMMAX del kernel.

Puoi ridurre la dimensione della richiesta o riconfigurare il kernel con un SHMMAX più grande.; Per ridurre la dimensione della richiesta (attualmente 14385152 byte), riduci l'uso della memoria condivisa di PostgreSQL, magari diminuendo shared_buffers o max_connections.

Se la dimensione della richiesta è già piccola, è possibile che sia inferiore al parametro SHMMIN del tuo kernel,
nel qual caso è necessario aumentare la dimensione della richiesta o riconfigurare lo SHMMIN.

La documentazione di PostgreSQL contiene ulteriori informazioni sulla configurazione della memoria condivisa.

Comprendere le differenze nelle definizioni

La definizione dei parametri SHMMAX/SHMALL è leggermente diversa in Linux e MacOS X:

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

Team sysctl può essere utilizzato per modificare temporaneamente il valore. Per impostare valori permanenti, aggiungi una voce in /etc/sysctl.conf. I dettagli sono riportati di seguito.

Modifica dei parametri del kernel su 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

Modifica dei parametri del kernel su 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

Non dimenticare: per rendere le modifiche permanenti, aggiungi questi valori in /etc/sysctl.conf

Pagine grandi (Huge Pages)

In Linux, di default vengono utilizzate pagine di memoria da 4 KB, in BSD — Super Pagine, e in Windows — Pagine grandi (Large Pages). Una pagina è una porzione di memoria RAM assegnata a un processo. Un processo può avere più pagine a seconda delle esigenze di memoria. Maggiore è la memoria richiesta da un processo, più pagine gli vengono allocate. Il sistema operativo supporta una tabella di allocazione delle pagine per i processi. Più piccolo è il dimensionamento della pagina, più grande sarà la tabella, e più tempo ci vorrà per cercare una pagina in questa tabella. Pertanto, le pagine grandi consentono di gestire grandi quantità di memoria con costi di overhead ridotti; meno visualizzazioni di pagine, meno errori di pagina, operazioni di lettura/scrittura più veloci attraverso grandi buffer. Come risultato, si ha un miglioramento delle prestazioni.

PostgreSQL supporta le grandi pagine solo su Linux. Per impostazione predefinita, Linux utilizza pagine di memoria da 4 KB, quindi in caso di un numero eccessivo di operazioni di memoria, è necessario impostare pagine di dimensioni maggiori. Si osserva un aumento delle prestazioni utilizzando grandi pagine di 2 MB e fino a 1 GB. La dimensione della grande pagina può essere impostata durante il caricamento. Puoi controllare facilmente i parametri delle grandi pagine e il loro utilizzo sul tuo computer Linux utilizzando il comando cat /proc/meminfo | grep -i huge.

Recupero delle informazioni sulle grandi pagine (solo su Linux)

Nota: Questo è valido solo per Linux, per altri sistemi operativi questa operazione è ignorata$ 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

In questo esempio, anche se la dimensione della grande pagina è impostata a 2048 (2 MB), il numero totale di grandi pagine è 0. Ciò significa che le grandi pagine sono disabilitate.

Script per determinare il numero di grandi pagine

Questo semplice script restituisce il numero necessario di grandi pagine. Esegui lo script sul tuo server Linux mentre PostgreSQL è in funzione. Assicurati che la variabile d'ambiente $PGDATA indichi la directory dei dati di PostgreSQL.

Ottenere il numero richiesto di grandi pagine

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

L'output dello script appare come segue:

Output dello script

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

Il valore raccomandato per le grandi pagine è 88, quindi è necessario impostare il valore a 88.

Impostazione delle grandi pagine

sysctl -w vm.nr_hugepages=88

Controlla le grandi pagine ora, vedrai che le grandi pagine non sono in uso (HugePages_Free = HugePages_Total).

Ulteriori informazioni sulle grandi pagine (solo su 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

Ora imposta il parametro huge_pages su «on» in $PGDATA/postgresql.conf e riavvia il server.

E ancora informazioni sulle grandi pagine (solo su 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

Ora puoi vedere che si stanno utilizzando pochissime pagine di grandi dimensioni. Proviamo ora ad aggiungere alcuni dati al database.

Alcune operazioni sul database per gestire le grandi pagine

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

Vediamo se ora stiamo utilizzando più grandi pagine rispetto a prima.

Ancora alcune informazioni sulle grandi pagine (solo su 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

Ora puoi vedere che la maggior parte delle grandi pagine è in uso.

Nota: il valore degli HugePages utilizzato qui è molto basso, il che non è tipico per una macchina in produzione. Ti preghiamo di valutare il numero necessario di pagine per il tuo sistema e di impostarle di conseguenza in base al carico e alle risorse.

vm.swappiness

vm.swappiness — è un altro parametro del kernel che può influenzare le prestazioni del database. Questo parametro è usato per gestire il comportamento dello swapping (swappiness) (movimento delle pagine in memoria e fuori) in Linux. Il valore varia da 0 a 100. Determina quanta memoria sarà scaricata o liberata. Zero significa disattivare lo swap, mentre 100 significa uno swap aggressivo.

Puoi ottenere buone prestazioni impostando valori più bassi.

Impostare un valore di 0 nei kernel più recenti può portare a un'azione dell'OOM Killer (il processo di pulizia della memoria in Linux) che terminerà il processo. Pertanto, è sicuro impostare un valore di 1 se si desidera ridurre al minimo lo swapping. Il valore predefinito in Linux è 60. Un valore più alto costringe l'MMU (Unità di Gestione della Memoria) a utilizzare più spazio di swapping rispetto alla RAM, mentre un valore più basso mantiene più dati/codice in memoria.

Un valore più basso è una buona scommessa per migliorare le prestazioni in PostgreSQL.

vm.overcommit_memory / vm.overcommit_ratio

Le applicazioni acquisiscono memoria e la liberano quando non è più necessaria. Tuttavia, in alcuni casi, un'applicazione può ricevere troppa memoria e non rilasciarla. Questo può attivare l'OOM killer. Ecco i possibili valori per il parametro vm.overcommit_memory con una descrizione per ciascuno:

  1. Overcommit euristico (predefinito); euristica basata sul kernel
  2. Consenti overcommit in ogni caso
  3. Non esagerare, non superare il coefficiente di overcommit.

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

vm.overcommit_ratio — percentuale della memoria RAM disponibile per l'overcommit. Un valore del 50% in un sistema con 2 GB di RAM può allocare fino a 3 GB di RAM.

Il valore 2 per vm.overcommit_memory garantisce migliori performance per PostgreSQL. Questo valore massimizza l'uso della memoria RAM da parte del processo server senza un rischio significativo di essere terminato dal processo OOM killer. L'applicazione potrà riavviarsi, ma solo entro i limiti del sovrautilizzo, riducendo così il rischio che l'OOM killer termini il processo. Pertanto, il valore 2 offre prestazioni superiori rispetto al valore predefinito 0. Tuttavia, l'affidabilità può essere migliorata evitando di sovraccaricare la memoria oltre il limite consentito. Questo esclude il rischio che il processo venga terminato dall'OOM killer.

Nei sistemi senza swap potrebbe sorgere un problema con vm.overcommit_memory impostato a 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 — è la percentuale di memoria occupata da pagine sporche che devono essere scritte su disco. Il flush su disco avviene in background. Questo valore varia da 0 a 100; tuttavia, un valore inferiore a 5 può risultare inefficace e alcuni kernel potrebbero non supportarlo. 10 è il valore predefinito nella maggior parte dei sistemi Linux. È possibile migliorare le prestazioni per operazioni di scrittura intensiva con un rapporto inferiore, il che significa che Linux scriverà le pagine sporche in background.

È necessario impostare il valore vm.dirty_background_bytes in base alla velocità del proprio disco.

Non esistono valori "buoni" per questi due parametri, poiché entrambi dipendono dall'hardware. Tuttavia, impostare vm.dirty_background_ratio a 5 e vm.dirty_background_bytes al 25% della velocità del disco, aumenta le prestazioni fino a ~ 25% nella maggior parte dei casi.

vm.dirty_ratio / dirty_bytes

È lo stesso di vm.dirty_background_ratio / dirty_background_bytes, tranne per il fatto che il flush avviene durante la sessione di lavoro, bloccando l'applicazione. Pertanto, vm.dirty_ratio deve essere superiore a vm.dirty_background_ratio. Questo garantisce che i processi in background vengano avviati prima, per evitare il massimo possibile di blocco dell'applicazione. Puoi regolare la differenza tra questi due rapporti a seconda del carico dell'input/output del disco.

Risultato

Puoi regolare altri parametri per aumentare le prestazioni, ma i miglioramenti saranno minimi e non ne trarrai un grande vantaggio. Dobbiamo ricordare che non tutti i parametri si applicano a tutti i tipi di applicazioni. Alcune applicazioni funzionano meglio quando configuriamo alcuni parametri, mentre altre no. Devi trovare il giusto equilibrio tra le configurazioni di questi parametri per il carico di lavoro previsto e il tipo di applicazione, tenendo presente anche il comportamento del sistema operativo. Configurare i parametri del kernel non è così semplice come configurare quelli del database: è più complesso fornire le tue raccomandazioni.

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster