Вертикальный шардинг

Ігор Грегорченко

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

Одной из техник масштабирования базы данных является разделение таблиц по разным серверам. В этом случае несколько таблиц будут находится на одном сервере, а остальные на другом. Тогда запросы к разным таблицам будут обрабатываться разными серверами базы данных. Это и называется вертикальным шардингом.

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

Подготовка шардинга

Для выделения таблицы на отдельный сервер необходимо выполнить несколько простых действий.

1. Отдельное соединение

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


$con = mysql_connect('10.10.0.1');

**$con_photos = mysql_connect(‘10.10.0.1’);**

#…

mysql_query(‘SELECT * FROM users …’, $con);

#…

mysql_query(‘SELECT * FROM photos …’, **$con_photos**);

## Дубликат соединения для выбранных таблиц

2. Создание копии

Далее необходимо создать полную копию выбранных таблиц на новом сервере. В простом случае можно использовать дамп и остановку всего сайта на период создания копии. Чтобы сделать это без паузы, следует воспользоваться репликацией. В этом случае на новом сервере настраивается реплика нужных таблиц. В качестве Мастера будет выступать старый сервер, а новый будет Слейвом.

3. Переключение соединения

После этого достаточно переключить соединение на новый сервер:

$con = mysql_connect('10.10.0.1');

$con_photos = mysql_connect(‘**10.10.0.2**’);

#…

## Теперь мы используем два разных соединения для разных таблиц

Если для создания копии использовалась репликация, ее необходимо остановить.

Работа из приложения

В приложении мы будем работать с разными соединениями для разных таблиц:


***$con*** = mysql_connect('10.10.0.1');

**$con_photos** = mysql_connect(‘10.10.0.2’);

#…

mysql_query(‘SELECT * FROM users …’, ***$con***);

#…

mysql_query(‘SELECT * FROM photos …’, **$con_photos**);

## используем разные соединения для соответствующих таблиц

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

JOIN’ы

Понятно, что JOIN двух таблиц на разных серверах сделать невозможно. Есть два варианта решения этой задачи.

Группы таблиц

Часто JOIN запросы имеют место только между какой-то группой таблиц, которые логически связаны друг с другом. Например таблицы, которые хранят данные о альбомах и фотографиях пользователей:

  • photos список фотографий, содержит album_id
  • albums список альбомов

В таком случае удобнее выносить на отдельный шард сразу всю группу этих таблиц. Это позволит использовать JOIN в рамках этой группы.

Выборка в приложении

В другом варианте, функциональность JOIN’a придется перенести на приложение. Например, такой запрос:
SELECT * FROM photos p JOIN albums a ON (a.id = p.album_id) WHERE a.user_id = 1
## Выбор всех фотографий пользователя 1

Если таблицы users и albums находятся на разных серверах, можно получить тот же результат так:

# ...

$q = mysql_query(‘SELECT * FROM albums WHERE user_id = 1’, $connection_albums);

$albums = mysql_fetch_all($q);

# получаем список ID альбомов пользователя

foreach ( $albums as $album ) $album_ids[] = $album[‘id’];

# выбираем все фотки для указанных альбомов

$q = mysql_query(‘SELECT * FROM photos WHERE **album_id IN (‘ . implode(‘,’, $album_ids) . ‘)**’, $connection_photos)

## Выполнение двух запросов вместо одного JOIN’a

Отказоустойчивость

Вероятность поломки серверов баз данных увеличивается с ростом их количества.

Для обеспечения отказоустойчивости необходимо резервировать сервера баз данных с помощью репликации. В таком случае, каждый шард будет иметь резервный сервер с копией данных.

В случае выхода из строя одного из шардов достаточно будет переключить его соединение на резервный сервер:

$con = mysql_connect('10.10.0.1');

—$con_photos = mysql_connect(‘10.10.0.2’);—

**$con_photos = mysql_connect(‘10.10.0.3’);**

#…

## Для использования резервного сервера достаточно будет изменить параметры соединения

Самое важное

Вертикальный шардинг – это удобный механизм масштабирования баз данных. Выделение логически связанных групп таблиц в отдельные шарды позволит даже использовать JOIN’ы. Обязательно используйте схему резервирования для повышения отказоустойчивости при шардинге. Начинайте с наиболее крупных и нагруженных таблиц. Для особо крупных таблиц применяйте методику горизонтального шардинга.

Останні статті

Что такое прокси-сервер: пояснение простыми словами, зачем нужны прокси

Прокси (proxy), или прокси-сервер — это программа-посредник, которая обеспечивает соединение между пользователем и интернет-ресурсом. Принцип…

21.11.2024

Что такое PWA приложение? Зачем необходимо прогрессивное веб-приложение

Согласитесь, было бы неплохо соединить в одно сайт и приложение для смартфона. Если вы еще…

19.11.2024

Как создать игру на телефоне: программирование с помощью конструктора

Повсеместное распространение смартфонов привело к огромному спросу на мобильные игры и приложения. Миллиарды пользователей гаджетов…

17.11.2024

Google Bard: эффективный аналог ChatGPT

В перечне популярных чат-ботов с искусственным интеллектом Google Bard (Gemini) еще не пользуется такой популярностью…

14.11.2024

Скрипт и программирование: что это такое простыми словами

Скрипт (англ. — сценарий), — это небольшая программа, как правило, для веб-интерфейса, выполняющая определенную задачу.…

12.11.2024

Дедлайн в разработке: что это такое простыми словами

Дедлайн (от англ. deadline — «крайний срок») — это конечная дата стачи проекта или задачи…

11.11.2024