Mostrando entradas con la etiqueta mysql cluster. Mostrar todas las entradas
Mostrando entradas con la etiqueta mysql cluster. Mostrar todas las entradas

MySQL, escalando en BlackHole

En anteriores entradas ya vimos cómo montar un clúster MySQL Master-Slave y también de cómo hacerlo para un Master-Master. En ambos casos la solución era siempre la misma y se comprobó que la segunda opción (máster-máster), no era más que la primera en ambos sentidos.
Hoy vamos a ver una solución más óptima al escalado de un sistema MySQL. Esta opción que veremos suele ser más desconocida, aunque viene perfectamente implementada en el motor de base de datos y permite realizar un escalado master-multi-slave de forma sencilla.
En la mayoría de los casos los sistemas necesitan escalar para dar soporte a múltiples lecturas y no tanto en los que a escrituras se refiere. Esto significa que por cada escritura, a lo mejor tenemos, 500 lecturas. Es decir, la gente consume más de lo que aporta. Obviamente estamos hablando en términos relativos y por supuesto, cada aplicación es un mundo. Sin embargo, si vuestro caso se ajusta al aquí descrito, lo más probable es que vayáis a necesitar varios nodos de lectura. Para ello, MySQL ya aporta el escalado Máster - Slave. y podemos poner, por ejemplo, los Slave en modo sólo lectura. Ahora bien, si pensamos lo que estamos diciendo, vamos a tener un equipo que hará de Máster y del que se replicarán los datos a N Slave's. Según la forma tradicional de trabajo de MySQL, el Máster escribirá en sus tablas los datos, luego en el binary log y luego estos datos serán replicados a los equipos Slave's. Pero si queremos tener un amplio escalado, ¿por qué necesitamos escribir los datos en el Máster? Este tiempo de acceso a disco es innecesario. Si no lo vamos a emplear, lo mejor sería suprimirlo.
Para intentar dar solución a este problema, vamos a hacer uso de la engine de MySQL, BlackHole. Sí, efectivamente, si lo traducimos, agujero negro. Antes de seguir  vamos a ver cómo trabaja en un pequeño ejemplo práctico.
mysql> CREATE TABLE `test` (
    -> `id` SMALLINT(5) UNSIGNED NOT NULL AUTO_INCREMENT,
    -> `nombre` text NOT NULL,
    -> PRIMARY KEY (`id`)
    -> ) ENGINE=BLACKHOLE;
Ya tenemos la tabla creada. Ahora metamos algunas tuplas...
mysql> INSERT INTO test (nombre) VALUES ('javier');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO test (nombre) VALUES ('puppet');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO test (nombre) VALUES ('linux');
Query OK, 1 row affected (0.00 sec)
Las inserciones se realizaron correctamente. Vamos a ver ahora al leer qué obtenemos...
mysql> SELECT * FROM test;
Empty set (0.00 sec)
Lo ocurrido es realmente lo esperado, la engine BlackHole no guarda datos.
Pero entonces, ¿en qué nos puede ayudar BlackHole a la hora de escalar una base de datos?
Pues muy simple, esta nueva engine no escribe los datos en las tablas de MySQL, pero sí lo hace en el binary log, que es justo el log que MySQL emplea para realizar la sincronización de los datos con los esclavos. Por lo tanto, empleando BlackHole podríamos terminar con una arquitectura como la que sigue.
mysql backhole escalate system
MySQL BackHole system escalate
En el equipo máster  que sólo se encargará de realizar las escrituras, todas las tablas serán de tipo BlackHole y tendrá como esclavos al resto de nodos, sobre los que sí existirán realmente los datos y sobre los que se realizarán todas las lecturas.
En el ejemplo anterior, las tres tuplas no se habían escrito en el máster y todo apuntaba a que se habían perdido. Ahora que la nuevo engine se ha explicado, vamos a ver como realmente las tuplas sí están escritas en los esclavos.
slave> select * from test;
+----+--------+
| id | nombre |
+----+--------+
|  1 | javier |
|  2 | puppet |
|  3 | linux  |
+----+--------+
3 rows in set (0.00 sec)
Así que ya sabéis, si realmente os interesa escalar una base de datos de un máster a varios esclavos y las escrituras las tenéis controladas, la opción de poner las tablas del maestro de tipo agujero negro es muy interesante ya que nos permitirá tener un máster más liviano y dejar el trabajo y el proceso de almacenar datos a los esclavos, que son los que realmente lo tienen que hacer.

La entrada, MySQL, BlackHole para escalar la puede leer en Puppet Linux.
Leer más

MySQL multimaster, transacciones

Hemos hablado ya de cómo instalar un servidor MySQL en replicación multimaster, y también cómo solucionar el problema que aparecía en los autoincrementales. Hoy voy a comentar un problema que también aparece en este modelo y que es el de las transacciones. Por temas de rendimiento generalmente MySQL no escribe todos los datos a disco cada vez que algo nuevo se manda, sino que lo junta todo en lo que se denomina una transacción y luego lo realiza. Esto garantiza que los datos sean en todo momento consistentes. El problema que tenemos aquí es saber qué sucede si lo mismo sucede a través de la red. Un master puede enviar los datos para que sean escritos en 'su slave', pero éstos deben garantizarse que son escritos antes de que el master los escriba. De no ser así, podríamos llegar a un punto de inconsistencia: master y slave tendrían datos diferentes. Para evitarlo debemos habilitar las transacciones síncronas. Esto obliga a que los datos sean escritos en el slave antes que en el master y en caso de que el slave no responda, se escriben únicamente en el master pasado un tiempo. Luego el proceso de sincronización de datos deja master y slave en el mismo punto cuando el slave esté nuevamente vivo.
Para configurar esto debemos ejecutar los siguientes comandos en ambos nodos del clúster.
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so'; 
Y en el fichero de configuración (/etc/my.cnf) escribir lo siguiente,
[mysqld]
...
rpl_semi_sync_slave_enabled  = 1
rpl_semi_sync_master_enabled = 1
...
Tras ello, reiniciar el servidor MySQL.
shell> service mysql restart
Una vez terminado de aplicar en ambos nodos, podemos ver las nuevas variables aplicadas y el valor de las mismas, el cual podemos modificar a nuestro antojo, para mejorar el rendimiento si así lo consideramos oportuno.
mysql> SHOW VARIABLES LIKE 'rpl_semi_sync%';
+------------------------------------+-------+
| Variable_name                      | Value |
+------------------------------------+-------+
| rpl_semi_sync_master_enabled       | ON    |
| rpl_semi_sync_master_timeout       | 10000 |
| rpl_semi_sync_master_trace_level   | 32    |
| rpl_semi_sync_master_wait_no_slave | ON    |
| rpl_semi_sync_slave_enabled        | ON    |
| rpl_semi_sync_slave_trace_level    | 32    |
+------------------------------------+-------+
6 rows in set (0.01 sec)

mysql> SHOW STATUS LIKE 'Rpl_semi_sync%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 0     |
| Rpl_semi_sync_master_net_avg_wait_time     | 0     |
| Rpl_semi_sync_master_net_wait_time         | 0     |
| Rpl_semi_sync_master_net_waits             | 0     |
| Rpl_semi_sync_master_no_times              | 0     |
| Rpl_semi_sync_master_no_tx                 | 0     |
| Rpl_semi_sync_master_status                | ON    |
| Rpl_semi_sync_master_timefunc_failures     | 0     |
| Rpl_semi_sync_master_tx_avg_wait_time      | 0     |
| Rpl_semi_sync_master_tx_wait_time          | 0     |
| Rpl_semi_sync_master_tx_waits              | 0     |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 0     |
| Rpl_semi_sync_slave_status                 | ON    |
+--------------------------------------------+-------+
15 rows in set (0.00 sec)

Si quieres ampliar información, aquí.
Leer más

MySQL multimaster: trucos

Si ya habéis leído el post sobre cómo montar un sistema MySQL con dos nodos activos, podréis ver que esa configuración presenta varias deficiencias. Una de las más notorias y que además es casi fijo que os suceda es un fallo a la hora de sincronizar datos si éstos tienen un campo que sea un ID autoincremental.
En una arquitectura master - slave, como sólo se escribe en uno de los nodos, no hay problema, pero en master - master, cada vez que se escriba el auto-incremental se va a aumentar en uno, pudiendo colisionar cuando lleguen los datos del otro nodo. Y si la tabla está diseñada para que no puedan existir datos con ID's duplicados, ya tenemos el lío montado!
Por suerte, MySQL tiene tiene una solución para este problema, que no es otra que indicarle a un nodo que emplee los autoincrementales pares y al otro nodo los impares. De esta forma, cuando se sincronicen los datos, siempre serán correctos y nunca habrá ID's replicados. Para lograr esto, simplemente en el fichero de configuración (/etc/my.cnf) de cada uno de los nodos tendremos que tener lo siguiente,
  • M1: Números pares
    auto_increment_increment = 2
    auto_increment_offset    = 1
    
  • M2: Números impares
    auto_increment_increment = 2
    auto_increment_offset    = 2
    
Lógicamente si aun aplicación es la encargada de realizar los insert's habrá que controlar en función del servidor destino el ID que deba escribir, evitando siempre escribir duplicados para que sea así posible la sincronización de los datos.
Leer más

MySQL Active -- Active (multimaster)

Hace unos días hablamos aquí de cómo poder montar una arquitectura master - slave en MySQL y los beneficios de la misma. Hoy vamos a ver cómo crear un sistema en MySQL master - master (o multimaster) y los beneficios del mismo.
En la gran mayoría de los casos, un sistema master - slave será lo ideal y ofrecerá una buena estabilidad entre rendimiento y fiabilidad. En este caso, lo que se favorece es un gran número de lecturas, frente a un número considerablemente bajo de escrituras. Por el contrario, la nueva acquitectura master - master, lo que favorecerá será a un gran número de escrituras, frente a un número normal o bajo de lecturas. Se escribe más de lo que se lee, de ahí que nos interese dividir los servidores de escritura.
Montar un sistema master - master realmente es configurar en ambos sentidos un sistema master - slave. El Master-1 será el slave del Master-2 y viceversa. Todo lo que se escriba en Master-2 será replicado automática a Master-1 y todo lo que se escriba en Master-1 será replicado automática a Master-2.
Los datos de los que partimos serán:
  • M1 -- 192.168.0.33 -- id: 1
  • M2 -- 192.168.0.35 -- id: 2
En ambos nodos se cuenta con una versión 5.5.x de MySQL previamente instalada, por lo que únicamente explicaremos el proceso de replicación. Puesto que prácticamente lo que se haga en el primer nodo lo tendremos que ejecutar en el segundo, simplemente haremos un cambio del prompt de MySQL, para saber en qué equipo estamos en cada momento.
  1. Configuramos los servidores
    Aquí únicamente tendremos que configurar el fichero de configuración de MySQL (/etc/my.cfg) de ambos nodos. La configuración es similar a la de la arquitectura master-slave, pero como salvedad en este caso únicamente haremos réplica máster-máster de una base de datos.
    log-bin          = mysql-bin
    binlog-do-db     = BD_master
    binlog-ignore-db = mysql
    binlog-ignore-db = test
    server-id        = 1
    
    Y aplicamos la misma configuración para M2, salvo por el server-id.
    log-bin          = mysql-bin
    binlog-do-db     = BD_master
    binlog-ignore-db = mysql
    binlog-ignore-db = test
    server-id        = 2
    
  2. Reiniciamos el servicio MySQL
    M1@shell> service mysqld restart
    
    En ambos nodos...
    M2@shell> service mysqld restart
    
  3. Creamos un backup de los datos
    El equipo M1 es el que contiene los datos de origen, así que serán los que empleemos para crear el clúster. Por lo tanto, haremos un backup de los mismos,
    M1@shell> mysqldump -u root -p --master-data=2 > all.sql
    
  4. Posición del log para replicación
    Y al igual que sucede al crear un slave, necesitamos saber en qué punto del binary log estamos situados, para indicar que será a partir de ese punto desde donde deba comenzar a replicar. Para eso, simplemente desde el servidor M1, ejecutamos:
    mysql@M1> SHOW MASTER STATUS;
    +------------------+----------+--------------+------------------+
    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
    +------------------+----------+--------------+------------------+
    | mysql-bin.000001 |       98 |              |                  | 
    +------------------+----------+--------------+------------------+
    
    1 row in set (0.00 sec)
    
  5. Importamos los datos en M2
    Importamos los datos que sacamos del servidor M1 al servidor M2 para partir de los mismos datos de origen. Previamente a este importado, tendremos que pasar el fichero all.sql de M1 a M2.
    mysql@M2> SOURCE /home/javier/all.sql
    
  6. Creamos el usuario de replicación
    Puesto que ambos nodos se replican el uno del otro, tendremos que crear un usuario en cada uno de los servidores.
    mysql@M1> GRANT REPLICATION SLAVE, REPLICATION CLIENT 
           -> ON *.* 
           -> TO remote_user@'192.168.0.35' 
           -> IDENTIFIED BY 'remote_user_passwd';
    
    Lo mismo para el segundo master.
    mysql@M2> GRANT REPLICATION SLAVE, REPLICATION CLIENT 
           -> ON *.* 
           -> TO remote_user@'192.168.0.33' 
           -> IDENTIFIED BY 'remote_user_passwd';
    
  7. Configuramos la replicación de datos
    mysql@M1> CHANGE MASTER TO MASTER_HOST='192.168.0.35',
           -> MASTER_USER = 'remote_user',
           -> MASTER_PASSWORD = 'remote_user_passwd',
           -> MASTER_LOG_FILE = 'mysql-bin.000001 ',
           -> MASTER_LOG_POS = 98;
    
    mysql@M2> CHANGE MASTER TO MASTER_HOST='192.168.0.33',
           -> MASTER_USER = 'remote_user',
           -> MASTER_PASSWORD = 'remote_user_passwd',
           -> MASTER_LOG_FILE = 'mysql-bin.000001 ',
           -> MASTER_LOG_POS = 98;
    
  8. Arrancamos los procesos slave's en ambos nodos
    mysql@M1> START SLAVE;
    
    mysql@M2> START SLAVE;
    
Y con esto ya tenemos un sistema de MySQL activo - activo, o lo que es lo mismo un slave de cada uno de los master's.
Leer más

MySQL, deshabilitar slave-replication en una sesión

Hace tiempo hablamos de cómo poder montar un MySQL en una arquitectura master-slave y también cómo hacer para poner por un momento un slave en modo sólo lectura. Lo habitual es que el sistema slave esté en modo sólo lectura y evitar así que alguien se conecte a esta máquina y haga cambios no requeridos y que ello corrompa los datos, bien del slave, bien de ambos (master y slave). Aunque al ponerlo en modo read_only no se permite la escritura, un usuario con privilegios de SUPER sí puede realizar cambios. No suele ser lo habitual, pero en caso de que sea necesario, sí es posible realizar dichos cambios sin afectar a la estructura master-slave. Para ello hay únicamente que deshabilitar para la sesión actual la escritura en el binary log. Esto se hace con la variable sql_log_bin.
mysql> set sql_log_bin = 0;
A partir de este momento todo lo que se ejecute no se escribirá en el binary log y por lo tanto el slave no lo verá y afectará a sus cambios.
Para volver a la forma de trabajo habitual, únicamente hay que volver a poner dicha variable a 1 o salir de la sesión, puesto que el valor sólo fue establecido para la sesión.
Leer más

MySQL, detener replicación definitivamente

Hace tiempo expliqué de forma muy simple y rápida cómo poder realizar una configuración MASTER-SLAVE en MySQL. Ya sabéis, en caso de que queramos mejorar un poco el rendimiento de una base de datos o tener alta disponibilidad, esta es una buena opción, ya que dejamos a MySQL la responsabilidad de duplicar los datos en vez de añadir una capa intermedia (DRDB, por ejemplo) y por lo tanto más complejidad al sistema. Ésto último, no en todos los casos es posible ;-)
Pero, ¿cómo hacemos para dejar de replicar un sistema? Esta es una buena pregunta, ya que MySQL permite parar la sincronización de un esclavo, tal que así,
mysql-slave> STOP SLAVE;
Y como se puede observar tampoco existe el proceso que se encarga de la réplica,
mysql-slave> SHOW PROCESSLIST;
+--+----+---------+----+-------+----+-----+----------------+
|Id|User|Host     |db  |Command|Time|State|Info            |
+--+----+---------+----+-------+----+-----+----------------+
|1 |root|localhost|NULL|Query  |  0 |NULL |show processlist|
+--+----+---------+----+-------+----+-----+----------------+
1 row in set (0.00 sec)
Sin embargo, si miramos el estado del esclavo vemos que sigue teniendo perfectamente definidas todas las variables de sincronización con el equipo maestro,
mysql-slave> SHOW SLAVE STATUS \G
*************************** 1. row ***************************
               Slave_IO_State: 
                  Master_Host: 192.168.0.64
                  Master_User: slave
                  Master_Port: 3306
                Connect_Retry: 30
              Master_Log_File: mysql-bin.005010
          Read_Master_Log_Pos: 1676964
               Relay_Log_File: sistema_db_2-relay-bin.000423
                Relay_Log_Pos: 1677110
        Relay_Master_Log_File: mysql-bin.005010
             Slave_IO_Running: No
            Slave_SQL_Running: No
...
...
1 row in set (0.00 sec)
Y por lo tanto ante un reinicio del servicio, por ejemplo o un "START SLAVE" la replicación volvería a comenzar.
Entonces, ¿cómo borramos definitivamente esas configuraciones? Para poder hacer eso, MySQL implemente el siguiente comando,
mysql-slave> RESET SLAVE ALL;
Query OK, 0 rows affected (0.00 sec)
que reinicia todas las variables de replicación a valores nulos y por lo tanto volver a sincronizar el máster con el slave ya no será posible. Si ahora miramos el estado del slave, ¡¡lo conseguimos!!
mysql-slave> SHOW SLAVE STATUS \G
Empty set (0.00 sec)
Ya para finalizar, y dejar los sistemas limpios si no nos interesa volver a establecer ningún equipo como slave del máster, simplemente revocamos los permisos de réplica del usuario que en su día se creó para dicha tarea.
mysql-master> REVOKE REPLICATION SLAVE ON *.* FROM 'slave'@'%';
Query OK, 0 rows affected (0.00 sec)
Leer más

MySQL: slave en sólo lectura

En un post anterior se habló de cómo montar un sistema de replicación de MySQL master-slave y las ventajas que esto supone para la alta disponibilidad.
Hay veces que también puede ofrecer una mejora considerable en un sistema, al tener un único nodo de escritura y otro nodo de lectura. Si esto va a suceder, lo mejor es indicar que el servidor slave será de 'sólo lectura', para conseguir así optimizar las consultas.
La desventaja de esto es que la aplicación que realice las consultas no puede realizar ninguna escritura, si lo hace, ésta será denegada, ya que en el slave luego no se podrá escribir y todas las escrituras las habrá que realizar desde el master. Algo que además deja una mejor consistencia en los datos: en el master se escribe y en los slaves se lee.
Para conseguir realizar esto, MySQL tiene una variable que podemos establecer en el fichero de configuración (/etc/my.cfg) para que se comporte como servidor de sólo lectura.
read_only

Luego desde el prompt de MySQL lo comprobamos.
mysql> show variables like 'read_only';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| read_only     | ON    |
+---------------+-------+
1 row in set (0.00 sec)

La entrada, MySQL: slave en sólo lectura la puedes leer en El mundo en bits.
Leer más

MySQL Cluster howto

Víde explicativo de cómo montar en 7 minutos un cluster mysql basado en MySQL Cluster 7.1.


Leer más

Formulario de contacto

Nombre

Correo electrónico *

Mensaje *

Últimos comentarios