Рубрика:
Разработка /
Масштабирование
|
Facebook
Мой мир
Вконтакте
Одноклассники
Google+
|
АЛЕКСАНДР КАЛЕНДАРЕВ, AD-1, ведущий программист, akalend@mail.ru
Еще раз про шардинг
Проблема масштабирования БД – одна из самых обсуждаемых проблем современных архитектур информационных систем. Разберем примеры горизонтального масштабирования MySQL для разных случаев и рассмотрим типовые ошибки
Определимся с терминологией
Масштабирование БД – это возможность БД увеличивать объем хранимой информации при неизменных характеристиках доступа к данным. Масштабирование бывает вертикальным, когда увеличение происходит за счет аппаратных средств (увеличение памяти, количество и объем дисковых накопителей), и горизонтальным – за счет увеличения количества таблиц, баз и серверов. В данной статье как раз и будем его рассматривать.
Одна из техник масштабирования – это партицирование таблиц. Партицирование – это разбиение таблиц, содержащих большое количество записей, на логические части по некоторым критериям. В MySQL существуют встроенные средства партицирования. Однако это выходит за рамки данной статьи.
Шардингом называется прием, который позволяет распределять данные между разными логическими и физическими серверами БД. Так, одна такая логическая часть данных будет называться шардой.
Следует заметить, что на одном физическом сервере можно поднять два экземпляра БД [1]. Обычно это используется для взаимного дублирования данных, чтоб поддерживать высокую доступность путем горячего резервирования сиспользованием так называемой перекрестной схемы: на одном сервере запущены мастер шарды 1 и слейв шарды 2, а на втором сервере запущены мастер шарды 2 и слейв шарды 1.
Данные между серверами распределяют на основе некоторого алгоритма или стратегии. Стратегия шардинга – алгоритм распределения записей по разным физическим таблицам. Например, может быть такой алгоритм распределения записей: первые 1000 записей пишем в таблицу 1, следующие 1000 – в таблицу 2 и т.д., пока место не закончится... Или такой: первую запись пишем в таблицу 1. вторую – в таблицу 2, третью – в таблицу 3… После записи в последнею таблицу снова пишем в таблицу 1.
Само распределение записей по разным шардам можно осуществлять по разным полям таблицы, поэтому введем такое понятие, как критерий шардинга – это функция или правило, на основании которого принимают решение к отнесению записи в ту или иную таблицу (шарду).
Ключом шардинга является индексируемое поле (ключ) в соответствии с критерием шардинга. Например, для соцсети критерием шардинга может быть id профиля пользователя. Он же и будет ключом шардинга.
Существуют некоторые типовые стратегии шардинга:
Линейная стратегия
Линейная стратегия – это поочередное заполнение таблиц данных, увеличение до определенного уровня, например 1 млн записей, сначала в одной таблице, потом заполнение 1 млн записей таблицы на другой шарде, затем на следующей, потом снова заполнение новой таблицы на первой шарде. Таким образом, первый миллион записей будет находиться в шарде 0, второй – в шарде 1, третий – в шарде 2.
Вычислить номер шарды можно по формуле:
(1)
где:
- intval() – выделение целой части;
- N – текущий номер записи;
- Counttab – количество записей в заполненной таблице;
- CountShard – общее количество шард;
- % – операция остаток от деления.
Циклическая стратегия
Циклическаяя стратегия – это поочередное заполнение сразу всех таблиц данных: таблица 1, таблица 2 … таблица NshardCount.
Вычислить номер шарды можно по формуле:
(2)
Если при использовании линейной стратегии мы имеем ограниченный размер каждой таблицы, то при использовании циклической данные будут заполняться безразмерно, пока не закончится дисковое пространство.
Когда я отвечал за сервис обмена сообщениями (мессенджер) в одной службе знакомств, то там использовалась именно такая система шардинга. В результате чего за четыре года все серверы БД оказались переполненными. Я ради эксперимента запустил запрос: SELECT count(*) … , чтоб приблизительно оценить объем шарды, но мне пришлось его сбросить минут через пять, так как нехорошо такими экспериментами нагружать боевые серверы.
При выборе стратегии шардинга необходимо проанализировать периодический прирост данных и продумать варианты возможного дальнейшего масштабирования.
Геостратегия
Данная стратегия предполагает деление записи по шардам по некоторому ключу. На первом сервере данные по Африке, на втором – по Европе, на третьем – Северная Америка и т.д. Очевидно, она использовалась в службе учета геоданных, раз получила такое название.
Например, такая стратегия используется в одной международной службе знакомств: на одном сервере содержится поисковый индекс жителей Москвы и Подмосковья, на другом – остальные города России, на третьем – города Европы иСеверной Америки, на четвертом – Южной Америки.
Реализацию этой стратеги мы не будем рассматривать в данной статье, но вы можете это сделать самостоятельно, так как в ней нет ничего сложного.
Создание таблиц
При использовании линейной стратегии для MySQL можно использовать поле типа AUTOINCREMENT, так как вторая таблица начинается с записи номер:
(3)
где Ntab – номер таблицы, который вычисляется по формуле (2).
Ее создание осуществляется с использованием следующего оператора:
CREATE TABLE tab_name_Ntab (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
…. /* прочие данные*/
PRIMARY KEY (`id`),
… /* прочие ключи */
) AUTO_INCREMENT= Nfirst /* вписываем конкретное число*/
При реализации циклической стратегии все гораздо проще. На каждую шарду по одной такой таблице. Все таблицы создаются одинаковым SQL-запросом.
Ближе к практике
Выше было описано много скучной теории, но для надежной эксплуатации надо хоть немного знать, как и что устроено, и изредка залезать под капот своего автомобиля. Я реализовал относительно несложный PHP-пакет MySQLShard [2], который в этом нам поможет.
В пакете имеются две основные сущности:
- класс MysqlShard [src/adapters/mysqlshard.php], который формирует запросы и осуществляет доступ к БД,
- и набор разных стратегий, являющихся потомками класса AbstractStrategy [src/strategy].
Статью целиком читайте в журнале «Системный администратор», №09 за 2016 г. на страницах 75-79.
PDF-версию данного номера можно приобрести в нашем магазине.
- Описание запуска нескольких экземпляров MySQL на одном физическом сервере – http://dev.mysql.com/doc/refman/5.7/en/multiple-servers.html.
- Пакет mysql_shard – https://github.com/akalend/mysql_shard.
- Описание работы с докер-контейнерами – http://docs.docker.com.
Facebook
Мой мир
Вконтакте
Одноклассники
Google+
|