Particionamiento y fragmentación

La agrupación (clustering) de bases de datos se realiza por varias razones. Los clúster pueden mejorar la disponibilidad, la tolerancia a fallos, e incrementar el rendimiento aplicando un enfoque de "divide y vencerás", ya que el trabajo se distribuye en varias máquinas. La agrupación (clustering) a veces se combina con particionamiento y fragmentación para dividir aún más una tarea compleja grande en unidades más pequeñas y manejables.

El complemento mysqlnd_ms pretende dar soporte a una gran variedad de clústeres de bases de datos de MySQL. Algunos sabores de clúster de bases de datos de MySQL poseen métodos internos para el particionamiento y la fragmentacion, los cuales podrían ser transparentes de usar. El complemetno admite los dos enfoques más comunes: filtración de tabla de Replicación de MySQL, y la fragmentación (particionamiento basada en aplicación).

La Replicación de MySQL admite el particionamiento como filtros que permiten crear esclavos que replican todas las bases de datos o específicas del maestro, o tablas. Es entonces responsabilidad de la aplicación elegir un esclavo según las reglas de los filtros. Se puede usar el filtro node_groups de mysqlnd_ms para dar soporte manual a esto, o usar el filtro de tablas experimental.

El particionamiento manual o fragmentación está soportado a través del filtro de agrupación de nodos, y de las sugerencias SQL a partir de 1.5.0. El filtro node_groups permite asignar un nombre simbólico a un grupo de servidores maestros y esclavos. En el ejemplo, el maestro master_0 y slave_0 forman un grupo con el nombre de Partition_A. Es su responsabilidad decidir lo que haga un grupo. Por ejemplo, se podrían usar grupos de nodos para la fragmentación, y usar los nombres de grupos para direccionar fragmentos como Shard_A_Range_0_100.

Ejemplo #1 Clúster de grupos de nodos

{
  "myapp": {
       "master": {
            "master_0": {
                "host": "localhost",
                "socket": "\/tmp\/mysql.sock"
            }
        },
        "slave": {
            "slave_0": {
                "host": "simulate_slave_failure",
                "port": "0"
            },
            "slave_1": {
                "host": "127.0.0.1",
                "port": 3311
            }
        },
        "filters": {
            "node_groups": {
                "Partition_A" : {
                    "master": ["master_0"],
                    "slave": ["slave_0"]
                }
            },
           "roundrobin": []
        }
    }
}

Ejemplo #2 Particionamiento manual usando sugerencias SQL

<?php
function select($mysqli$msj$sugerencia '')
{
    
/* Nota: prueba débil, dos conexiones a dos servidores podrían tener el mismo id de hilo */
    
$sql sprintf("SELECT CONNECTION_ID() AS _thread, '%s' AS _hint FROM DUAL"$msj);
    if (
$sugerencia) {
        
$sql $sugerencia $sql;
    }
    if (!(
$res $mysqli->query($sql))) {
        
printf("[%d] %s"$mysqli->errno$mysqli->error);
        return 
false;
    }
    
$fila =  $res->fetch_assoc();
    
printf("%d - %s - %s\n"$fila['_thread'], $fila['_hint'], $sql);
    return 
true;
}

$mysqli = new mysqli("myapp""usuario""contraseña""base_datos");
if (!
$mysqli) {
    
/* Por supuesto, su manejo de errores es mejor... */
    
die(sprintf("[%d] %s\n"mysqli_connect_errno(), mysqli_connect_error()));
}

/* Permitir siempre esclavos */
select($mysqli"slave_0");
select($mysqli"slave_1");

/* solamente permtir los servidores del grupo de nodos "Partition_A" */
select($mysqli"slave_1""/*Partition_A*/");
select($mysqli"slave_1""/*Partition_A*/");
?>
6804 - slave_0 - SELECT CONNECTION_ID() AS _thread, 'slave1' AS _hint FROM DUAL
2442 - slave_1 - SELECT CONNECTION_ID() AS _thread, 'slave2' AS _hint FROM DUAL
6804 - slave_0 - /*Partition_A*/SELECT CONNECTION_ID() AS _thread, 'slave1' AS _hint FROM DUAL
6804 - slave_0 - /*Partition_A*/SELECT CONNECTION_ID() AS _thread, 'slave1' AS _hint FROM DUAL

Por omisión, el complemento usará todos los servidores maestros y esclavos configurados para la ejecución de consultas. Pero si una consulta comienza con una sugerencia SQL como /*node_group*/, el complemento considerará únicamente los servidores enumerados en node_group para la ejecución de consultas. Así, las consultas SELECT prefijadas con /*Partition_A*/ úncamente serán ejecutadas en slave_0.