Configuración de parámetros del núcleo de Linux para optimizar PostgreSQL

Configuración de parámetros del núcleo de Linux para optimizar PostgreSQL El rendimiento óptimo de PostgreSQL depende de la correcta configuración de los parámetros del sistema operativo. Parámetros de kernel mal configurados pueden llevar a una disminución en el rendimiento del servidor de bases de datos. Por lo tanto, es crucial que estos parámetros estén ajustados de acuerdo con el servidor de bases de datos y su carga de trabajo. En este artículo, discutiremos algunos parámetros importantes del kernel de Linux que pueden afectar el rendimiento del servidor de bases de datos y cómo configurarlos.

SHMMAX / SHMALL

SHMMAX es un parámetro del kernel utilizado para determinar el tamaño máximo de un segmento de memoria compartida que puede asignar un proceso de Linux. Hasta la versión 9.2, PostgreSQL utilizaba System V (SysV), para el cual se requería la configuración de SHMMAX. Después de la 9.2, PostgreSQL cambió a la memoria compartida POSIX. Por lo tanto, ahora se requiere menos memoria compartida de System V.

Hasta la versión 9.3, SHMMAX era el parámetro más importante del kernel. El valor de SHMMAX se establece en bytes.

De manera similar, SHMALL es otro parámetro del kernel utilizado para definir
el volumen total de páginas de memoria compartida. Para ver los valores actuales de SHMMAX, SHMALL o SHMMIN, utiliza el comando ipcs.

Detalles de SHM* — Linux

$ ipcs -lm

------ Límites de Memoria Compartida --------
Número máximo de segmentos = 4096
Tamaño máximo de segmento (kbytes) = 1073741824
Máxima memoria compartida total (kbytes) = 17179869184
Tamaño mínimo de segmento (bytes) = 1

Detalles de SHM* — MacOS X

$ ipcs -M
Estado IPC desde  a partir del jue. 16 de ago. 22:20:35 PKT 2018
shminfo:
	shmmax: 16777216	(tamaño máximo de segmento de memoria compartida)
	shmmin:       1	(tamaño mínimo de segmento de memoria compartida)
	shmmni:      32	(número máximo de identificadores de memoria compartida)
	shmseg:       8	(número máximo de segmentos de memoria compartida por proceso)
	shmall:    1024	(cantidad máxima de memoria compartida en páginas)

PostgreSQL utiliza System V IPC para la asignación de memoria compartida. Este parámetro es uno de los más importantes del kernel. Siempre que recibas los siguientes mensajes de error, significa que tienes una versión más antigua de PostgreSQL y un valor de SHMMAX muy bajo. Se espera que los usuarios ajusten y aumenten el valor de acuerdo con la memoria compartida que planean utilizar.

Posibles errores de configuración incorrecta

Si SHMMAX está configurado incorrectamente, puedes recibir un error al intentar inicializar un clúster de PostgreSQL usando el comando initdb.

Error de initdb
DETALLE: La llamada al sistema fallida fue shmget(key=1, size=2072576, 03600).

SUGERENCIA: Este error generalmente significa que la solicitud de PostgreSQL para un segmento de memoria compartida excedió el parámetro SHMMAX de tu kernel. 
Puede reducir el tamaño de la solicitud o reconfigurar el kernel con un SHMMAX más grande. Para reducir el tamaño de la solicitud (actualmente 2072576 bytes),
reduzca el uso de memoria compartida de PostgreSQL, quizás reduciendo shared_buffers o max_connections.

Si el tamaño de la solicitud ya es pequeño, es posible que sea menor que el parámetro SHMMIN de su kernel,
en cuyo caso es necesario aumentar el tamaño de la solicitud o reconfigurar SHMMIN.

La documentación de PostgreSQL contiene más información sobre la configuración de memoria compartida. El proceso hijo salió con el código de salida 1.

De manera similar, puede obtener un error al iniciar el servidor PostgreSQL utilizando el comando pg_ctl.

pg_ctl Fallo
DETALLES: La llamada al sistema fallida fue shmget(key=5432001, size=14385152, 03600).

SUGERENCIA: Este error generalmente significa que la solicitud de PostgreSQL para un segmento de memoria compartida excedió el parámetro SHMMAX de tu kernel.

Puede reducir el tamaño de la solicitud o reconfigurar el kernel con un SHMMAX más grande. Para reducir el tamaño de la solicitud (actualmente 14385152 bytes), reduzca el uso de memoria compartida de PostgreSQL, quizás reduciendo shared_buffers o max_connections.

Si el tamaño de la solicitud ya es pequeño, es posible que sea menor que el parámetro SHMMIN de su kernel,
en cuyo caso es necesario aumentar el tamaño de la solicitud o reconfigurar SHMMIN.

La documentación de PostgreSQL contiene más información sobre la configuración de memoria compartida.

Comprender las diferencias en las definiciones

La definición de los parámetros SHMMAX/SHMALL varía un poco entre Linux y MacOS X:

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

Comando sysctl puede usarse para cambiar temporalmente el valor. Para establecer valores permanentes, agregue una entrada en /etc/sysctl.conf. Los detalles están a continuación.

Cambio de parámetros del kernel en 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

Cambio de parámetros del kernel en 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

No olvide: para hacer que los cambios sean permanentes, agregue estos valores a /etc/sysctl.conf

Páginas grandes (Huge Pages)

En Linux, por defecto se utilizan páginas de memoria de 4 KB, en BSD — Super Pages, y en Windows — Large Pages. Una página es una parte de la memoria RAM asignada a un proceso. Un proceso puede tener varias páginas dependiendo de sus requisitos de memoria. Cuanta más memoria requiera un proceso, más páginas se le asignan. El sistema operativo mantiene una tabla de asignación de páginas para los procesos. Cuanto más pequeño sea el tamaño de la página, más grande será la tabla, y más tiempo se requerirá para buscar una página en esa tabla de páginas. Por lo tanto, las páginas grandes permiten utilizar grandes volúmenes de memoria con costos reducidos; menos accesos a páginas, menos errores de página, operaciones de lectura/escritura más rápidas a través de grandes búferes. Como resultado, se mejora el rendimiento.

PostgreSQL solo admite páginas grandes en Linux. Por defecto, Linux utiliza páginas de memoria de 4 KB, por lo que en casos con muchas operaciones de memoria, es necesario establecer páginas de mayor tamaño. Se observa un aumento en el rendimiento al utilizar páginas grandes de 2 MB hasta 1 GB. El tamaño de la página grande puede establecerse durante el arranque. Puede verificar fácilmente los parámetros de la página grande y su uso en su computadora Linux usando el comando cat /proc/meminfo | grep -i huge.

Obteniendo información sobre páginas grandes (solo en Linux)

Nota: Esto es solo para Linux, para otros SO esta operación se ignora
$ 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

En este ejemplo, aunque el tamaño de la página grande está establecido en 2048 (2 MB), el número total de páginas grandes tiene un valor de 0. Esto significa que las páginas grandes están desactivadas.

Script para determinar la cantidad de páginas grandes

Este es un script simple que devuelve la cantidad necesaria de páginas grandes. Ejecute el script en su servidor Linux mientras PostgreSQL está en funcionamiento. Asegúrese de que la variable de entorno $PGDATA está configurada en el directorio de datos de PostgreSQL.

Obteniendo el número requerido de páginas grandes

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

La salida del script se ve así:

Salida del script

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

El valor recomendado de páginas grandes es 88, por lo que debe establecer el valor en 88.

Estableciendo páginas grandes

sysctl -w vm.nr_hugepages=88

Verifique las páginas grandes ahora, verá que las páginas grandes no se están utilizando (HugePages_Free = HugePages_Total).

Nuevamente información sobre páginas grandes (solo en 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

Ahora configure el parámetro huge_pages como 'on' en $PGDATA/postgresql.conf y reinicie el servidor.

Y nuevamente información sobre páginas grandes (solo en 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

Ahora puede ver que se están utilizando muy pocas páginas grandes. Ahora intentemos agregar algunos datos a la base de datos.

Algunas operaciones de la base de datos para utilizar grandes páginas

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

Veamos si ahora estamos utilizando más grandes páginas que antes.

Una vez más, información sobre grandes páginas (solo en 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

Ahora puedes ver que la mayoría de las grandes páginas están siendo utilizadas.

Nota: el valor aproximado para HugePages utilizado aquí es muy bajo, lo cual no es un valor normal para una máquina en un entorno productivo. Por favor, evalúa la cantidad necesaria de páginas para tu sistema y ajústalas en consecuencia según la carga y los recursos.

vm.swappiness

vm.swappiness — este es otro parámetro del núcleo que puede afectar el rendimiento de la base de datos. Este parámetro se utiliza para controlar el comportamiento de la paginación (swappiness) (la paginación de páginas en la memoria y fuera de ella) en Linux. El valor varía de 0 a 100. Determina cuánta memoria será liberada o intercambiada. Cero significa desactivar el intercambio y 100 significa intercambio agresivo.

Puedes lograr un buen rendimiento configurando valores más bajos.

Establecer un valor de 0 en núcleos más nuevos puede resultar en que el OOM Killer (el proceso de limpieza de memoria en Linux) mate el proceso. Por lo tanto, se puede establecer de forma segura un valor de 1 si deseas minimizar la paginación. El valor por defecto en Linux es 60. Un valor más alto hace que el MMU (módulo de gestión de memoria) use más espacio de intercambio que RAM, mientras que un valor más bajo mantiene más datos/código en memoria.

Un valor más bajo es una buena apuesta para mejorar el rendimiento en PostgreSQL.

vm.overcommit_memory / vm.overcommit_ratio

Las aplicaciones obtienen memoria y la liberan cuando ya no la necesitan. Pero en algunos casos, una aplicación recibe demasiada memoria y no la libera. Esto puede provocar el OOM killer. Aquí están los posibles valores para el parámetro vm.overcommit_memory con una descripción para cada uno:

  1. Overcommit heurístico (por defecto); heurística basada en el núcleo
  2. Permitir overcommit en cualquier caso
  3. No sobrepases el coeficiente de overcommit.

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

vm.overcommit_ratio — porcentaje de la memoria RAM disponible para sobrecarga. Un valor del 50% en un sistema con 2 GB de RAM puede asignar hasta 3 GB de RAM.

Un valor de 2 para vm.overcommit_memory proporciona un mejor rendimiento para PostgreSQL. Este valor maximiza el uso de RAM por el proceso del servidor sin un riesgo significativo de ser terminado por el proceso OOM killer. La aplicación podrá reiniciarse, pero solo dentro de la sobrecarga, lo que reduce el riesgo de que OOM killer termine el proceso. Por lo tanto, un valor de 2 ofrece un mejor rendimiento que el valor predeterminado de 0. Sin embargo, la fiabilidad se puede mejorar evitando que la memoria esté por encima del rango permitido, lo que elimina el riesgo de que el proceso sea finalizado por OOM killer.

En sistemas sin intercambio, puede haber un problema con vm.overcommit_memory establecido en 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 — es el porcentaje de memoria ocupada por páginas sucias que deben escribirse en el disco. El volcado en el disco se realiza en segundo plano. El valor de este parámetro varía de 0 a 100; sin embargo, un valor por debajo de 5 puede ser ineficaz, y algunos núcleos no lo admiten. 10 es el valor predeterminado en la mayoría de los sistemas Linux. Puede mejorar el rendimiento para operaciones de escritura intensiva con un menor ratio, lo que significa que Linux volcará páginas sucias en segundo plano.

Necesita establecer el valor vm.dirty_background_bytes dependiendo de la velocidad de su disco.

Para estos dos parámetros no hay valores 'buenos', ya que ambos dependen del hardware. Sin embargo, establecer vm.dirty_background_ratio en 5 y vm.dirty_background_bytes en el 25% de la velocidad del disco mejora el rendimiento en aproximadamente un 25% en la mayoría de los casos.

vm.dirty_ratio / dirty_bytes

Es lo mismo que vm.dirty_background_ratio / dirty_background_bytes, excepto que el volcado se realiza en la sesión activa, bloqueando la aplicación. Por lo tanto, vm.dirty_ratio debe ser mayor que vm.dirty_background_ratio. Esto asegura que los procesos en segundo plano se inicien antes para evitar el máximo posible de bloqueo de la aplicación. Puede ajustar la diferencia entre estos dos ratios según la carga de E/S del disco.

Summary

Puedes ajustar otros parámetros para mejorar el rendimiento, pero las mejoras serán mínimas y no obtendrás beneficios significativos. Debemos recordar que no todos los parámetros son relevantes para todos los tipos de aplicaciones. Algunas aplicaciones funcionan mejor cuando ajustamos ciertos parámetros, mientras que otras no. Debes encontrar el equilibrio correcto entre las configuraciones de estos parámetros para la carga de trabajo esperada y el tipo de aplicación, así como tener en cuenta el comportamiento del sistema operativo al realizar la configuración. Ajustar los parámetros del kernel no es tan sencillo como ajustar los parámetros de la base de datos; aquí es más complicado dar recomendaciones.

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster