Algunos consejos generales para aumentar el rendimiento

diskarray

Como hemos dicho muchas veces, no existe siempre la solución perfecta para aumentar el rendimiento de nuestro sistema. Las bases de datos son sistemas dinámicos que se utilizan de diferentes maneras y contienen diferentes tipos de datos.

Una configuración que funciona bien con un sistema, no tiene porque hacerlo con otro y existen muchos factores que pueden afectar positiva y negativamente al rendimiento.

Pero existen diferentes técnicas que se pueden usar aisladas ó en conjunto que ayudan en muchos casos a mejorar el rendimiento. Aqui teneis una pequeña lista con algunos consejos generales que suelen ayudar en muchas ocasiones cuando se necesita mejorar el rendimiento. En esta lista no tendremos en cuanta las mejorias que se pueden obtener con el uso adecuado de SQL y normalización de los datos.

  • Ejecutar VACUUM ANALYZE tan a menudo como sea necesario, Bien manualmente ó ajustanto autovacuum si es necesario
  • Un sistema de discos de alto rendimiento suele ser más importante que la cantidad de memoria disponible y esta a su vez más importante que la CPU utilizada.
  • Un servidor de bases de datos nunca tendra suficiente memoria. Cuanta más memoria, mejor.
  • Cuanto más discos disponibles en RAID, mejor. Usar Tablespaces para organizar los datos.
  • RAID 1+0 / 0+1 suele funcionar mejor que RAID 5.
  • Saparar el registro de transacciones (ficheros WAL) del resto de datos, usar diferentes discos.
  • Aumentar el valor de checkpoint_segments en sistemas con una alta concurrencia de actualizaciones de los datos (insert,update,delete)
  • Discos SCSI y SAS som preferibles en servidores con un alto nivel de utilización
  • Múltiples CPUs ayudan a ejecutar/realizar trabajos paralelos en nuestras bases de datos.
  • Ejecutar CLUSTER cuando sea viable en tablas con una alto nivel de actualización de datos.
  • Utilizar un servidor dedicado siempre que sea posible. Será más facil de configurar y ajustar para mejorar nuestro rendimiento.
  • Al inicializar/poblar una nueva base de datos con una gran cantidad de datos:
    • Usar COPY en vez de INSERT
    • Remover los indices durante la restauración de los datos.
    • Aumentar el valor de maintenance_work_mem
    • Aumentar el valor de checkpoint_segments
    • fsync=false !! No olvidar cambiar este valor a TRUE cuando termineis de restaurar los datos !!
    • No olvidar ejecutar ANALYZE al termino de la restauración de los datos

Bueno, y hasta aqui los consejos generales, más adelante iremos profundizando en aspectos concretos que pueden afectar al rendimiento.

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.

por que fsync=false?

Ese parametro afecta a todas las transacciones en curso y es peligroso tenerlo en OFF. Al menos desde 8.3 existe synchronous_commit tiene el mismo efecto en rendimiento pero se setea a nivel de sesion y si el servidor por algun momento falla no existe el riesgo de corrupcion de datos.

http://www.postgresql.org/docs/current/static/runtime-config-wal.html
http://www.postgresql.org/docs/current/static/wal-async-commit.html

Imagen de ralfm

Re: por que fsync=false?

Muy buena apreciación. Como tu comentas y yo recalco en el artículo, fsync = off es muy peligroso y no se deberia de utilizar en sistemas en producción.

El artículo dice que se puede utilizar solamente cuando estemos restaurando los datos. Yo lo he utilizado cuando he realizado actualizaciones mayores de PostgreSQL, durante la importación de grandes cantidades de datos y nadie tiene acceso a las bases de datos.

Con otras palabras, en entornos controlados, nunca en producción y sabiendo lo que se hace.

synchronous_commit, como tu dices, es la única opción viable si se tiene que utilizar en producción y podemos permitirnos el perder algunas transacciones (sin corrupción de datos). Pero solo está disponible a partir de la version 8.3.

No estaría mal hacer un test para ver el aumento de velocidad que se consigue con las diferentes opciones.

No estoy de acuerdo del todo en alguna cosa...

Por experiencia en BBDD de alta concurrencia, es más importante la RAM que la velocidad real de los discos, sobre todo si la BBDD es principalmente lectura y no hay inserciones o updates masivos.
¿Por qué? Pues porque a más RAM, más cacheado por parte de sistema operativo. En un sistema QUAD XEON con una carga media de 60% de BBDD os puedo asegurar que con una buena cantidad de RAM las operaciones de I/O al disco duro, si no hay operaciones masivas de escritura, son mínimas una vez que el sistema lleva un rato operando y el sistema operativo ha cacheado adecuadamente.
Las operaciones de escritura puntuales, igualmente pueden amortiguarse enormemente con una controladora simple con un poco de caché (64,128MB).
Ahora, eso sí, si las inserciones son masivas, entonces los discos se notarán una auténtica barbaridad.

A modo de ejemplo, en el sistema que os comento se sustituyó un sistema de 3 discos SCSI antiguo en RAID5 (sí, RAID5 sucks!!!) por una cabina iSCSI de 8 discos en RAID1. El rendimiento en escritura se multiplicó por tres, y sin embargo la operativa en el día a día apenas se modificó. Una serie de procesos batch nocturos pasaron de tardar hora y media a apenas 30 minutos, donde había muchas inserciones y un VACUUM nocturno, y un matenimiento de reindexación semanal pasó a tardar solo 1 hora (antiguamente casi tres). Pero el rendimiento general en el día a día apenas se notó.

Así que mi consejo es, primero la RAM, luego los discos.

Imagen de rafaelma

memoria vs. discos

Gracias por la puntualización y el comentario de calidad.

En el caso que comentas, principalmente lectura y sin inserciones o updates masivos, tienes toda la razón. Otro parametro a tener en cuenta, del cual no das datos, es el tamaño de la base de datos. Si no es muy grande en comparación a la memoria disponible, no se notarán mucho mejores discos, como tu dices. Pero si es el tamaño de la base de datos es mucho mayor que la memoria que podamos conseguir, mejores discos serán más importantes que la memoria, incluso en bases del tipo que comentas (aunque esto tambien dependerá de como y que datos se lean)

En el artículo se dan consejos generales y se avisa que no existe la solución perfecta. Cada base de datos es un mundo y tu ejemplo ilustra perfectamente esto, gracias por demostralo.

fsync=true, muy, pero muy malo si quieres una BD rápida

Si estas utilizando "fsync = true", es por que tienes una base de datos que se podría decir que es de solo lectura y es donde da "casi" igual tener este parametro "false" o "true". Por el contrario, si tu base de datos realiza sentencias "UPDATE", "INSERT", "VACUUM FULL", de forma constante y quieres un rendimiento "Bueno o muy Bueno", es mejor que coloques este parametro en "false".

¿Por que?, bueno una manera rápida de explicarlo es:

fsync=true --> Ir a disco por cada transacción

fsync=false --> Ir a cache de disco y/o cache de memoria por cada transacción, e ir a disco realmente cuando yo lo desee (ya que esto lo configuras en los WAL del archivo postgresql.conf).

NOTA: Jamas los discos por muy rápido que sean se acercarán siquiera a la velocidad de la memoria RAM, salvo este tipo de productos que revolucionaran la forma de pensar (Fusion-io ioDrive, www.fusionio.com/)

Por supuesto que para tener "fsync = false" debes cumplir con ciertas cosas que te permitan dormir confiado si eres el administrador de la base de datos, entre ellas estan:

* Un hardware con redundancia (funte de poder, discos en RAID, UPS, etc) y ademas muy confiable.
* Un respaldo de tu base de datos realizado con frecuencia.

Pero si eres de los que tine muchos recursos, pues no te queda otra que dormir confiado y hasta soñar si puedes utilizar cosas como:

* PostgreSQL PITR
* cluster de tu BD (actvo-activo->multimaster, activo-pasivo->master-slave).

Imagen de rafaelma

Re: fsync=true, muy, pero muy malo si quieres una BD rápida

Siento decirte que estoy totalmente en desacuerdo con las afirmaciones de tu comentario.

Tener "fsync = false" es muy, muy peligroso, en sistemas de producción en donde los datos son importantes. Este parámetro se utiliza solamente por PostgreSQL para los ficheros WAL (no los ficheros de datos), para garantizar la integridad de tu base de datos e implementar ACID.

Con "fsync = false" tu base de datos PostgreSQL *no* es ACID. Si PostgreSQL se apaga de manera no controlada, fsync esta apagado y tienes solamente un poco de mala suerte, perderas datos y tendras una base de datos corrupta e inconsistente que no podras arrancar.

Por mucho hardware de redundancia y de confianza que tengas y por muchos backups que hagas, nunca, repito nunca, deberias de apagar fsync si aprecias tus datos y no puedes permitirte la perdida de los mismos.

Yo llevo muchos años trabajando con sistemas redundantes a todos los niveles del stack, de calidad y nada baratos. Un par de veces en todos estos años hemos sufrido una situación imprevista en las que con fsync apagado hubiesemos perdido datos y tenido que usar mucho tiempo para restaurar el sistema.

PITR y replicación de poco sirven con fsync apagado, ya que se basan y confian en que el sistema WAL funcione al 100% (y para ello fsync tiene que estar activado)

¿Qué versión de PostgreSQL estas utilizando? con las últimas versiones y en especial la serie 8.3, el rendimiento de tu sistema será excelente con "fsync=true" si tienes todo configurado correctamente y ejecutandose en el hardware adecuado.

PD.- No deberias de tener necesidad de usar "VACUUM FULL". Es lento, te bloquea el sistema completamente y es innecesario si utilizas VACUUM normal adecuadamente.

--
Un saludo
Rafael Martinez
webmaster

Re: fsync=true, muy, pero muy malo si quieres una BD rápida

Sin animos de caer en un dilema mayor, mi explicación anterior solo toma el titulo de tu articulo "Algunos consejos generales para aumentar el rendimiento" en el cual estas hablando principalmente de mejorar el rendimiento y me parecen todos muy buenos menos el del tema del "fsync" por supuesto. Al hablar de mejorar el rendimiento de PostgreSQL, tu estás siendo antagónico recomendando colocar el "fsync=on".

Ahora bien, si tu título obedeciera a "como evitar perdia de tus datos en caso de una falla de hardware o software", cabe muy bien la recomendación de colocar el "fsync=on"

Para mas información leer detalladamente el siguiente enlace:
http://www.postgresql.org/docs/8.3/interactive/runtime-config-wal.html

de la cual extraje textualmente

"However, using fsync results in a performance penalty: when a transaction is committed, PostgreSQL must wait for the operating system to flush the write-ahead log to disk. When fsync is disabled, the operating system is allowed to do its best in buffering, ordering, and delaying writes. This can result in significantly improved performance."

Con respecto a la versión de PostgreSQL que utilizo, pues afortunadamente utilizo en ambientes de produnccióon las versiones 7.4, 8.0, 8.2 y 8.3.

Hablando del comando "VACUUM", por tu comentario presiento que utilizas bases de datos de solo consultas, o de pocas transacciones de UPDATE, INSERT y DELETE. Toda base de datos en PostgreSQL que maneja grande volumenes de transacciones y que mayormente sean de UPDATE, INSERT y DELETE deben ser sometidas a ejecuciones periodicas de los comandos VACUUM, REINDEX y ANALIZE entre otros, si no quieres un descenso de tu rendimiento y espacio en disco; sin contar que es necesario para eliminar el bien conocido problema del "ID wraparound" . Tanto es así que el equipo de desarrollo de PostgreSQL se vio gratamente satisfecho cuando incorporó la herramienta de contribución "pg_autovacuum" al core de PostgreSQL.

Para mas información leer detalladamente el siguiente enlace: http://www.postgresql.org/docs/8.3/interactive/routine-vacuuming.html
http://www.postgresql.org/docs/8.3/interactive/catalog-pg-autovacuum.html

Imagen de rafaelma

Re: fsync=true, muy, pero muy malo si quieres una BD rápida

Dilema ninguno, este tipo de discusiones es importante para que las cosas queden claras para los usuarios que lean estos comentarios :-)

En el artículo lo que comento es lo contrario a lo que dices, aconsejo poner fsync=false cuando estemos restaurando grandes cantidades de datos, en entornos controlados, nunca en producción y sabiendo lo que se hace. El aumento de rendimiento del que hablo en este ejemplo es solo para restauraciones de datos, y no para sistemas en uso.

El gran problema de tener fsync=false, no es solo que puedas perder datos, sino que tengas una base de datos corrupta que no quiera arrancar. Si quieres tener mejor rendimiento y si te puedes permitir el perder las ultimas transacciones pero sin el riesgo de corromper la base de datos, se puede utilizar synchronous_commit, pero solo está disponible a partir de la version 8.3.

Mi comentario sobre VACUUM se referia *solamente* a "VACUUM FULL". Vacuum + analyze es importantisimo para el buen funcionamiento del sistema, como tu dices. Las veces que hemos tenido que utilizar en los ultimos años REINDEX lo puedo contar con los dedos de la mano y no hemos visto una disminucion en el rendimiento de los sistemas. REINDEX en nuestro caso no es viable tampoco al ser muchas de las bases de datos 24/7 (reindex bloquea el acceso)

Entre las casi 200 bases de datos que administro, tenemos unos 10mill de insert/dia, 3mill de update/dia y unos 3mill de delete/dia con un total de casi 40mill de transacciones/dia, sinceramente no se pueden definir de solo lecturas o con pocas transacciones ;-)

PD.- Voy a intetar de crear alguna estadistica de rendimientos para diferentes usos de fsync y synchronous_commit

--
Un saludo
Rafael Martinez
Webmaster

una ayudita rafael

Contenidos duplicados. Trasladado a: http://www.postgresql-es.org/node/326

Rendimiento de Memoria

Buenos dias

Tenemos un servidor con doble procesamiento y 16 gb de memoria ram, corriendo el linux y el manejador es el postgre, pero siento que las aplicaciones estan demasiado lentas, existe alguna manera de saber si el servidor esta utilizando todos los recursos de hardware que tiene.

gracias pos su aoporte