Лекция 11. Распределённая база данных
В этой части конспекта курсив — комментарии лектора, остальной текст — материал презентации.
Когда строим какую-либо реляционную систему, у неё три части:
- клиентская;
- бэкенд;
- база данных.
Нужно масштабироваться. Можно делать это вертикально, но упрёмся в производительность. Тогда проще сделать много серверов — БД распределена на несколько устройств.
Определение
Распределённая база данных — это набор логически взаимосвязанных данных, которые физически распределены между несколькими узлами в некоторой компьютерной сети.
Мотивация
- Масштабируемость;
- высокая доступность и отказоустойчивость;
- производительность.
Модели распределения данных
- Репликация. Если репликация, то соединённые ноды имеют одни и те же данные. Одна сломалась — в другой всё осталось (отказоустойчивость). Повышается производительность чтения.
- Шардинг. Если шардинг, то в разных нодах разные данные. Нода упала — половина данных недоступна.
- Replication + Sharding — комбинация.
А партиционирование?
- Партиционирование — это «вертикальное» разделение таблицы по строкам внутри одной базы данных (на одном сервере), а не между разными узлами. Не путать с шардингом.
Репликация
По способу синхронизации:
- Синхронная —
COMMITдожидается подтверждения от реплик. Высокая консистентность, но выше латентность. - Асинхронная — реплики отстают от мастера. Быстро, но возможна потеря самых свежих изменений при падении мастера.
Архитектуры репликации
- Master-Slave (Primary-Replica). Есть одна нода-мастер, остальные — её слейвы. Мастер может писать и читать, слейвы — только читать.
- Multi-Master. Любая реплика тоже мастер — может принимать запись.
- Peer-to-Peer. Каждая нода — полноценный, независимый организм.
Стратегии шардирования
- Шардирование по диапазону (самый простой вариант — например,
id 1..1000на одну ноду,1001..2000на другую). - Шардирование по хешу.
- Шардирование по справочнику (lookup-таблица: ключ → шард).
- Геошардинг (по географическому признаку).
Проблемы шардирования
- Сложность запросов (
JOIN-ы поперёк шардов). - Транзакции — требуют дорогих Two-Phase Commit.
- Решардинг — перераспределение данных при изменении числа шардов очень дорого.
- Роутинг запросов — нужен координатор.
- Неподходящие ключи шардирования — могут привести к перекосу нагрузки.
- Кайфанёшь от
SELECT COUNT(*)— приходится считать по всем шардам.
Типы распределённых СУБД
- Однородные (Homogeneous) — все узлы используют одну СУБД и схему.
- Неоднородные (Heterogeneous) — узлы могут использовать разные СУБД.
Two-Phase Commit (2PC)
Протокол атомарной фиксации распределённой транзакции:
- Фаза подготовки (Prepare). Координатор просит всех участников приготовиться зафиксировать транзакцию; они отвечают «готов» или «не готов».
- Фаза решения (Commit / Abort). Если все согласны — координатор рассылает
COMMIT, иначе —ROLLBACK.
Недостатки 2PC
- Протокол требует двух раундов сетевого взаимодействия.
- Каждая транзакция ждёт ответов от всех участников.
- Координатор — единая точка отказа.
Альтернатива 2PC: делаем «маленькие» операции на уровне микросервисов (паттерн SAGA: длинная транзакция как последовательность локальных, с компенсирующими действиями при сбое).
BASE
BASE — свойство системы, которое жертвует немедленной строгой согласованностью в обмен на высокую доступность и производительность.
Расшифровка:
- Basically Available — система отвечает на любой запрос, но ответ может содержать ошибку или несогласованные данные.
- Soft state — состояние системы может меняться со временем из-за изменений конечной согласованности.
- Eventual consistency — система в конечном итоге станет согласованной. Она будет продолжать принимать данные и не будет проверять каждую транзакцию на согласованность.
CAP-теорема
CAP-теорема (теорема Брюера) утверждает, что в любой распределённой системе, обеспечивающей хранение данных, невозможно одновременно гарантировать более двух из трёх свойств:
- Consistency — информация на разных узлах согласована.
- Availability — система отвечает на запросы в любой момент времени.
- Partition tolerance — связи между узлами могут обрываться (система продолжает работать при сетевых разделениях).
CP
- При разрыве связи между узлами система блокирует запись на часть узлов, чтобы гарантировать, что данные останутся согласованными.
- Примеры: MongoDB, Redis, ZooKeeper.
AP
- При разрыве связи все узлы остаются доступными для чтения и записи. Это может привести к тому, что разные узлы будут иметь разные версии данных.
- Примеры: Cassandra, ScyllaDB.
CA
Такая система может существовать только при отсутствии сетевых сбоев (то есть фактически — нераспределённые системы или системы в одном дата-центре с надёжной сетью).
Пример — сервис «Позвони, напомню!»
Идея сервиса — система хранения фактов с разрешёнными действиями:
- запрос на запись факта;
- запрос на изменение факта;
- запрос на чтение факта.
Продолжение разбора кейса — на Хабре
PACELC
PACELC расширяет CAP, описывая поведение системы не только во время сетевых сбоев, но и в нормальных условиях работы:
- If (P)artition — если произошло сетевое разделение, выбираем между Availability и Consistency.
- (E)lse — иначе (в нормальной работе) выбираем между Latency (низкой задержкой) и Consistency.
То есть даже без сетевых сбоев приходится платить либо консистентностью, либо скоростью ответа.