Горизонтальное шардирование
Горизонтальное шардирование (англ. horizontal sharding) — это метод масштабирования баз данных, при котором одна логическая таблица (или коллекция) физически разбивается на несколько независимых частей, называемых шардами (shards). Каждый шард представляет собой отдельную базу данных, сервер или кластер, хранящий подмножество строк исходной таблицы. В отличие от вертикального шардирования, где разделение происходит по столбцам, горизонтальное шардирование распределяет данные по строкам, что позволяет увеличить пропускную способность системы за счёт параллельной обработки запросов на разных узлах.
История
Концепция шардирования возникла в конце 1990-х — начале 2000-х годов, когда рост интернет-сервисов (поисковые системы, социальные сети, электронная коммерция) привёл к необходимости обработки объёмов данных, превышающих возможности одного сервера. Первые реализации горизонтального шардирования были выполнены в рамках проектов распределённых баз данных, таких как Google Bigtable (2004) и Amazon Dynamo (2007). В 2009 году компания MongoDB внедрила автоматическое шардирование в свою документоориентированную СУБД, что сделало технологию доступной для широкого круга разработчиков. В 2010-х годах горизонтальное шардирование стало стандартной практикой в архитектурах микросервисов и облачных платформ (Amazon RDS, Google Cloud Spanner, Yandex Database, признанная в РФ российской разработкой).
Принцип работы
Горизонтальное шардирование основано на разделении строк таблицы по ключу шардирования (shard key) — столбцу или набору столбцов, значение которого определяет, в какой шард будет помещена запись. Ключ шардирования выбирается так, чтобы обеспечить равномерное распределение данных и минимизировать количество запросов, пересекающих границы шардов.
Основные этапы
- Определение ключа шардирования — выбор столбца с высокой кардинальностью (например, идентификатор пользователя, дата, географический регион).
- Разбиение данных — строки распределяются по шардам на основе значения ключа (например, по диапазону значений или хеш-функции).
- Маршрутизация запросов — приложение или промежуточный слой (прокси) определяет, к какому шарду обратиться, анализируя ключ в запросе.
- Обработка распределённых запросов — если запрос затрагивает несколько шардов, выполняется сборка результатов (merge) на стороне приложения или координатора.
Классификация
По способу распределения данных
- Диапазонное шардирование (range-based sharding) — строки распределяются по непрерывным диапазонам значений ключа (например, пользователи с ID от 1 до 1000 — шард 1, от 1001 до 2000 — шард 2). Простота реализации, но риск неравномерной нагрузки («горячие точки»), если данные в одном диапазоне запрашиваются чаще.
- Хеш-шардирование (hash-based sharding) — к значению ключа применяется хеш-функция, результат которой определяет номер шарда. Обеспечивает равномерное распределение, но усложняет запросы по диапазонам (например, поиск всех записей за месяц).
- Списочное шардирование (list-based sharding) — каждому шарду назначается список допустимых значений ключа (например, шард «Европа» — страны EU, шард «Азия» — страны Азии). Используется редко, в основном для географического разделения.
- Кольцевое шардирование (consistent hashing) — модификация хеш-шардирования, при которой шарды и ключи отображаются на виртуальное кольцо. При добавлении или удалении шарда перераспределяется только часть данных (используется в Cassandra, Amazon DynamoDB).
По способу управления
- Автоматическое шардирование — СУБД сама управляет разбиением и перемещением данных (например, MongoDB, Citus, Vitess). Требует минимального вмешательства администратора.
- Ручное шардирование — разработчик или администратор вручную определяет структуру шардов и логику маршрутизации (например, в PostgreSQL с использованием расширений или в приложении). Даёт больше контроля, но увеличивает сложность эксплуатации.
Преимущества
- Масштабируемость — возможность увеличивать ёмкость системы путём добавления новых серверов без остановки сервиса.
- Производительность — запросы обрабатываются параллельно на нескольких узлах, что снижает время ответа для операций чтения и записи.
- Отказоустойчивость — выход из строя одного шарда не приводит к потере всех данных (при условии репликации внутри шарда).
- Экономия ресурсов — позволяет использовать серверы среднего класса вместо одного дорогого суперкомпьютера.
Недостатки и ограничения
- Сложность запросов — операции JOIN, агрегации и транзакции, затрагивающие несколько шардов, требуют координации и снижают производительность.
- Неравномерная нагрузка — при неправильном выборе ключа шардирования одни шарды могут быть перегружены, а другие — простаивать.
- Управление схемой — изменение структуры таблицы (добавление столбцов, индексов) требует синхронизации на всех шардах.
- Трудности с резервным копированием — резервное копирование распределённой системы сложнее, чем для монолитной базы данных.
- Требования к сети — высокая задержка между шардами может снизить общую производительность.
Применение
Горизонтальное шардирование широко используется в системах, где требуется обработка больших объёмов данных (Big Data) и высокая доступность:
- Социальные сети — распределение пользователей, постов и сообщений по шардам (например, Twitter, VK).
- Электронная коммерция — каталоги товаров, заказы и транзакции (Amazon, Ozon).
- Игровые платформы — профили игроков, игровые сессии (Steam, World of Warcraft).
- Системы аналитики — хранение и обработка логов, событий (Elasticsearch, ClickHouse).
- Облачные сервисы — мультитенантные базы данных, где каждый клиент (tenant) хранится в отдельном шарде (SaaS-платформы).
Примеры реализации
- MongoDB — поддерживает автоматическое шардирование с использованием хеш-функции или диапазонов. Ключ шардирования задаётся при создании коллекции.
- PostgreSQL — для горизонтального шардирования используются расширения, такие как Citus (превращает PostgreSQL в распределённую СУБД) или pg_shard.
- MySQL — шардирование реализуется через кластеры (MySQL Cluster) или сторонние решения (Vitess, ProxySQL).
- Cassandra — использует кольцевое шардирование с consistent hashing, где данные распределяются по узлам автоматически.
- Yandex Database (YDB) — российская распределённая СУБД, поддерживающая горизонтальное шардирование с автоматическим перераспределением данных.
Критика
Основные претензии к горизонтальному шардированию связаны с его сложностью. В отличие от вертикального масштабирования (увеличение мощности одного сервера), шардирование требует перепроектирования архитектуры приложения, особенно в части обработки распределённых транзакций и обеспечения согласованности данных (CAP-теорема). Некоторые эксперты отмечают, что для многих проектов с умеренной нагрузкой (до 10-20 миллионов записей) горизонтальное шардирование избыточно, и достаточно репликации или кэширования.
Интересные факты
- Термин «шард» (англ. shard — осколок) впервые был использован в контексте баз данных в 1990-х годах в компании LiveJournal.
- В 2010 году компания Facebook (организация признана экстремистской и запрещена в РФ) разработала собственную систему шардирования для MySQL, которая обрабатывала более 1 миллиарда запросов в день.
- В распределённых системах часто используется комбинация шардирования и репликации: каждый шард реплицируется на несколько узлов для повышения отказоустойчивости.
Источники
- Kleppmann, M. (2017). Designing Data-Intensive Applications. O'Reilly Media.
- MongoDB Documentation. Sharding. mongodb.com/docs/manual/sharding/
- PostgreSQL Documentation. Citus: Distributed PostgreSQL. citusdata.com
- Amazon DynamoDB Documentation. Partitions and Data Distribution. docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.Partitions.html
- Yandex Database. Архитектура YDB. ydb.tech/docs/architecture
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →