Tag Archives: CentOS

Migrando Zabbix de MySQL a PostgreSQL

No hace mucho me vi obligado a migrar a PostgreSQL la base de datos de Zabbix que tenía en MySQL y aunque Zabbix soporta las dos bases de datos la migración no fue sencilla. Cómo seguro que alguien más se puede ver en la situación aquí os dejo una guía de lo que a mí me funcionó.

Zabbix es un Sistema de Monitorización creado por Alexei Vladishev y está diseñado para monitorizar y registrar el estado de varios servicios de red, Servidores, Webs …

La decisión de migrar a PostgreSQL básicamente fue porque  la base de datos de Zabbix creció muy rápidamente y nos empezaba a dar problemas de rendimiento. Debido a que Zabbix era la única aplicación que usaba MySQL en nuestro entorno decidimos pasar a PostgreSQL de la que tenemos más experiencia.

Proceso de Migración

En primer lugar un repaso a las versiones de los sistemas implicados:

  • Linux CentOS 6.4
  • Zabbix 2.2
  • MySQL Percona 5.6
  • PostgreSQL 9.1.3

Para realizar la migración utilicé documentación de Zabbix.org donde explican como hacer un Upgrade de la versión de Zabbix 1.8 a 2.0 para después migrar de MySQL a PostgreSQL. En mi caso no me funcionó del todo el proceso de migración y por eso esta guía:

Exportar base de datos MySQL

En mi caso no me funcionó un dump en SQL si no que tuve que hacer un dump en formato CSV. Tampoco me era necesaria la información de histórico así que prescindí de las siguientes tablas:

    • zabbix.acknowledges
    • zabbix.alerts
    • zabbix.events
    • zabbix.history
    • zabbix.history_log
    • zabbix.history_str
    • zabbix.history_str_sync
    • zabbix.history_sync
    • zabbix.history_text
    • zabbix.history_uint
    • zabbix.history_uint_sync
    • zabbix.proxy_dhistory
    • zabbix.proxy_history
    • zabbix.trends
    • zabbix.trends_uint
    • zabbix.user_history

Export de todas las tablas de Zabbix en CSV.


> mkdir /tmp/zabbix/CSV; chown -R mysql: /var/tmp/zabbix
> for i in `find /var/lib/mysql/zabbix/ -type f | \
 sed 's/\....$//' | sort | uniq | sed 's#/var/lib/mysql/zabbix/##'`; do
 mysqldump -t -T/tmp/zabbix/CSV zabbix $i --fields-terminated-by=';' ;
done

Crear base de datos Zabbix en PostgreSQL

Para crear la base de datos Zabbix en PostgreSQL lo mejor es utilizar el schema.sql para PostgreSQL que viene en la distribución de Zabbix. Para que posteriormente la carga de datos no tenga problemas de restricciones eliminamos de schema.sql todos los ADD CONSTRAINT (los necesitaremos para “subir” restricciones después de la carga de datos).

> cat schema.sql | grep "ADD CONSTRAINT" > schema_constraint.sql</span>
> cat schema.sql | grep -v "ADD CONSTRAINT" > schema_modified.sql

Creamos el usuario Zabbix en el PostgreSQL y la base de datos:

> su - postgres -c 'PGPASSWORD=Zabbix22; yes $PGPASSWORD | createuser -P -SdR zabbix'
> echo 'CREATE DATABASE zabbix OWNER zabbix' | psql -U postgres
> export PGPASSWORD=Zabbix22
> psql -U zabbix zabbix < /usr/share/zabbix-postgresql/schema_modified.sql

Cargar los datos exportados de MySQL

Los datos exportados del MySQL en formato CSV los cargamos en PostgreSQL con el comando COPY que copia los datos de un fichero en una tabla.

Antes de hacer el COPY  primero transformar los ‘/r’ de retorno de carro ya que si no el proceso fallará ya que PostgreSQL no interpretará bien el fichero. Este es el error que devuelve PostgreSQL.


ERROR: literal carriage return found in data
HINT: Use "\r" to represent carriage return."

Para cada fichero el retorno de carro ‘\r’ se substituye por ^M con el comando sed:


# Para cada fichero CSV

> sed 's/^M/\\r/' alerts.txt > alerts2.txt

Cargar los datos a la base de datos Zabbix, cómo usuario postgres:


> su - postgres

postgres> psql zabbix
#Para cada fichero CSV
$  COPY alerts FROM 'tmp/zabbix/CSV/alerts.txt' DELIMITER ';' CSV;

Después de cargar los datos y si no hay ningún error podemos “levantar”  CONSTRAINTS

> psql -U zabbix zabbix < /usr/share/zabbix-postgresql/schema_constraint.sql

Si has llegado hasta aquí ya te debería de funcionar todo, aunque por seguridad yo cargué el fichero images.sql que también está disponible en la distribución de Zabbix.

Links de Ayuda

Servidor Web en Linux con Varnish Cache, Apache, PHP+APC, MySQL y WordPress

Aunque en esta entrada vamos a ver como se instala WordPress usando la distribución de CentOS, el objetivo es ver como usando Varnish Cache como “reverse proxy”  aceleramos de forma considerable la velocidad de respuesta de nuestro servidor.

No explicaré la configuración detallada de todos los servicios ya que la explicación podría ser interminable, eso sí, os pondré algunos links de utilidad.

En nuestra instalación, Varnish escuchará por el puerto 80 (http) y apache por el puerto 81.  De esta forma cuando se haga alguna petición http por el puerto 80, Varnish comprobará si esa petición la tiene “cacheada”, si la tiene, la devolverá y si no la tiene, pasará la llamada al apache y a nuestro WordPress que devolverán el contenido. Además apache sólo atenderá peticiones realizadas des de el mismo servidor (127.0.0.1).

Los requisitos de WordPress son: un servidor Web (usaremos apache),  php (añadiremos también el acelerador de php APC)  y la base de datos MySQL. En este caso vamos a utilizar la siguientes versiones:

  • Apache 2.2.15 (Escuchar por el puerto 81)
  • PHP 5.3.3 + APC 3.1.9
  • MySQL 5.1.61 (Escucha por el puerto 3306)
  • Varnish 3.0.2 (Escuchar por el puerto 80).
  • WordPress 3.8.1

Arquitectura

Internet <–> Server

Varnish accelerator
192.168.1.2:80
<–> Apache webserver
127.0.0.1:81
<–> MySQL Server
127.0.0.1:3306

Las peticiones llegarán al servidor Varnish que se encargará de devolver contenido estático ‘cacheado’ o en caso de que no esté en cache trasladará la petición al servidor Web Apache (con WordPress) que devolverá el contenido dinámico haciendo llamadas a la base de datos MySQL vía php

Instalación

Varnish
  • La instalación de Varnish con yum no es difícil (configurarlo es un poco más complicado), en cualquier caso si quieres profundizar puedes seguir esta guía:

http://www.how2centos.com/install-varnish-centos-6/

[root]> rpm -Uhv http:~/~/repo.varnish-cache.org/redhat/varnish-3.0/el5/noarch/varnish-release-3.0-1.noarch.rpm
[root]> yum install varnish
[root]> chkconfig varnishd on
[root]> wget http://wiki.bitnami.org/@api/deki/files/347/=wordpress.vcl
[root]> sudo mv default.vcl default.vcl.orig
[root]> sudo mv wordpress.vlc /etc/varnish/default.vcl/
  • Modificar el fichero de configuració del Varnish default.vcl indicándole que apache escucha por el puerto 81:
# default.vcl where it is specified the Apache port.
backend default {
.host = "127.0.0.1";
.port = "80" ;  change to  "81"
VARNISH_LISTEN_PORT=6081 #change to VARNISH_LISTEN_PORT=80
VARNISH_STORAGE_SIZE=1G #change to VARNISH_STORAGE_SIZE=2G
  • El fichero default.vcl describe al Varnish como ha de cachear la llamadas. En nuestro caso queremos que cachee un WordPress, pero no queremos que se cacheen las llamadas a la parte de administración del WordPress. Varnish Cache nos proporcionar un default.vcl configurado especialmente para WordPress evitándonos la complicación inicial de crear el vcl.

No olvides de configurar req.grace para que el contenido cacheado se mantenga más tiempo si cae el backend. En este caso se mantiene una hora.

if (req.backend.healthy) {
    set req.grace = 30s;
} else {
    set req.grace = 1h;
}
Apache

La instalación de apache también la hacemos vía yum de CentOS:

[root]> yum install httpd.i686
Listen 80  # Change to  Listen 81
Add ServerName localhost:81
  • Modificar el fichero de configuración de apache httpd.conf comentando los módulos que no se utilizan
  • Añadir la parte de compresión de ficheros (requiere del módulo mod_deflate activado)
# compress text, html, javascript, css, xml:
AddOutputFilterByType DEFLATE text /plain
AddOutputFilterByType DEFLATE text /html
AddOutputFilterByType DEFLATE text /xml
AddOutputFilterByType DEFLATE text /css
AddOutputFilterByType DEFLATE application /xml
AddOutputFilterByType DEFLATE application xhtml+xml
AddOutputFilterByType DEFLATE application /rss+xml
AddOutputFilterByType DEFLATE application /javascript
AddOutputFilterByType DEFLATE application /x-javascript
PHP + APC
  • Cómo en los servicios anteriores instalar php con yum:
[root]> yum install php.i686
  • La caché APC de PHP la podéis instalar siguiendo la guía:

http://www.electrictoolbox.com/install-apc-php-linux/

  • Para evitar que la caché APC se fragmente se puede añadir APC_clear.php y limpiar diariamente la caché programando una tarea diaria en el crontab (/etc/cron.daily)

http://linuxaria.com/howto/everything-you-need-to-know-about-apc-alternate-php-cache?lang=en

Mysql
  • La misma forma de instalación para el MySQL vía yum de CentOS:
[root]> yum install mysql.i686
  • Para configurar inicialmente el mysql podéis seguir este procedimiento:

http://dev.antoinesolutions.com/mysql

WordPress

La instalación de WordPress está muy bien explicada en:

http://codex.wordpress.org/Installing_WordPress

Como Iniciar/Parar Servicios

Como usuario root:

root>sudo service httpd stop/start
root>sudo service mysqld stop/start
root>sudo service varnish stop/start

Benchmarking

Para comprobar la efectividad del Varnish he realizado varias pruebas d’estrés de la página principal de mi Blog con una página sencilla y algunas fotos.. Las pruebas las he hecho usando ApacheBench, Version 2.3. Para ver como se comporta la caché del Varnish se puede monitorizar usando el comando varnishhist.

Evidentemente hay diferencia dependiendo de si el Varnish ya tiene el contenido en caché o no. También afecta el número de peticiones concurrentes.. En las pruebas que he hecho nunca he llegado al 100% de CPU y la memoria sobre 70% de ocupación.

En este caso he simulado una carga de 60.000 peticiones y con una concurrencia de 30 peticiones

  • En el caso de 60.000 peticiones con una concurrencia de 30, se sirven todas la peticiones en 87seg (43ms por petición) sin que el Varnish tenga el contenido en caché.
> ab -n 60000 -c 30 http://blog.macordoba.net/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking blog.macordoba.net (be patient)
Completed 6000 requests
Completed 12000 requests
Completed 18000 requests
Completed 24000 requests
Completed 30000 requests
Completed 36000 requests
Completed 42000 requests
Completed 48000 requests
Completed 54000 requests
Completed 60000 requests
Finished 60000 requests
Server Software: Apache
Server Hostname: blog.macordoba.net
Server Port: 80
Document Path: /
Document Length: 5914 bytes
Concurrency Level: 30
Time taken for tests: 87.964 seconds
Complete requests: 60000
Failed requests: 59892
(Connect: 0, Receive: 0, Length: 59892, Exceptions: 0)
Write errors: 0
Total transferred: 372850150 bytes
HTML transferred: 354958356 bytes
Requests per second: 682.10 [#/sec] (mean)
Time per request: 43.982 [ms] (mean)
Time per request: 1.466 [ms] (mean, across all concurrent requests)
Transfer rate: 4139.32 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 8 27.8 8 1022
Processing: 2 36 236.8 9 3988
Waiting: 1 35 236.8 8 3988
Total: 2 44 237.5 17 3989
Percentage of the requests served within a certain time (ms)
50% 17
66% 17
75% 17
80% 17
90% 17
95% 18
98% 33
99% 1988
100% 3989 (longest request)
  • En el caso de 60.000 peticiones con una concurrencia de 30 con la cache del Varnish ya creada, se sirven todas las peticiones en 35seg (17ms por petición).
~> ab -n 60000 -c 30 http://blog.macordoba.net/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking blog.macordoba.net (be patient)
Completed 6000 requests
Completed 12000 requests
Completed 18000 requests
Completed 24000 requests
Completed 30000 requests
Completed 36000 requests
Completed 42000 requests
Completed 48000 requests
Completed 54000 requests
Completed 60000 requests
Finished 60000 requests
Server Software: Apache
Server Hostname: blog.macordoba.net
Server Port: 80
Document Path: /
Document Length: 5916 bytes
Concurrency Level: 30
Time taken for tests: 35.146 seconds
Complete requests: 60000
Failed requests: 0
Write errors: 0
Total transferred: 372840000 bytes
HTML transferred: 354960000 bytes
Requests per second: 1707.19 [#/sec] (mean)
Time per request: 17.573 [ms] (mean)
Time per request: 0.586 [ms] (mean, across all concurrent requests)
Transfer rate: 10359.83 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 9 22.2 8 1005
Processing: 2 9 1.4 9 31
Waiting: 1 8 1.4 9 30
Total: 2 18 22.3 17 1034
Percentage of the requests served within a certain time (ms)
50% 17
66% 17
75% 17
80% 17
90% 17
95% 18
98% 19
99% 23
100% 1034 (longest request)

El resultado no puede ser más concluyente. Con Varnish sirviendo contenido de Caché el contenido se sirve un 50% más rápido.