Шардирование

В предыдущем уроке вы рассмотрели подход к горизонтальному масштабированию с использованием репликации и паттернов Read replica и Cache aside. В этом уроке узнаете больше про шардирование.

Шардирование и партиционирование

Партиционирование, или секционирование, — метод разделения больших объёмов данных на отдельные сегменты. Иногда шардирование называют партиционированием в целом, но на самом деле шардирование — это частный случай партиционирования. Чтобы разобраться в этом, разберём виды партиционирования.

Вертикальное партиционирование

Вертикальное партиционирование — это метод разделения одной большой таблицы на несколько меньших, которые физически хранятся отдельно.
Вертикальное партиционирование позволяет повысить производительность и доступность данных, поскольку операции выполняются над меньшим количеством данных. Например, можно разделить таблицу с данными о покупателях и их предпочтениях на две таблицы и тогда при выполнении запросов будут загружаться только необходимые столбцы.
Приведём пример, когда полезно шардирование. В какой-то учётной системе с большим количеством данных есть таблица «Х». Она имеет 110 500 атрибутов, которые лежат в одной строке. Как только разработчики замечают, что запросы стали выполняться в разы медленнее, они начинают разделять эту таблицу на более мелкие. Применяется вертикальное партиционирование.
💡 Вертикальное партиционирование делают в первую очередь при проблемах с производительностью. Этот способ поможет оптимизировать запросы, но не решит проблему с большим количеством данных.
При вертикальном партиционировании всё просто: достаточно придумать, что «отрезать» от таблицы, и перенести это в другую. С горизонтальным партиционированием сложнее.

Горизонтальное партиционирование

Горизонтальное партиционирование, шардирование, или сегментирование, — распределение данных по нескольким базам, чаще всего на отдельных физических серверах.
Шардирование предполагает разделение данных на группы по определённым критериям. В зависимости от критерия, по которому распределяются данные, выделяют методы шардирования, но о них немного позже.
В результате разделения данных каждый сегмент (шард) включает одни и те же столбцы, но разные строки информации.
☝ Благодаря шардированию можно разделить операции записи и чтения данных между разными серверами, за каждым из которых закреплена отдельная машина.
Приведём пример, когда полезно шардирование. Интернет-магазин, работающий по всей стране или даже в нескольких странах, не может концентрировать все данные в одном месте. Разработчики разносят данные по разным регионам. При этом остаётся возможность запросить данные в одном месте, если это необходимо. Это и есть горизонтальное партиционирование, или шардирование.
Вы познакомились с механизмом работы шардирования. Пора узнать про преимущества и ограничения этого метода масштабирования.

Преимущества и ограничения шардирования

Преимущества

Шардирование помогает:
  • Преодолеть технические ограничения Популярные продукты со временем достигают предела возможностей оборудования. Шардирование позволяет распределить данные по разным машинам, чтобы обеспечить потенциал для дальнейшего роста.
  • Повысить надёжность Если шарды базы данных расположены на разных серверах, отказ одного из них не приведёт к полной остановке работы. Если перестанет работать одна часть сайта или приложения, остальные продолжат функционировать.
  • Ускорить доступ к данным с простыми запросами Продукты с монолитной базой данных обычно не отличаются высокой производительностью, поскольку запросы конкурируют друг с другом. Шардирование помогает распределить нагрузку и увеличить объёмы и скорость обработки данных.

Ограничения

  • Сложность реализации Реализация шардирования сложна и сопряжена с риском ошибок при разделении данных. Это может привести к потере информации или повреждению хранилища.
  • Риск снижения эффективности разработки Из-за необходимости управлять данными из нескольких сегментов вместо единой точки входа эффективность команды разработчиков может снизиться. Например, расширить схему БД или расследовать какую-то проблему будет сильно сложнее: могут возникнуть сложности с поиском нужных данных или добавлением новых. Кроме того, необходимо поддерживать механизм шардирования — расходовать ресурсы не на разработку, а на эксплуатацию.
  • Неравномерность загрузки серверов Возможна несбалансированность данных, когда одни серверы оказываются загружены больше, чем другие. Это потребует повторного сегментирования и может вызвать простой серверов.
  • Снижение скорости обработки сложных запросов Сложные запросы, требующие обращения к нескольким шардам одновременно, могут привести к потере производительности и замедлению процесса получения данных по сравнению с обращением к одной таблице. Например, вам может потребоваться выборка по нескольким продуктам со всеми атрибутами. Но эти продукты настолько разные, что лежат в разных шардах, и обработка займёт очень много времени.

Задание 1

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

Задание 2

Выберите все верные утверждения о шардировании.
Шардирование за счёт распределения данных по разным серверам повышает отказоустойчивость.
Запросы перестают конкурировать между собой на одном сервере, что повышает доступность данных.
Шардирование позволяет распределить данные по разным машинам, обеспечивая потенциал для дальнейшего роста.
При шардировании повышается риск неравномерности загрузки мощностей серверов. Это будет зависеть от используемого метода шардирования — об этом далее в уроке.
Теперь разберём методы шардирования.

Методы шардирования

У шардирования есть множество методов — рассмотрим самые популярные.

Хэшированное шардирование

Хэшированное шардирование (англ. key based sharding) — это разделение данных на шарды на основе хэш-функции. Хэш-функция принимает входные данные и возвращает хэш-значение, которое определяет, в какой шард попадёт каждая запись данных. 
Этот алгоритм нельзя запустить в обратную сторону и получить исходное сообщение. Применение алгоритма к одному и тому же значению всегда даёт одинаковый результат.
Особенности алгоритма:
  • высокая производительность;
  • отсутствие единой точки отказа;
  • равномерное распределение данных;
  • затруднённый поиск данных.
Приведём пример хэшированного шардирования. Магазин содержит базу данных пользователей. Чтобы ослабить нагрузку на сервер, разработчики горизонтально делят её по шардам, используя хэш-функцию для определения шарда. В результате пользователи будут равномерно распределены по серверам.
☝ Применение алгоритма оптимально для приложений, в которых крайне важно равномерно распределить данные. Например, при хранении пользовательских сессий в веб-приложениях или товаров в магазине.

Диапазонное шардирование

Диапазонное шардирование (англ. range based sharding) — разделение данных на шарды на основе диапазона значений (chunk). Значения разделяются не с помощью функции, а по ключу или другим атрибутам. Например, товары стоимостью до 50₽ идут в первый шард, от 50₽ до 100₽ — во второй, свыше 100₽ — в третий. Каждому фрагменту присваивается диапазон на основе значений ключа сегментирования. Ключи сегментов, чьи значения близки друг к другу, чаще всего оказываются в одном диапазоне. Это упрощает выполнение целевых операций.
Особенности алгоритма:
  • лёгкая реализуемость;
  • быстрый поиск информации по сравнению с хэшированием;
  • дисбаланс базы данных.
☝ Подходит для данных временных рядов или последовательных данных, таких как журналы, события с временными метками, цены на товары и т. д.

Динамическое шардирование

Динамическое шардирование (англ. dynamic sharding) — автоматическое масштабирование хранилища в зависимости от текущей производительности и объёма данных. Такое шардирование очень гибкое, но требует сложной балансировки нагрузки, надёжного мониторинга и тщательно продуманной архитектуры базы данных. По этой причине динамическое шардирование популярно, но применяется не так часто, ведь его сложно реализовать. Глубоко погружаться в его алгоритмы мы не будем: для этого потребовался бы не один урок.
Динамическое шардирование обычно использует для определения местоположения записей внешний поисковый сервис. Это помогает решать проблемы, возникающие при динамическом сегментировании. Внешний поиск предоставляет полную информацию о том, в каком сегменте находятся данные, что позволяет перемещать пользователей по отдельности, а не большими группами, из одного сегмента в другой. Это помогает снизить нагрузку на перегруженные сегменты. При этом поисковый сервис становится единственным местом взаимодействия с системой и потенциальным источником сбоев.

Геошардинг

Геошардинг (англ. geo sharding) — это хранение в разных сегментах информации, относящейся к определённой географической зоне. Его можно комбинировать с другими методами шардирования, если это необходимо.
Такой подход оптимален для сервисов, которым важна локальность данных, например, для сетей доставки контента и мобильных приложений с учётом геолокации.
С основными методами шардирования вы познакомились — теперь выполните несколько заданий, чтобы лучше усвоить материал.

Задание 3

Какой из методов шардирования позволяет наиболее равномерно распределить данные?
Позволяет равномерно распределить данные при условии внимательного подхода к выбору функции шардирования.

Задание 4

Компания решила использовать динамическое шардирование для масштабирования данных. Через некоторое время разработчики заметили, что при высоких нагрузках система начала терять данные. Какая причина могла привести к такой проблеме?
Данная функция используется в другом методе — хэшированном шардировании.
Динамическое шардирование требует надёжной системы мониторинга и балансировки нагрузки. Недостатки в этих областях могут привести к потере данных при высоких нагрузках. После раскапывания проблемы обнаружили, что не заметили сбой в сервисе-локаторе.

Задание 5

Онлайн-кинотеатр активно развивался в последнее время. Каждую неделю появлялись десятки новых фильмов и сериалов и добавлялась новая функциональность. В течение последнего квартала участились жалобы от пользователей на замедление работы приложения.
Разработчики заметили, что база данных перегружена. Большое количество разнородных данных, которые собираются сложными запросами: многие пользователи находятся в разных странах и городах, все смотрят разное. Особенно высокая нагрузка на сервер по вечерам и в выходные дни.
Какой метод поможет улучшить работу сервиса?
Как временное решение — да. Но аудитория продолжит расти и база тоже, поэтому этого хватит ненадолго.
Если нагрузка связана с распределением трафика по регионам, то этот метод может решить проблему. А ещё лучше будет дополнить его хэшированным шардированием.
Мы рассказали о наиболее популярных вариантах шардирования. Для начала работы их достаточно.
Коротко параметры рассмотренных методов шардирования можно представить в таблице так.
Хэшированное шардированиеДиапазонное шардированиеДинамическое шардированиеГеошардинг
Риск потери данных⚡ Низкий — отсутствие единой точки отказа⚡Низкий🛑 Высокий⚡Низкий
Распределение данных⚡ Равномерное🛑 Неравномерное🛑Неравномерное🛑Неравномерное
Поиск данных🟠 Средней сложности⚡Лёгкий🛑 Сложный⚡Лёгкий
Реализуемость⚡Лёгкая⚡Лёгкая🛑 Сложная⚡Лёгкая
Масштабируемость хранилища⚡Высокая⚡Высокая⚡ Автоматическая🟠 Средняя
Геораспределение данных🛑 Отсутствует🛑 Отсутствует🟠 Возможно⚡Реализовано

Итоги

  • Одним из способов масштабирования является партиционирование — метод разделения больших объёмов данных на отдельные сегменты. Партиционирование бывает вертикальным, при котором данные делятся по столбцам. И горизонтальным, при котором данные по строкам разделяют и кладут в разные базы данных. Горизонтальное партиционирование называют шардированием.
  • Шардирование помогает преодолеть технические ограничения, повысить надёжность и ускорить доступ к данным с простыми запросами. При этом оно сложно реализуемо, снижает скорость обработки сложных запросов и сопряжено с риском снижения эффективности разработки и неравномерной загрузки серверов.
  • Существует много разных методов шардирования, из которых популярнее всего четыре: хэшированное, диапазонное, динамическое и геошардирование.
В следующем уроке вы узнаете о том, как на практике реализовать шардирование в Redis и MongoDB.

Что почитать по теме

Статья про паттерны и антипаттерны шардирования на Хабре