Главный вопрос перед шардированием: получится ли разделить работу вместе с данными? База может занимать много места, но почти вся активность приходится на небольшой участок. Если этот участок целиком уедет на один новый сервер, остальные узлы не спасут положение. Компания купит распределённую систему с прежним узким местом.
При шардировании разные части набора данных размещаются на разных узлах. Приложение или инфраструктура выбирает, к какой части направить запрос. Это позволяет распределять хранение и обработку, если правило разделения соответствует тому, как продукт использует данные. Сам выбор этого правила зачастую важнее покупки серверов.
Три похожих слова с разными последствиями
Репликация создаёт копии данных. Шардирование делит набор на части. Партиционирование таблицы, например по месяцам, может облегчить работу с историей внутри одной базы, но не обязательно распределяет вычисления между самостоятельными серверами. Эти подходы можно сочетать, однако один не является заменой остальных.
Сам шард тоже может состоять из основного узла и реплик. Несколько шардов не означают автоматически несколько независимых и защищённых от аварий частей: для доступности ещё нужны резервирование, маршрутизация и проверенное переключение. В описании шардирования MongoDB эти компоненты показаны отдельно.
Прежде чем выбирать архитектуру, нужно установить ограничение: память, объём хранения, скорость записи, дорогие выборки или конкуренция за одни и те же записи. Для чтения иногда хватает индекса или реплики. Для архивной истории — изменения срока хранения и партиционирования. Блокировку одной популярной записи добавлением пустых шардов не устранить.
Удобный ключ может оказаться неравномерным
Представим сервис для нескольких компаний. Разделить данные по идентификатору организации удобно: её пользователи, обращения и документы остаются рядом. Обычный экран обращается к одному шарду. Но среди клиентов появляется крупная компания, которая создаёт больше работы, чем остальные вместе. Равное число организаций на каждом узле ничего не говорит о равенстве нагрузки.
Хеширование ключа помогает распределять разные значения по диапазону. Оно не разделит само по себе работу одного огромного клиента, если все его записи имеют один и тот же ключ организации. Потребуется другое решение: выделенный шард, более мелкая единица разделения или составной ключ. У каждого варианта будут последствия для запросов.
Разделение по времени тоже выглядит естественно. Старые данные уходят в старые диапазоны, новые — в свежие. Однако при монотонно растущем ключе поток новых записей может концентрироваться в одном диапазоне. Дополнительные узлы для истории не разгрузят текущий приём данных. Это один из рисков, отмеченных в рекомендациях по выбору ключа.
Проверять нужно распределение операций, а не только гигабайтов. Два одинаковых по размеру шарда могут обслуживать совершенно разное число запросов. Средняя загрузка всего кластера скроет перегрузку одного из них. Для выбора пригодятся реальные профили клиентов, частота изменений и наиболее тяжёлые операции.
Что случится с запросом, которому нужны все данные
Пока запрос содержит подходящий ключ, его можно направить адресно. Общий поиск или сводный отчёт может потребовать обращения к нескольким шардам и объединения результатов. Появляются дополнительные задержки, передача данных и зависимость от медленного участника. Увеличение числа узлов не гарантирует, что такой запрос ускорится.
Снова возьмём компании-клиенты. Их внутренние экраны прекрасно работают с разделением по организации. Но отделу продаж вашей компании нужен общий список просроченных договоров. Для него придётся выбрать отдельный путь: сквозной запрос, подготовленное представление или аналитическое хранилище. Допустимая свежесть отчёта определит, какие варианты подходят.
С изменениями сложнее. Операция, затрагивающая несколько шардов, может потребовать распределённой транзакции, если выбранная СУБД её поддерживает. В другом случае понадобится явный процесс согласования. Не следует молча заменять требование «всё или ничего» обещанием, что данные когда-нибудь сойдутся. Отдельно проверяются уникальность идентификаторов и другие ограничения: область действия гарантии должна совпадать с бизнес-требованием.
Это повод пересмотреть границы данных, а не запрет на распределение. Если большую часть критических операций удаётся оставить внутри одного шарда, сложных пересечений будет меньше. Но редкая операция между клиентами, например перенос подразделения при реорганизации, всё равно должна иметь предусмотренный сценарий.
Перемещение данных станет штатной работой
После запуска клиенты растут неравномерно. Нужно уметь перемещать данные и менять маршрутизацию, пока приложение продолжает принимать изменения. Простого копирования таблиц недостаточно: важно определить, где в каждый момент разрешена запись, как догоняются изменения и когда новый адрес считается действующим.
Готовые механизмы СУБД могут выполнить значительную часть этой работы. Команде всё равно нужны запас мощности, наблюдение за задержками и проверка результата. Перераспределение конкурирует за ресурсы с обычной нагрузкой. Откладывать его до полностью заполненного диска — плохой план эксплуатации.
Резервное копирование тоже придётся проверить заново. Наличие копии каждого шарда ещё не доказывает, что из них получится восстановить согласованное состояние системы. Особенно если процессы пересекают границы. Нужны понятные точки восстановления и практическая проверка данных после возврата приложения к работе.
Начинать подготовку стоит до аварии, когда измеренная динамика нагрузки показывает приближение к пределу и оставляет время на миграцию. Доказывать необходимость шардирования остановкой бизнеса не требуется. Но прогноз должен опираться на наблюдаемые операции и ресурсы, а не на слово «миллиарды» в презентации.
Перед решением полезны три испытания на представительной копии нагрузки: большой клиент резко увеличивает активность, общий отчёт работает одновременно с записью, данные одного клиента переезжают на другой узел. Если команда может показать корректный результат, время выполнения и способ восстановления при прерывании каждого сценария, предложение о шардировании уже можно обсуждать как инженерный план.