Skip to content

Latest commit

 

History

History
121 lines (79 loc) · 7.77 KB

database-partitioning.md

File metadata and controls

121 lines (79 loc) · 7.77 KB

Database Partitioning

Sep 21, 2020 · 3 min read

Шардирование — разделение базы данных на две, три, пять частей, и раскладывание их по разным машинам. В какой-то момент это может быть выгоднее (дешевле), чем покупать машину помощнее.

У этого, разумеется, есть свои минусы. Коротко обсудим в этой статье.

В прошлый раз говорили про кеширование и балансеры.

Как шардировать? #

Рассотрим какие есть схемы шардирования.

В статье «System Design для самых маленьких» я уже писал про шардирование.

Range based #

Делим условный список сущностей, которые имеют смысл для нашего бизнес-домена, на несколько частей. Скажем, если это пользователи — пусть первый миллион пользователей находится на машине А, второй миллион на машине Б, и т.д.

Минус такого подхода в том, что мы предполагаем, что все сущности равнозначны (в смысле нагрузки), но это не так. Какие-то шарды будут перегружены, а какие-то стоять без дела.

Vertical #

Поделим все данные по принадлежности к определённым фичам. Скажем, если мы делаем инстаграм, то у нас будут: пользователи, картинки, фоловеры. Разложим их по разным базам.

Обычно различные фичи имеют различный профиль нагрузки, поэтому с разделением довольно удобно куда-то дать больше мощности, а куда-то меньше, в зависимости от профиля нагрузки.

Внутри «вертикали» можно дополнительно использовать range based, если она перегружена.

Hash-based #

При вычислении куда положить (и откуда достать) данные используем хеш-функция. В самом простом варианте — остаток от деления. Скажем, у нас 100500 пользователей и 10 серверов: остаток от деления айдишника пользователя на 10 скажем на каком сервере находятся данные этого пользователя.

Возникает проблема при добавлении новых серверов – весь мапинг собьётся. Поможет Consistent Hashing, чтобы снизить количество данных, которые придётся переналить. Ну и переналивать данные на новые шарды все-таки придётся, но делать это можно без простоя всей системы, прямо на «горячую».

Directory Service #

Чтобы понимать куда отправлять запросы за конкретным пользователем или его картинками, нужно держать мапинг между данными и серверами, в зависимости от того какая схема шардирования используется.

Удобно для этой цели поднять отдельный сервис, который знает где искать данные — сервер директорий.

Какие есть проблемы? #

Joins #

Теряем возможность джойнить. Если надо собрать данные из разных таблиц, которые лежат на разных машинах — такое себе мероприятия в смысле производительности.

Приходится денормализовывать данные, т.е. появляется дублирование данных, и как следствие — неконсистентность. С этим приходится бороться вручную.

Referential Integrity #

С помощью foreign key поддерживается консистентность связей между различными таблицами, всё работает само.

Пример, есть у нас две таблицы: parent и child. В дочерней соответственно есть foreign_key, который указывает на родительские записи.

mysql> SELECT * FROM parent;
+--------+
| par_id |
+--------+
|   1    |
|   2    |
|   3    |
+--------+
mysql> SELECT * FROM child;
+--------+----------+
| par_id | child_id |
+--------+----------+
|   1    |    1     |
|   1    |    2     |
|   2    |    3     |
|   2    |    4     |
|   2    |    5     |
|   3    |    6     |
+--------+----------+

(primary key — child_id, а foreign key — par_id)

Что будет если удалить первую запись из родительской таблицы?

mysql> DELETE FROM parent where par_id = 1;

Правильно. Каскадом за родительской таблицей будут удалены невалидные записи из дочерней.

mysql> SELECT * FROM parent;
+--------+
| par_id |
+--------+
|   2    |
|   3    |
+--------+
mysql> SELECT * FROM child;
+--------+----------+
| par_id | child_id |
+--------+----------+
|   2    |    3     |
|   2    |    4     |
|   2    |    5     |
|   3    |    6     |
+--------+----------+

Однако, если мы разделили данные фактически по разным базам — нет такой магии, которая будет работать сквозным образом.

Про консистеность приходится думать на уровне приложения.

Материалы #

PS. Обсудить можно в телеграм-чате любознательных программистов. Welcome! 🤗

Подписывайтесь на мой твитер или канал в телеграме, чтобы узнавать о новых разборах задач.