PostgresSQL Optimizacion
Memoria RAM y paginación
Antes de comenzar,
es preciso recordar, aunque sea de forma somera, el papel de la memoria RAM en
un ordenador, así como los efectos indeseados de la paginación.Podemos imaginarnos
la memoria RAM como un recurso limitado divido en rodajas o segmentos. Los
segmentos, de un tamaño fijo, se agrupan formando páginas de memoria. En la
memoria se guarda todo lo que la CPU necesita para hacer su trabajo, esto
incluye programas, datos requeridos por los programas, el kernel,… y por
supuesto, las zonas de trabajo de postgres.
Para optimizar el uso del espacio disponible en la memoria, las páginas
que hace algún tiempo no se utilizaron son expulsadas por el S.O. al disco, a una
zona denominada swap (intercambio). Esta actividad se
denomina swap pageout y no supone un inconveniente, ya que se
produce en periodos de inactividad de la CPU.
Lo malo viene cuando hay que recuperar una página desde la swap (que
recientemente había sido expulsada de la memoria), porque el programa que la
requiere tendrá que esperar hasta que se encuentre de nuevo allí. Este efecto
adverso, que crece a medida que hay más páginas que se tienen que traer de la
swap, se conoce con el nombre swap pagein o paginación.
El reto de nuestra
afinación va a consistir en optimizar el uso de memoria para postgres,
minimizando en lo posible el número de intercambios con la swap (pagein). El
mejor ajuste de los parámetros de configuración será aquél que obtenga la máxima
disponibilidad en memoria para la BD, sin perjudicar al resto de elementos, que
también deben permanecer en memoria.
El número de shared_buffers es el parámetro que más
afecta al rendimiento de PostgreSQL. Este valor, de tipo entero, indica el
número de bloques de memoria o buffers de 8KB (8192 bytes) que
postgres reservará, como zona de trabajo, en el momento del arranque para
procesar las consultas. De forma predeterminada (en postgresql.conf),
su valor es de 1000. Un número claramente insuficiente para conseguir un
rendimiento mínimamente aceptable.
Estos buffers se ubican dentro de los denominados segmentos de
memoria compartida. Es importante saber que el espacio ocupado por el
número de buffers que pretendamos asignar, nunca podrá exceder al tamaño máximo
que tengan los segmentos de memoria. En caso contrario, postgres se negará a
arrancar avisando con un error que no puede reservar el espacio solicitado.
Llegados a este
punto, te preguntarás:
·
¿Cuántos shared_buffers puedo asignar?
·
¿Cómo sé cual es el tamaño de un segmento?
·
¿Qué puedo hacer si se supera el tamaño máximo del segmento?
Vamos a resolver
todas estas cuestiones de forma práctica, así que coge una taza de café y
siéntate frente a tu servidor. El proceso consiste en los siguientes pasos:
1. Considerar un
número superior al actual de shared buffers (comenzaremos por
un 10% del total de la memoria)
2. Modificar el tamaño
del segmento si no cabe el número de buffers
3. Comprobar el
rendimiento y paginación
4. En función del
resultado obtenido, aumentar o disminuir el porcentaje de memoria y empezar de
nuevo
Una buena recomendación es la de empezar asignando un 10% del total de
la memoria RAM para shared_buffers y a partir de ahí, ir
aumentando o disminuyendo dicho porcentaje en función del rendimiento y la
paginación.
Para comprobar el rendimiento, aplica EXPLAIN a tus consultas. Para ver la
paginación del servidor, puedes usar herramientas como vmstat o ipcs (consulta
sus páginas man).
Antes de comenzar, es preciso recordar, aunque sea de forma somera, el papel de la memoria RAM en un ordenador, así como los efectos indeseados de la paginación.Podemos imaginarnos la memoria RAM como un recurso limitado divido en rodajas o segmentos. Los segmentos, de un tamaño fijo, se agrupan formando páginas de memoria. En la memoria se guarda todo lo que la CPU necesita para hacer su trabajo, esto incluye programas, datos requeridos por los programas, el kernel,… y por supuesto, las zonas de trabajo de postgres.
Para optimizar el uso del espacio disponible en la memoria, las páginas
que hace algún tiempo no se utilizaron son expulsadas por el S.O. al disco, a una
zona denominada swap (intercambio). Esta actividad se
denomina swap pageout y no supone un inconveniente, ya que se
produce en periodos de inactividad de la CPU.
Lo malo viene cuando hay que recuperar una página desde la swap (que
recientemente había sido expulsada de la memoria), porque el programa que la
requiere tendrá que esperar hasta que se encuentre de nuevo allí. Este efecto
adverso, que crece a medida que hay más páginas que se tienen que traer de la
swap, se conoce con el nombre swap pagein o paginación.
El reto de nuestra
afinación va a consistir en optimizar el uso de memoria para postgres,
minimizando en lo posible el número de intercambios con la swap (pagein). El
mejor ajuste de los parámetros de configuración será aquél que obtenga la máxima
disponibilidad en memoria para la BD, sin perjudicar al resto de elementos, que
también deben permanecer en memoria.
El número de shared_buffers es el parámetro que más
afecta al rendimiento de PostgreSQL. Este valor, de tipo entero, indica el
número de bloques de memoria o buffers de 8KB (8192 bytes) que
postgres reservará, como zona de trabajo, en el momento del arranque para
procesar las consultas. De forma predeterminada (en postgresql.conf),
su valor es de 1000. Un número claramente insuficiente para conseguir un
rendimiento mínimamente aceptable.
Estos buffers se ubican dentro de los denominados segmentos de
memoria compartida. Es importante saber que el espacio ocupado por el
número de buffers que pretendamos asignar, nunca podrá exceder al tamaño máximo
que tengan los segmentos de memoria. En caso contrario, postgres se negará a
arrancar avisando con un error que no puede reservar el espacio solicitado.
Llegados a este
punto, te preguntarás:
·
¿Cuántos shared_buffers puedo asignar?
·
¿Cómo sé cual es el tamaño de un segmento?
·
¿Qué puedo hacer si se supera el tamaño máximo del segmento?
Vamos a resolver
todas estas cuestiones de forma práctica, así que coge una taza de café y
siéntate frente a tu servidor. El proceso consiste en los siguientes pasos:
1. Considerar un
número superior al actual de shared buffers (comenzaremos por
un 10% del total de la memoria)
2. Modificar el tamaño
del segmento si no cabe el número de buffers
3. Comprobar el
rendimiento y paginación
4. En función del
resultado obtenido, aumentar o disminuir el porcentaje de memoria y empezar de
nuevo
Una buena recomendación es la de empezar asignando un 10% del total de
la memoria RAM para shared_buffers y a partir de ahí, ir
aumentando o disminuyendo dicho porcentaje en función del rendimiento y la
paginación.
Para comprobar el rendimiento, aplica EXPLAIN a tus consultas. Para ver la
paginación del servidor, puedes usar herramientas como vmstat o ipcs (consulta
sus páginas man).
WORK_MEM
Este parámetro configura el espacio de memoria que postgres utiliza para realizar ordenaciones de tablas o de resultados parciales de consultas, sobre todo en cláusulas ORDER BY, CREATE INDEX o MERGE JOIN.
Este valor es más dificil de configurar porque depende, por un lado, de lo grande que sean las tablas o resultados que hay que ordenar, y por otro, del número de peticiones simultáneas para esa misma consulta (para cada una se empleará la misma cantidad de memoria).
Un buen comienzo es asignar entre un 2% y un 4% del total de la memoria si prevemos pocos accesos simultáneos a grandes sesiones de ordenación y mucho menor, si esperamos muchos accesos simultáneos a sesiones de ordenación pequeñas. Como antes, lo mejor es ir probando distintos valores y ver en qué pueden afectar a la paginación adversa (swap pagein). El valor hay que expresarlo en KB.
Referencias
- PostgreSQL
Hardware Performance Tunning – http://www.ca.postgresql.org/docs/momjian/hw_performance/
- ·
Managing
Kernel Resources – http://developer.postgresql.org/docs/postgres/kernel-resources.html
- ·
Lista de correo pgsql-es-ayuda – http://archives.postgresql.org/pgsql-es-ayuda/2005-11/msg00563.php
- PostgreSQL
Hardware Performance Tunning – http://www.ca.postgresql.org/docs/momjian/hw_performance/