Партиционирование данных

После определенного объема данных становится технически и экономически целесообразнее масштабировать хранилище горизонтально, добавляя новые сервера, так как вертикальное масштабирование становится крайне дорогостоящим. В таких случаях, для повышения производительности, доступности данных и балансировки нагрузки применяется механизм партиционирования. Партиционированием данных называют механизм разделения больших массивов данных (обычно, в базах данных) на меньшие части. Данные всей БД целиком, или данные таблиц распределяются на нескольких серверах, либо специфическим образом на одном.

Виды партиционирования

Выделяют 3 вида партиционирования:

  • Вертикальное
    Данные разбиваются таким образом, чтобы таблицы, которые относятся к определенному домену, находились на выделенных серверах. Например, если мы создаем сайт медицинских услуг, то данные о врачах и лекарствах будут храниться на одном сервере, а данные о пациентах и болезнях – на другом.
    Этот подход крайне понятен в работе, но мы можем столкнуться с ситуацией, когда нам понадобиться применять дополнительное партиционирование, так как мы, например, не сможем хранить данные о 500 миллионах исследованиях на одном сервере.
  • Горизонтальное
    Его также часто называют шардированием данных. В этом случае мы распределяем записи одного типа в разных таблицах. Например, мы храним все исследования сделанные в США в одной таблице, а исследования в Китае – в другой. Т.е. данные делятся на диапазоны и хранятся отдельно.
    Основной сложностью данного подхода является корректный выбор критерия для распределения данных по диапазонам. В противном случае мы получим дисбаланс данных, и определенные запросы будут выполняться крайне долго.
  • Основанное на поисковом сервисе
    Как видно из названия, этот вид партиционирования предполагает наличие отдельного сервиса за пределами БД, который знает наш подход к распределению данных и сам определяет, в какую партицию записывать новые данные.

Критерии партиционирования

  • Раунд-робин
    Этот простой подход гарантирует равномерное распределение данных. У нас есть заданные количество партиций N и каждая новая запись M записывается в партицию по формуле M % N.
  • Хэш-код
    Данный подход заключается в том, что мы вычисляем хэш-код ключа (поле или набор полей, на основании которого мы разделяем данные) и вычисляем сервер по формуле HASH % N, где N – количество серверов. При использовании данного подхода стоит учитывать тот факт, что при добавлении новых серверов приведет к изменению вычисления позиции новых элементов и нам понадобится перераспределение данных. Это означает, что какое-то время данные могут быть недоступны.
  • По значению
    Этот подход предполагает “закрепление” определенных значений записи за указанными партициями. Например, все пользователи, чьи профессии входят в список Software Engineer, QA, AQA, Designer будут записываться в партицию для IT.

Все виды партиционирования, указанные выше, могут быть комбинированы.

Ключевые проблемы партиционирования данных

  • Перераспределение
    Мы часто можем столкнуться с необходимостью изменения подхода к партиционированию (слишком частые обращения к данным из определенной партиции, слишком много данных записывается в партицию, при распределении по значению и т.д.)
    В этих случаях, нам приходится создавать новые партиции и перераспределять данные в них, что почти всегда приводит к недоступности данных на определенное время.
  • Денормализация
    Очень часто при создании партиций упускается из внимания необходимость объединения данных из разных партиций при запросе. Например, JOIN, при работе с большими объемами данных имеет не самую высокую производительность даже при работе с одной БД, а при распределении данных на нескольких машинах – эта ситуация усугубляется. Для решения этой задачи часто прибегают к денормализации БД, что несет абсолютно понятные риски и невозможность использовать привычные механизмы БД и решать задачи констрейнтов на уровне приложения.