digital-garden/_inbox/Шардирование в БД.md

98 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
aliases:
- Шардинг
tags:
- зрелость/🌱
date:
- - 2024-03-12
zero-link:
- "[[00 HighLoad]]"
- "[[00 Базы Данных]]"
parents:
linked:
- "[[Партиционирование в БД]]"
---
## Тезисы
- Один из вариантов горизонтального масштабирования данных, но не БД.
- Данные разбиваются на части. В отличии от [партиционирования](Партиционирование%20в%20БД.md) эти части размещаются на разных серверах.
- Не является [репликацией](_inbox/Репликация.md) и [партиционированием](Партиционирование%20в%20БД.md). Но на каждом шарде можно применить партицирование.
- ==Шардирование последняя мера по улучшению производительности.==
***
Шардирование — это метод разделения и распределения больших объёмов данных по разным базам данных или узлам в рамках одной распределённой системы, чтобы облегчить их управление, обеспечить масштабируемость и повысить производительность. Каждая часть данных, или "шард", функционирует как отдельная база данных, и все шарды вместе образуют логически единую базу данных.
Основные принципы шардирования включают в себя:
- **Горизонтальное разделение данных**: Вместо того чтобы хранить все данные в одной таблице или базе данных, они разделяются на меньшие части. Каждый шард содержит часть данных, например, пользователей с идентификаторами от 1 до 1000 в одном шарде и от 1001 до 2000 в другом.
- **Распределение нагрузки**: Поскольку запросы к данным могут обрабатываться параллельно разными шардами, это способствует балансировке нагрузки и увеличению производительности системы.
- **Масштабируемость**: По мере роста объёмов данных новые шарды могут быть добавлены в систему, что позволяет масштабировать приложение горизонтально.
- **Локализация данных**: Шардирование может быть использовано для локализации данных, чтобы уменьшить задержки, связанные с географическим расположением пользователей и баз данных.
**Плюсы:**
- [Горизонтальное масштабирование](Горизонтальное%20масштабирование.md)
- **Улучшение производительности**: Единственный способ ускорить операции вставки в БД.
- **Высокая доступность и устойчивость к отказам**: Отказ одного шарда не приводит к полному сбою системы. Данные в остальных шардах остаются доступными, что повышает общую устойчивость системы к отказам.
**Минусы**
- **Сложность управления**: Нет стандартных механизмов по управлению шардами. В случае добавления или удаления шардов может потребоваться перераспределение больших объемов данных, что может быть ресурсоемкой операцией и повлиять на производительность системы.
- **Трудности с транзакциями и согласованностью**: Шардирование может затруднить обеспечение атомарности и согласованности транзакций, охватывающих несколько шардов, что может потребовать дополнительных усилий для поддержания целостности данных.
**Проблемы:**
- [Решардинг](_inbox/Решардинг.md)
- [Согласованное префиксное чтение](Согласованное%20префиксное%20чтение.md)
- При запросе SELECT FROM данные могут отдаться сначала все с одного шарда, потом с другого и так далее.
- Запросы не по ключу шардирования обойдут все узлы.
- Запросы по диапазону ключей хэширования могут обойти все шарды.
- Данные не равномерно распределились.
- Попробовать подобрать лучше ключ шардирования/кэш функцию
- [Решардинг](_inbox/Решардинг.md)
- [JOIN SQL](JOIN%20SQL.md)
- Держать нужные данные на одном шарде
- Делать вычисления в одном сервисе
Как выбрать ключ для шардирования и хэш функцию:
- Определиться, какой функционал для вашего бизнеса самый полезный. Какие запросы нужно выполнить, чтобы этот функционал работал. Как разбить данные так, чтобы данные запросы стали быстрее.
- Подумать о [Решардинг](_inbox/Решардинг.md). Насколько легко будет добавлять и убирать шарды.
Обычно для распределения по шардам используется какая-то функция шардирования, в которую передается ключ. Популярные формулы хэширования:
- Если ключ цифровой, то можно просто поделить его на количество серверов, получив остаток от деления. Если это строка, то можно взять хэш функцию, которая даст число и уже его делить на количество серверов.
- При изменении количества серверов будет большая головная боль с [решардингом](_inbox/Решардинг.md), так как придется перетаскивать данные практически со всех шардов.
- Алгоритм crc32.
- какой-то мур-мур
Стратегии распределения данных по шардам:
- [Key Based Sharding](Key%20Based%20Sharding.md). Наиболее распространенный способ.
- [Range Base Sharding](Range%20Base%20Sharding.md). Не использует хэш функцию.
- [Directory Based Sharding](Directory%20Based%20Sharding.md)
- [Consistent hashing](Consistent%20hashing.md). Уменьшает боль от [решардинга](_inbox/Решардинг.md).
Как направлять на шарды:
- Умный клиент. Приложение само решает в какой шард идти
- Нет дополнительной точки отказа. Нет лишнего хопа.
- Усложняется разработка. Нужно учитывать шардирование при разработке.
- Как выполнять [решардинг](_inbox/Решардинг.md)?
- Прокси
- Промежуточный сервис между клиентом и БД, который знает о шардинге и передает данные от БД к клиенту.
- Сервисы ничего не знают о шардинге
- Дополнительная точка отказа.
- Но можно попробовать разместить проксю рядом с сервисом.
- Увеличивается количество трафика.
- Уменьшается [Latency](Latency.md). Лишний хоп.
- Координатор
- Промежуточный сервис между клиентом и БД, но в отличие от прокси не отдает сами данные, а указывает сервису в какой шард сходить.
- Сервисы ничего не знают о шардинге.
- Дополнительная точка отказа.
- Уменьшается [Latency](Latency.md). Лишний хоп.
- Intra-database routing
- Клиент обращается к любому шарду БД, а он уже знает в какой шард сходить.
- Так работает [Redis](Redis.md) кластер
Лучше если количество нод будет равно степени 2 (2,4,8). Формула shard_Id % count.
- 16 записей на 8 шардов -> 2 записи на шард
- 16 записей на 16 шардов -> 1 запись на шард
Реализации в СУБД:
- [Шардирование в PostgreSQL](Шардирование%20в%20PostgreSQL.md)
## Заметки
- Как и в случае [партиционирования](Партиционирование%20в%20БД.md) запросы по ключу шардирования ускорятся.
- Можно создавать различные индексы на узлах. При этом может оказаться так, что индексы на исходной таблице могут не подойди для шардирования.
- В 2GIS при переезде на шардирование они создавали шарды, после чего обвешавали основную БД тригерами, чтобы они актуализировали данные в шарда, но при этом продолжали использовать старую БД. В какой-то момент переключились на шарды.