Archivo | diciembre, 2007

Cómo iniciar una replicación Maestro – Esclavo en MySQL >5.0

3 Dic

La replicación en MySQL funciona de una manera muy sencilla. Existe un maestro, que es el encargado de propagar los cambios y los esclavos, que son los que reciben estos cambios a fin de tener una copia exacta de lo que tiene el maestro.

Para que esto suceda, los esclavos tienen una conexión abierta contínua con el maestro para recibir estos cambios. Con esta conexión se comprueba desde el esclavo la última posición escrita en el log binario del maestro -eso es, se replican por medio del log binario. Cuando sucede algún cambio en el log binario del maestro, se remiten estos cambios a los esclavos, que posteriormente ejecutan estos cambios en sus tabla.s

Para empezar una replicación maestro esclavo sencilla hay que tener como mínimo dos instancias del servidor MySQL, una que haga de maestro y otra que haga de esclavo.

En el maestro tienen que estar las siguientes líneas en el fichero de configuración [my.cnf]:

log-bin=mysql-bin
server-id = 1

Por otro lado, en el esclavo tendremos que tener las siguientes lineas:

server-id = 2

Una vez configurados los servidores, podemos arrancarlos -obviamente aún no van a replicar porque no les hemos indicado que empiecen a replicar.

Cuando estén arrancados, en el maestro creamos o instalamos las tablas y la base de datos que queremos replicar. Cuando estén creadas y hayamos insertado los datos necesarios dentro de las tablas entonces tendremos que hacer un volcado de la base de datos a un archivo de texto. La razón de esto es que vamos a instalar esta misma base de datos en el esclavo. Para ello lo podremos hacer así:

mysql> GRANT REPLICATION PRIVILEGES ON *.bbdd TO 'usuario_replicacion'@'192.168.0.3' IDENTIFIED BY 'pass_replicacion';
mysql> flush privileges;
mysql> LOCK ALL TABLES READ ONLY
mysql> exit

Ahora desde la línea de comandos sacamos un DUMP del maestro:

joax@maestro> mysqldump bbdd > bbdd_dump_20071202.sql

Una vez terminado el proceso, tenemos que recordar la situación del log binario en el master:

mysql> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000005 | 98 | | |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)

Con esto ya podemos desbloquear las tablas en el maestro:

mysql> UNLOCK ALL TABLES;

Y con ello, en el esclavo ahora ejecutamos lo siguiente:

joax@esclavo> mysql bbdd < bbdd_dump_20071202.sql

Y una vez que el esclavo tenga generada la base de datos, lo configuramos para que esté posicionado con respecto al maestro:

mysql> CHANGE MASTER TO MASTER_HOST = '192.168.0.2';
mysql> CHANGE MASTER TO MASTER_USER = 'usuario_replicacion';
mysql> CHANGE MASTER TO MASTER_PASSWORD = 'pass_replicacion';
mysql> CHANGE MASTER TO MASTER_LOG_FILE = 'mysql-bin.000005';
mysql> CHANGE MASTER TO MASTER_LOG_POS = 98;
mysql> start slave;

Ahora el esclavo comenzará la replicación con el maestro. Quedándose a 0 segundos de él una vez copiado todo el log binario que le resta de lo sucedido hasta la fecha. Para comprobar que realmente está replicando, tendremos que ejecutar el siguiente comando en la consola de MySQL:

mysql> show slave status \G

Eso muestra:

*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.0.2
Master_User: usuario_replicacion
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000005
Read_Master_Log_Pos: 98
Relay_Log_File: esclavo-relay-bin.000001
Relay_Log_Pos: 98
Relay_Master_Log_File: mysql-bin.000005
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB: bbdd
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 98
Relay_Log_Space: 98
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
1 row in set (0.00 sec)

Lo importante es lo que sigue a Seconds_Behind_Master: porque es el valor que indica el retraso de este esclavo con respecto al maestro.

En definitiva y a modo de resumen:

1. Cambiar la configuración del maestro con las líneas:

server-id=1
log-bin=mysql-bin

2. Cambiar la configuración del esclavo:

server-id=2

3. Bloquear las tablas del maestro y hacer un dump:

mysql> LOCK ALL TABLES READ ONLY
mysql> SHOW MASTER STATUS
mysql> exit
joax@maestro> mysqldump bbdd > bbdd_dump_20071202.sql

4. Instalar la base de datos en el esclavo:

joax@esclavo> mysql bbdd < bbdd_dump_20071202.sql
mysql> CHANGE MASTER TO MASTER_HOST = '192.168.0.2';
mysql> CHANGE MASTER TO MASTER_USER = 'usuario_replicacion';
mysql> CHANGE MASTER TO MASTER_PASSWORD = 'pass_replicacion';
mysql> CHANGE MASTER TO MASTER_LOG_FILE = 'mysql-bin.000005';
mysql> CHANGE MASTER TO MASTER_LOG_POS = 98;
mysql> start slave;

En un cluster podremos incluir tantos esclavos como necesitemos. He llegado a ver clusteres de varias decenas de esclavos sobre el mismo maestro. Pero son puntos donde a lo mejor tienes que tomar una estrategia de particionado de la base de datos. Estrategia que veremos próximamente.

La escalabilidad, una asignatura pendiente

1 Dic

Desde hace varios meses, la escalabilidad está siendo mi única materia de estudio y aplicación. No paro de investigar, hacer y deshacer. Y digo deshacer porque una de las cosas más importantes que he aprendido de esta materia es que no se pueden leer blogs aleatoriamente y hacer lo que dicen.

Una vez estuve leyendo un blog de un americano que aseguraba que haciendo una configuración específica a MySQL se podría aumentar su eficencia en la concurrencia. Como no teníamos otra cosa que hacer, lo probamos. Claro, esto de probar las cosas está bien hasta que te pegas el castañazo. Más bien el trompazo. Porque cuando activamos esta nueva configuración, los esclavos de la base de datos empezaron a caer uno detrás de otro como moscas. Menos mal que sólo cambiamos esta configuración en unos cuantos por lo que el portal no sufrió consecuencias y seguía funcionando.

Pero aprendí desde ese momento que cuando alguien en internet habla de escalabilidad o de posibles ideas para solventar este problema tienes que tener claro o seguro que en realidad ha tenido experiencia en ese campo.

Otra anécdota que puedo contar es que en los inicios de tuenti, estábamos otro compañero y yo por la noche haciendo cambios varios sobre la estructura de datos. Hasta que nos topamos con la duda de si aplicar estos cambios a las tablas en el portal. Leyendo la documentación de MySQL 5.0, aseguraba que en un entorno maestro-esclavo hacer cambios en las tablas con ALTER no debiera afectar en absoluto al rendimiento del sistema puesto que el ALTER se realiza sobre una copia temporal de la tabla, por lo que las lecturas podrían seguir sucediendo en la misma tabla durante la operación. Por lo que tanto Kenny como yo decidimos que podríamos hacerlo sin problemas.

Ya podréis saber el resultado de esta acción por cómo estoy empezando esta frase. Si, casi desastre. El maestro comenzó a retener las escrituras sobre la tabla y de esta manera reteniendo las conexiones desde el PHP. Esto hizo que se sobrepasara el límite de conexiones que el servidor tenía previsto -y eso que lo aumentamos en mucho sabiendo que podría pasar… Esto formó una espiral de acontecimientos que nos obligó a cancelar la operación para que el portal no se cayera.

A lo largo de este tiempo, esta son las cosas que creo claves para tener una buena escalabilidad -que es imposible sin experiencia y conocimiento del sector donde te metes , por supuesto:

  • Las cosas tienen que ser muy simples: todo lo complicado no es escalable, y menos aquellas cosas que precisamente hacemos complicadas para que escalen. Puesto que la complejidad es el peor enemigo de la escalabilidad.
  • Investigación: A la hora de econtrarte con un problema de escalabilidad, probablemente, si no eres uno de los portales más grandes del mundo o con una cierta peculiaridad que no tiene nadie, alguien ha pasado ya por lo mismo que tú. Consulta los blogs, listas de desarrolladores y demás frecuentadas por las personas de otros sitios iguales al tuyo (pero más grandes).
  • Priorización: Es muy importante determinar qué cosas son las más importantes para centrarte en la escalabilidad de ellas. Perder demasiado el tiempo en algo que no es importante en tu portal podría mermar otra prioridad que sin embargo necesita ese tiempo.
  • Iteración constante en los cuellos de botella: Esta tiene su base en la Administración de Sistemas. Pero en realidad se puede aplicar a todo tipo de disciplina que necesita una escalabilidad. En producto nos econtramos contínuamente con cuellos de botella en el código que no pueden ser resueltos con más servidores…
  • Éxito como equipo: Tener en cuenta tus responsabilidades, asumirlas y ejecutarlas es vital para que otros miembros de tu equipo puedan hacer las suyas confiando que tu parte estará hecha. Esto hace que el equipo pueda afrontar los problemas de manera más efectiva.
  • Conocer tu plataforma: Tener una buena plataforma y conocerla son claves para poder escalarla. Si estás usando un framework que no conoces por dentro (ruby on rails) puedes encontrarte en una situación donde las propias librerías pueden no ser escalables.

Algunos de estos puntos vienen de leer este comentario en los blogs relacionados con Youtube.