En el mundo del desarrollo de aplicaciones, la gestión eficiente de bases de datos es esencial para garantizar el rendimiento y la escalabilidad. Una solución popular es el uso de un modelo Master-Slave, donde las operaciones de escritura y lectura se separan para distribuir la carga entre varios servidores. En este artículo, exploraremos cómo implementar esta estrategia en Laravel 11 y cómo configurar contenedores Docker para establecer una réplica Master-Slave con MySQL 8.

¿Qué es un modelo Master-Slave y por qué usarlo?

El modelo Master-Slave es una arquitectura de bases de datos en la que:
• Master: Maneja todas las operaciones de escritura (INSERT, UPDATE, DELETE).
• Slave(s): Manejan las operaciones de lectura (SELECT).

Beneficios del modelo Master-Slave

  1. Mejor rendimiento: • Las consultas de lectura se distribuyen entre múltiples servidores Slave, reduciendo la carga en el servidor Master.
  2. Alta disponibilidad:
    • Si un Slave falla, las operaciones de lectura pueden redirigirse a otros servidores.
  3. Escalabilidad:
    • Puedes agregar más servidores Slave según crezca la demanda de consultas de lectura.
  4. Optimización de recursos:
    • Las operaciones de escritura no compiten directamente con las de lectura, lo que mejora la eficiencia.

Implementación del modelo Master-Slave en Laravel 11

Laravel facilita el manejo de múltiples conexiones de bases de datos con su configuración integrada de lectura/escritura. Sigue estos pasos para configurar un entorno Master-Slave:

Configuración en config/database.php

Define las conexiones Master y Slave en el archivo de configuración:

'mysql' => [
    'driver' => 'mysql',
    'url' => env('DATABASE_URL'),
    'host' => env('DB_HOST', '127.0.0.1'),
    'port' => env('DB_PORT', '3306'),
    'database' => env('DB_DATABASE', 'forge'),
    'username' => env('DB_USERNAME', 'forge'),
    'password' => env('DB_PASSWORD', ''),
    'charset' => 'utf8mb4',
    'collation' => 'utf8mb4_unicode_ci',
    'prefix' => '',
    'strict' => true,
    'engine' => null,

    // Configuración Master-Slave
    'read' => [
        'host' => [
            env('DB_SLAVE1_HOST', '127.0.0.1'),
            env('DB_SLAVE2_HOST', '127.0.0.1'),
        ],
    ],
    'write' => [
        'host' => [
            env('DB_MASTER_HOST', '127.0.0.1'),
        ],
    ],

    'sticky' => true, // Mantiene la conexión al Master tras una escritura
],

Variables de entorno

Configura las direcciones de los servidores en el archivo .env:

DB_MASTER_HOST=master-db-host
DB_SLAVE1_HOST=slave1-db-host
DB_SLAVE2_HOST=slave2-db-host
DB_PORT=3306
DB_DATABASE=mydatabase
DB_USERNAME=myuser
DB_PASSWORD=mypassword

Laravel dirige automáticamente las consultas

Laravel separa las operaciones de escritura y lectura:
• Operaciones como INSERT, UPDATE, y DELETE se dirigen al servidor Master.
• Consultas SELECT se dirigen a los servidores Slave.

Por ejemplo:

// Operación de lectura (Slave)
$users = User::all();

// Operación de escritura (Master)
$user = User::find(1);
$user->name = ‘Nuevo Nombre’;
$user->save();

Configuración de MySQL Master-Slave con Docker

docker-compose.yml

Crea un archivo Docker Compose que defina los servicios Master y Slave:

version: '3.8'

services:
  mysql-master:
    image: mysql:8.0
    container_name: mysql-master
    environment:
      MYSQL_ROOT_PASSWORD: master_root_password
      MYSQL_REPLICATION_USER: replicator
      MYSQL_REPLICATION_PASSWORD: replication_password
      MYSQL_DATABASE: mydatabase
    ports:
      - "3306:3306"
    volumes:
      - master_data:/var/lib/mysql
      - ./master.cnf:/etc/mysql/conf.d/master.cnf
    networks:
      - mysql-network

  mysql-slave:
    image: mysql:8.0
    container_name: mysql-slave
    environment:
      MYSQL_ROOT_PASSWORD: slave_root_password
      MYSQL_REPLICATION_USER: replicator
      MYSQL_REPLICATION_PASSWORD: replication_password
    ports:
      - "3307:3306"
    volumes:
      - slave_data:/var/lib/mysql
      - ./slave.cnf:/etc/mysql/conf.d/slave.cnf
    networks:
      - mysql-network
    depends_on:
      - mysql-master

volumes:
  master_data:
  slave_data:

networks:
  mysql-network:

Configuración de MySQL

Crea los archivos de configuración para Master y Slave:

master.cnf

[mysqld]
server-id=1
log_bin=/var/log/mysql/mysql-bin.log
binlog_do_db=mydatabase

slave.cnf

[mysqld]
server-id=2
relay-log=/var/log/mysql/mysql-relay-bin.log
log_bin=/var/log/mysql/mysql-bin.log
read_only=1

Levantar los contenedores

Ejecuta los contenedores:

docker-compose up -d

Configuración de replicación

•   En el Master:
CREATE USER 'replicator'@'%' IDENTIFIED BY 'replication_password';
GRANT REPLICATION SLAVE ON *.* TO 'replicator'@'%';
FLUSH PRIVILEGES;
SHOW MASTER STATUS;

• En el Slave:

CHANGE REPLICATION SOURCE TO
    SOURCE_HOST='mysql-master',
    SOURCE_USER='replicator',
    SOURCE_PASSWORD='replication_password',
    SOURCE_LOG_FILE='mysql-bin.000001',
    SOURCE_LOG_POS=4;
START REPLICA;
SHOW REPLICA STATUS\G;

Conclusión

La combinación de Laravel 11 con una configuración de bases de datos Master-Slave proporciona una solución escalable y de alto rendimiento para aplicaciones modernas. Al aprovechar Docker para gestionar contenedores, puedes configurar rápidamente entornos replicados que aseguren la disponibilidad y eficiencia de tu aplicación.

Adoptar esta estrategia puede ser crucial para proyectos de gran escala, permitiendo que las aplicaciones soporten más usuarios y realicen operaciones de manera más eficiente. Si aún no lo has probado, este es el momento perfecto para implementar la replicación Master-Slave en tu flujo de trabajo con Laravel.

Categories:

Comments are closed