PHP: работа с реплицированными mysql-серверами

Появилась достаточно интересная задача: в наличии два реплицированных сервера mysql: master и slave. Изменения на сервере master копируются в slave. Необходимо правильно организовать работу с базой данных, чтобы для программиста ее использование осталось максимально прозрачным (например, текущие интерфейсы классов библиотеки Zend не изменились), а разные типы запросов попадали на разные сервера.

Имеется в виду, что изменения данных (например, update) должны вестись с сервером master, а выборка (например, select) с сервера slave.

Репликация сама по себе повышает доступность данных и увеличивает надежность их хранения.

masterslave PHP: работа с реплицированными mysql серверами php work

В php существует возможность работы с несколькими соединениями с базой путем определения их идентификаторов. Таким образом первое подходящее решение — замена стандартной функции mysql_query(string $query) более общей, с парсингом строки запроса.

Итак, создаем два подключения:

$master_db_server = mysql_connect(DB_HOST_MASTER, DB_USER_MASTER, DB_PASS_MASTER, true) or sqlErrorHandler(mysql_errno(), mysql_error(), mysql_stat(), __FILE__, __LINE__);
$slave_db_server = mysql_connect(DB_HOST_SLAVE, DB_USER_SLAVE, DB_PASS_SLAVE, true) or sqlErrorHandler(mysql_errno(), mysql_error(), mysql_stat(), __FILE__, __LINE__);

Соответственно дальше можно отправлять нужные запросы к нужному подключению, например:

mysql_query($query_line, $master_db_server);

При таком подходе программист обязан правильно организовать подключение к базе данных и использовать переопределенные функции.

Похожее решение реализовано в виде дополнительного класса к библиотеке Zend. Помимо распределения запросов между нужным количество серверов, возможно принудительное переключение на использование только Master или Slave-сервера.

Третьим возможным решением становится использование улучшенного mysql в php. Расширение mysqli позволяет использовать возможности MySQL версий 4.1 и выше. В них входит использование транзакций и поддержка реплицированных серверов. При этом работа с функциями mysqli не сильно отличается от работы со стандартным mysql:

<?php

/* Connect to a MySQL server */
$mysqli = new mysqli('localhost', 'user', 'password', 'world');

if (mysqli_connect_errno()) {
printf("Can't connect to MySQL Server. Errorcode: %s\n", mysqli_connect_error());
exit;
}

/* Send a query to the server */
if ($result = $mysqli->query('SELECT Name, Population FROM City ORDER BY Population DESC LIMIT 5')) {

print("Very large cities are:\n");

/* Fetch the results of the query */
while( $row = $result->fetch_assoc() ){
printf("%s (%s)\n", $row['Name'], $row['Population']);
}

/* Destroy the result set and free the memory used for it */
$result->close();
}
/* Close the connection */
$mysqli->close();
?>

Zend Framework также может использовать адаптер MySQLi, но мануал описывает нюансы в его использовании:

Итак, мы получили три пути решения для различных типов приложений. На мой взгляд наиболее рациональным является использование MySQLi адаптера в Zend Framework.

Rambler's Top100