Масштабирование баз данных — самая сложная задача во время роста проекта. 90% всех усилий обычно приходится как раз на работу, связанную с ростом объема данных и операций с ними. Классическая схема работы приложения с базой данных выглядит так:
Один сервер базы данных в какой-то момент перестает справляться с нагрузкой. В этот момент и следует применять описанные тут техники масштабирования.
Перед тем, как приступать к масштабированию, необходимо провести анализ медленных запросов и убедиться, что сервер MySQL настроен оптимально.
В основе масштабирования данных лежит тот же принцип, что и в основе масштабирования Web приложений. Это разделение данных на группы и выделение их на отдельные сервера. Существует две основные стратегии — репликация и шардинг.
Курсы от наших партнёров помогут вам повысить свой уровень знаний при работе с базами данных. IAMPM и Hillel ждут учеников чтобы передать им свой опыт.
Репликация позволяет создать полный дубликат базы данных. Так, вместо одного сервера у Вас их будет несколько:
Чаще всего используют схему master-slave:
Репликация позволяет использовать два или больше одинаковых серверов вместо одного. Операций чтения (SELECT) данных часто намного больше, чем операций изменения данных (INSERT/UPDATE). Поэтому, репликация позволяет разгрузить основной сервер за счет переноса операций чтения на слейв.
В приложении у Вас будет два соединения с базой данных. Одно — для мастера и одно для слейва:
$master = mysql_connect('10.10.0.1', 'root', 'pwd'); $slave = mysql_connect('10.10.0.2', 'root', 'pwd'); # какой-то код и все такое... $q = mysql_query('INSERT INTO users ...', $master); # еще какой-то код... $q = mysql_query('SELECT * FROM users WHERE...', $slave);
При выполнении запросов необходимо использовать соответствующее соединение
Репликация обычно поддерживается самой СУБД (например, MySQL) и настраивается независимо от приложения.
Читайте детальнее про настройку, использование и типы репликации данных на примере MySQL.
Следует отметить, что репликация сама по себе не очень удобный механизм масштабирования. Причиной тому — рассинхронизация данных и задержки в копировании с мастера на слейв. Зато это отличное средство для обеспечения отказоустойчивости. Вы всегда можете переключиться на слейв, если мастер ломается и наоборот. Чаще всего репликация используется совместно с шардингом именно из соображений надежности.
Шардинг (иногда шардирование) — это другая техника масштабирования работы с данными. Суть его в разделении (партиционирование) базы данных на отдельные части так, чтобы каждую из них можно было вынести на отдельный сервер. Этот процесс зависит от структуры Вашей базы данных и выполняется прямо в приложении в отличие от репликации:
Вертикальный шардинг — это выделение таблицы или группы таблиц на отдельный сервер. Например, в приложении есть такие таблицы:
Таблицу users Вы оставляете на одном сервере, а таблицы photos и albums переносите на другой. В таком случае в приложении Вам необходимо будет использовать соответствующее соединение для работы с каждой таблицей:
$users_connection = mysql_connect('10.10.0.1', 'root', 'pwd'); $photos_connection = mysql_connect('10.10.0.2', 'root', 'pwd'; # какой-то код и все такое... $q = mysql_query('SELECT * FROM users WHERE ...', $users_connection); # еще какой-то код... $q = mysql_query('SELECT * FROM photos WHERE...', $photos_connection); # еще какой-то код... $q = mysql_query('SELECT * FROM albums WHERE...', $photos_connection);
Для каждой таблицы или группы таблиц будет отдельное соединение
В отличие от репликации, мы используем разные соединения для любых операций, но с определенными таблицами. Читайте подробнее об использовании вертикального шардинга на практике.
Горизонтальный шардинг — это разделение одной таблицы на разные сервера. Это необходимо использовать для огромных таблиц, которые не умещаются на одном сервере. Разделение таблицы на куски делается по такому принципу:
Допустим, наше приложение работает с огромной таблицей, которая хранит фотографии пользователей. Мы подготовили два сервера (обычно они называются шардами) для этой таблицы. Для нечетных пользователей мы будем работать с первыми сервером, а для четных — со вторым. Таким образом, на каждом из серверов будет только часть всех данных о фотках пользователей. Это будет выглядеть так:
'2' => '10.10.0.2', ]; $user_id = $_SESSION['user_id']; # получение фотографий для пользователя $user_id $connection_num = $user_id % 2 == 0 ? 1 : 2; $connection = mysql_connect($photo_connections[$connection_num], 'root', 'pwd'); $q = mysql_query('SELECT * FROM photos WHREE user_id = ' . intval($user_id), $connection);
Перед обращением к таблице, мы выбираем нужное нам соединение
Результат вот этой операции $user_id % 2 будет остатком от деления на 2. Т.е. для четных чисел — 0, а для нечетных — 1.
Любая работа с таблицей photos теперь будет происходить только после получения нужного соединения на основе $user_id.
Горизонтальный шардинг — это очень мощный инструмент масштабирования данных. Но в то же время и очень нетривиальный. Читайте детально об использовании горизонтального шардинга на практике.
Не следует применять технику шардинга ко всем таблицам. Правильный подход — это поэтапный процесс разделения растущих таблиц. Следует задумываться о горизонтальном шардинге, когда количество записей в одной таблице переходит за пределы от нескольких десятков миллионов до сотен миллионов.
Шардинг и репликация часто используются совместно. В нашем примере, мы могли бы использовать по два сервера на каждый шард таблицы:
Тогда в приложении работа с этой табличкой может выглядеть так:
'master' => '10.10.0.10', 'slave' => '10.10.0.11', ], '2' => [ 'master' => '10.10.0.20', 'slave' => '10.10.0.21', ], ]; $user_id = $_SESSION['user_id']; # Читаем данные со слейвов $connection_num = $user_id % 2 == 0 ? 1 : 2; $connection = mysql_connect($photo_connections[$connection_num]['slave'], 'root', 'pwd'); $q = mysql_query('SELECT * FROM photos WHREE user_id = ' . intval($user_id), $connection); # какой-то код... # Изменение данных происходит на мастерах $photo_id = 7; $connection_num = $user_id % 2 == 0 ? 1 : 2; $connection = mysql_connect($photo_connections[$connection_num]['master'], 'root', 'pwd'); $q = mysql_query('UPDATE photos SET views = views + 1 WHREE photo_id = ' . intval($photo_id), $connection);
Читаем данные со слейвов, а записываем на мастер-сервера
Такая схема часто используется не для масштабирования, а для обеспечения отказоустойчивости. Так, при выходе из строя одного из серверов шарда, всегда будет запасной.
Следует отметить, что большинство [p165 Key-value баз данных] поддерживает шардинг на уровне платформы. Например, Memcache. В таком случае, Вы просто указываете набор серверов для соединения, а платформа сделает все остальное:
$m->addServer('10.5.0.2'); $m->addServer('10.5.0.3'); ... $m->get('user1')
Мемкеш сам умеет определять нужный сервер для каждого ключа
Шардинг и репликация — это популярные и мощные техники масштабирования систем работы с данными. Несмотря на примеры для MySQL, эти подходы универсальны и могут применяться для любой технологии. Получить навыки для работы с базами данных на можно на курсах наших партнеров Hillel и IAMPM.
Помните, процесс масштабирования данных — это архитектурное решение, оно не связано с конкретной технологией. Не делайте ошибок наших отцов — не переезжайте с известной Вам технологии на новую из-за поддержки или не поддержки шардинга. Проблемы обычно связаны с архитектурой, а не конкретной базой данных.
Этот текст был написан несколько лет назад. С тех пор упомянутые здесь инструменты и софт могли получить обновления. Пожалуйста, проверяйте их актуальность.
Прокси (proxy), или прокси-сервер — это программа-посредник, которая обеспечивает соединение между пользователем и интернет-ресурсом. Принцип…
Согласитесь, было бы неплохо соединить в одно сайт и приложение для смартфона. Если вы еще…
Повсеместное распространение смартфонов привело к огромному спросу на мобильные игры и приложения. Миллиарды пользователей гаджетов…
В перечне популярных чат-ботов с искусственным интеллектом Google Bard (Gemini) еще не пользуется такой популярностью…
Скрипт (англ. — сценарий), — это небольшая программа, как правило, для веб-интерфейса, выполняющая определенную задачу.…
Дедлайн (от англ. deadline — «крайний срок») — это конечная дата стачи проекта или задачи…